diff options
| author | Tim Redfern <tim@eclectronics.org> | 2013-12-29 12:19:38 +0000 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2013-12-29 12:19:38 +0000 |
| commit | f7813a5324be39d13ab536c245d15dfc602a7849 (patch) | |
| tree | fad99148b88823d34a5df2f0a25881a002eb291b /ffmpeg/libavcodec/flacdec.c | |
| parent | b7a5a477b8ff4d4e3028b9dfb9a9df0a41463f92 (diff) | |
basic type mechanism working
Diffstat (limited to 'ffmpeg/libavcodec/flacdec.c')
| -rw-r--r-- | ffmpeg/libavcodec/flacdec.c | 94 |
1 files changed, 55 insertions, 39 deletions
diff --git a/ffmpeg/libavcodec/flacdec.c b/ffmpeg/libavcodec/flacdec.c index aaddd2d..596b24d 100644 --- a/ffmpeg/libavcodec/flacdec.c +++ b/ffmpeg/libavcodec/flacdec.c @@ -44,6 +44,9 @@ #include "flac.h" #include "flacdata.h" #include "flacdsp.h" +#include "thread.h" +#include "unary.h" + typedef struct FLACContext { FLACSTREAMINFO @@ -101,7 +104,7 @@ static av_cold int flac_decode_init(AVCodecContext *avctx) return 0; if (!avpriv_flac_is_extradata_valid(avctx, &format, &streaminfo)) - return -1; + return AVERROR_INVALIDDATA; /* initialize based on the demuxer-supplied streamdata header */ avpriv_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo); @@ -212,7 +215,7 @@ static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order) if (method_type > 1) { av_log(s->avctx, AV_LOG_ERROR, "illegal residual coding method %d\n", method_type); - return -1; + return AVERROR_INVALIDDATA; } rice_order = get_bits(&s->gb, 4); @@ -221,7 +224,7 @@ static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order) if (pred_order > samples) { av_log(s->avctx, AV_LOG_ERROR, "invalid predictor order: %i > %i\n", pred_order, samples); - return -1; + return AVERROR_INVALIDDATA; } rice_bits = 4 + method_type; @@ -251,14 +254,15 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, { const int blocksize = s->blocksize; int av_uninit(a), av_uninit(b), av_uninit(c), av_uninit(d), i; + int ret; /* warm up samples */ for (i = 0; i < pred_order; i++) { decoded[i] = get_sbits_long(&s->gb, bps); } - if (decode_residuals(s, decoded, pred_order) < 0) - return -1; + if ((ret = decode_residuals(s, decoded, pred_order)) < 0) + return ret; if (pred_order > 0) a = decoded[pred_order-1]; @@ -290,7 +294,7 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, break; default: av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order); - return -1; + return AVERROR_INVALIDDATA; } return 0; @@ -299,7 +303,7 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order, int bps) { - int i; + int i, ret; int coeff_prec, qlevel; int coeffs[32]; @@ -311,21 +315,21 @@ static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order, coeff_prec = get_bits(&s->gb, 4) + 1; if (coeff_prec == 16) { av_log(s->avctx, AV_LOG_ERROR, "invalid coeff precision\n"); - return -1; + return AVERROR_INVALIDDATA; } qlevel = get_sbits(&s->gb, 5); if (qlevel < 0) { av_log(s->avctx, AV_LOG_ERROR, "qlevel %d not supported, maybe buggy stream\n", qlevel); - return -1; + return AVERROR_INVALIDDATA; } for (i = 0; i < pred_order; i++) { coeffs[pred_order - i - 1] = get_sbits(&s->gb, coeff_prec); } - if (decode_residuals(s, decoded, pred_order) < 0) - return -1; + if ((ret = decode_residuals(s, decoded, pred_order)) < 0) + return ret; s->dsp.lpc(decoded, coeffs, pred_order, qlevel, s->blocksize); @@ -337,7 +341,7 @@ static inline int decode_subframe(FLACContext *s, int channel) int32_t *decoded = s->decoded[channel]; int type, wasted = 0; int bps = s->bps; - int i, tmp; + int i, tmp, ret; if (channel == 0) { if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE) @@ -349,13 +353,12 @@ static inline int decode_subframe(FLACContext *s, int channel) if (get_bits1(&s->gb)) { av_log(s->avctx, AV_LOG_ERROR, "invalid subframe padding\n"); - return -1; + return AVERROR_INVALIDDATA; } type = get_bits(&s->gb, 6); if (get_bits1(&s->gb)) { int left = get_bits_left(&s->gb); - wasted = 1; if ( left < 0 || (left < bps && !show_bits_long(&s->gb, left)) || !show_bits_long(&s->gb, bps)) { @@ -364,8 +367,7 @@ static inline int decode_subframe(FLACContext *s, int channel) bps, left); return AVERROR_INVALIDDATA; } - while (!get_bits1(&s->gb)) - wasted++; + wasted = 1 + get_unary(&s->gb, 1, get_bits_left(&s->gb)); bps -= wasted; } if (bps > 32) { @@ -382,14 +384,14 @@ static inline int decode_subframe(FLACContext *s, int channel) for (i = 0; i < s->blocksize; i++) decoded[i] = get_sbits_long(&s->gb, bps); } else if ((type >= 8) && (type <= 12)) { - if (decode_subframe_fixed(s, decoded, type & ~0x8, bps) < 0) - return -1; + if ((ret = decode_subframe_fixed(s, decoded, type & ~0x8, bps)) < 0) + return ret; } else if (type >= 32) { - if (decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps) < 0) - return -1; + if ((ret = decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps)) < 0) + return ret; } else { av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n"); - return -1; + return AVERROR_INVALIDDATA; } if (wasted) { @@ -407,9 +409,9 @@ static int decode_frame(FLACContext *s) GetBitContext *gb = &s->gb; FLACFrameInfo fi; - if (ff_flac_decode_frame_header(s->avctx, gb, &fi, 0)) { + if ((ret = ff_flac_decode_frame_header(s->avctx, gb, &fi, 0)) < 0) { av_log(s->avctx, AV_LOG_ERROR, "invalid frame header\n"); - return -1; + return ret; } if (s->channels && fi.channels != s->channels && s->got_streaminfo) { @@ -426,14 +428,14 @@ static int decode_frame(FLACContext *s) if (!s->bps && !fi.bps) { av_log(s->avctx, AV_LOG_ERROR, "bps not found in STREAMINFO or frame header\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!fi.bps) { fi.bps = s->bps; } else if (s->bps && fi.bps != s->bps) { av_log(s->avctx, AV_LOG_ERROR, "switching bps mid-stream is not " "supported\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!s->bps) { @@ -446,14 +448,14 @@ static int decode_frame(FLACContext *s) if (fi.blocksize > s->max_blocksize) { av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", fi.blocksize, s->max_blocksize); - return -1; + return AVERROR_INVALIDDATA; } s->blocksize = fi.blocksize; if (!s->samplerate && !fi.samplerate) { av_log(s->avctx, AV_LOG_ERROR, "sample rate not found in STREAMINFO" " or frame header\n"); - return -1; + return AVERROR_INVALIDDATA; } if (fi.samplerate == 0) fi.samplerate = s->samplerate; @@ -472,8 +474,8 @@ static int decode_frame(FLACContext *s) /* subframes */ for (i = 0; i < s->channels; i++) { - if (decode_subframe(s, i) < 0) - return -1; + if ((ret = decode_subframe(s, i)) < 0) + return ret; } align_get_bits(gb); @@ -488,6 +490,7 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { AVFrame *frame = data; + ThreadFrame tframe = { .f = data }; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; FLACContext *s = avctx->priv_data; @@ -520,22 +523,23 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, /* check for inline header */ if (AV_RB32(buf) == MKBETAG('f','L','a','C')) { - if (!s->got_streaminfo && parse_streaminfo(s, buf, buf_size)) { + if (!s->got_streaminfo && (ret = parse_streaminfo(s, buf, buf_size))) { av_log(s->avctx, AV_LOG_ERROR, "invalid header\n"); - return -1; + return ret; } return get_metadata_size(buf, buf_size); } /* decode frame */ - init_get_bits(&s->gb, buf, buf_size*8); - if (decode_frame(s) < 0) { + if ((ret = init_get_bits8(&s->gb, buf, buf_size)) < 0) + return ret; + if ((ret = decode_frame(s)) < 0) { av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n"); - return -1; + return ret; } bytes_read = get_bits_count(&s->gb)/8; - if ((s->avctx->err_recognition & AV_EF_CRCCHECK) && + if ((s->avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_COMPLIANT)) && av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf, bytes_read)) { av_log(s->avctx, AV_LOG_ERROR, "CRC error at PTS %"PRId64"\n", avpkt->pts); @@ -545,7 +549,7 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = s->blocksize; - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0) return ret; s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded, s->channels, @@ -553,7 +557,7 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, if (bytes_read > buf_size) { av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size); - return -1; + return AVERROR_INVALIDDATA; } if (bytes_read < buf_size) { av_log(s->avctx, AV_LOG_DEBUG, "underread: %d orig size: %d\n", @@ -565,6 +569,17 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, return bytes_read; } +static int init_thread_copy(AVCodecContext *avctx) +{ + FLACContext *s = avctx->priv_data; + s->decoded_buffer = NULL; + s->decoded_buffer_size = 0; + s->avctx = avctx; + if (s->max_blocksize) + return allocate_buffers(s); + return 0; +} + static av_cold int flac_decode_close(AVCodecContext *avctx) { FLACContext *s = avctx->priv_data; @@ -576,14 +591,15 @@ static av_cold int flac_decode_close(AVCodecContext *avctx) AVCodec ff_flac_decoder = { .name = "flac", + .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_FLAC, .priv_data_size = sizeof(FLACContext), .init = flac_decode_init, .close = flac_decode_close, .decode = flac_decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), + .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32, |
