From 68a04b0ccee66f57516e129dd3ec457fd50b4bec Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 22 Dec 2012 01:21:09 -0500 Subject: [PATCH 1/4] alacdec: do not be too strict about the extradata size Sometimes the extradata has duplicate atoms, but that shouldn't prevent decoding. Just ensure that it is at least 36 bytes as a sanity check. CC: libav-stable@libav.org --- libavcodec/alac.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libavcodec/alac.c b/libavcodec/alac.c index 22882a56c0..1a3f769513 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -521,10 +521,9 @@ static av_cold int alac_decode_init(AVCodecContext * avctx) alac->avctx = avctx; /* initialize from the extradata */ - if (alac->avctx->extradata_size != ALAC_EXTRADATA_SIZE) { - av_log(avctx, AV_LOG_ERROR, "alac: expected %d extradata bytes\n", - ALAC_EXTRADATA_SIZE); - return -1; + if (alac->avctx->extradata_size < ALAC_EXTRADATA_SIZE) { + av_log(avctx, AV_LOG_ERROR, "alac: extradata is too small\n"); + return AVERROR_INVALIDDATA; } if (alac_set_info(alac)) { av_log(avctx, AV_LOG_ERROR, "alac: set_info failed\n"); From 5778299c7ed3f82c624589bd35c82f597a8e0b64 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 10 Feb 2012 17:51:11 -0500 Subject: [PATCH 2/4] ttadec: fix last frame handling when seeking Using a frame count, as is done currently, does not work at all with seeking. Instead, when the number of samples in the final frame has been decoded, we check if only the 32-bit CRC is remaining. If so, we assume that it is the final frame. There is no longer a need to keep total_frames in TTAContext. --- libavcodec/tta.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/libavcodec/tta.c b/libavcodec/tta.c index 0bd7daba9c..5ed70e99c9 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -64,7 +64,7 @@ typedef struct TTAContext { int format, channels, bps; unsigned data_length; - int frame_length, last_frame_length, total_frames; + int frame_length, last_frame_length; int32_t *decode_buffer; @@ -198,6 +198,7 @@ static int tta_check_crc(TTAContext *s, const uint8_t *buf, int buf_size) static av_cold int tta_decode_init(AVCodecContext * avctx) { TTAContext *s = avctx->priv_data; + int total_frames; s->avctx = avctx; @@ -262,24 +263,24 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) s->frame_length = 256 * avctx->sample_rate / 245; s->last_frame_length = s->data_length % s->frame_length; - s->total_frames = s->data_length / s->frame_length + - (s->last_frame_length ? 1 : 0); + total_frames = s->data_length / s->frame_length + + (s->last_frame_length ? 1 : 0); av_log(s->avctx, AV_LOG_DEBUG, "format: %d chans: %d bps: %d rate: %d block: %d\n", s->format, avctx->channels, avctx->bits_per_coded_sample, avctx->sample_rate, avctx->block_align); av_log(s->avctx, AV_LOG_DEBUG, "data_length: %d frame_length: %d last: %d total: %d\n", - s->data_length, s->frame_length, s->last_frame_length, s->total_frames); + s->data_length, s->frame_length, s->last_frame_length, total_frames); // FIXME: seek table - if (avctx->extradata_size <= 26 || s->total_frames > INT_MAX / 4 || - avctx->extradata_size - 26 < s->total_frames * 4) + if (avctx->extradata_size <= 26 || total_frames > INT_MAX / 4 || + avctx->extradata_size - 26 < total_frames * 4) av_log(avctx, AV_LOG_WARNING, "Seek table missing or too small\n"); else if (avctx->err_recognition & AV_EF_CRCCHECK) { - if (tta_check_crc(s, avctx->extradata + 22, s->total_frames * 4)) + if (tta_check_crc(s, avctx->extradata + 22, total_frames * 4)) return AVERROR_INVALIDDATA; } - skip_bits_long(&s->gb, 32 * s->total_frames); + skip_bits_long(&s->gb, 32 * total_frames); skip_bits_long(&s->gb, 32); // CRC32 of seektable if(s->frame_length >= UINT_MAX / (s->channels * sizeof(int32_t))){ @@ -325,11 +326,6 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, init_get_bits(&s->gb, buf, buf_size*8); - // FIXME: seeking - s->total_frames--; - if (!s->total_frames && s->last_frame_length) - framelen = s->last_frame_length; - /* get output buffer */ s->frame.nb_samples = framelen; if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { @@ -348,6 +344,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, rice_init(&s->ch_ctx[i].rice, 10, 10); } + i = 0; for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++) { int32_t *predictor = &s->ch_ctx[cur_chan].predictor; TTAFilter *filter = &s->ch_ctx[cur_chan].filter; @@ -424,9 +421,16 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, *r = *(r + 1) - *r; } cur_chan = 0; + i++; + // check for last frame + if (i == s->last_frame_length && get_bits_left(&s->gb) / 8 == 4) { + s->frame.nb_samples = framelen = s->last_frame_length; + break; + } } } + align_get_bits(&s->gb); if (get_bits_left(&s->gb) < 32) { ret = AVERROR_INVALIDDATA; goto error; From d02202e08a994c6c80f0256ae756698541b59902 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 8 Nov 2012 18:35:49 -0500 Subject: [PATCH 3/4] opt: avoid segfault in av_opt_next() if the class does not have an option list CC: libav-stable@libav.org --- libavutil/opt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavutil/opt.c b/libavutil/opt.c index e199170075..8a98a9ef55 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -37,8 +37,10 @@ const AVOption *av_opt_next(void *obj, const AVOption *last) { AVClass *class = *(AVClass**)obj; - if (!last && class->option[0].name) return class->option; - if (last && last[1].name) return ++last; + if (!last && class->option && class->option[0].name) + return class->option; + if (last && last[1].name) + return ++last; return NULL; } From 418693bdc5edad72b0d055f741931612d797eb05 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 21 Dec 2012 21:50:50 +0100 Subject: [PATCH 4/4] lavc: rewrite and extend AVFrame doxy --- libavcodec/avcodec.h | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index d12c72b74c..d9a2dc2ce4 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -972,11 +972,19 @@ enum AVSideDataParamChangeFlags { */ /** - * Audio Video Frame. - * New fields can be added to the end of AVFRAME with minor version - * bumps. Removal, reordering and changes to existing fields require - * a major version bump. - * sizeof(AVFrame) must not be used outside libav*. + * This structure describes decoded (raw) audio or video data. + * + * AVFrame must be allocated using avcodec_alloc_frame() and freed with + * avcodec_free_frame(). Note that this allocates only the AVFrame itself. The + * buffers for the data must be managed through other means. + * + * AVFrame is typically allocated once and then reused multiple times to hold + * different data (e.g. a single AVFrame to hold frames received from a + * decoder). In such a case, avcodec_get_frame_defaults() should be used to + * reset the frame to its original clean state before it is reused again. + * + * sizeof(AVFrame) is not a part of the public ABI, so new fields may be added + * to the end with a minor bump. */ typedef struct AVFrame { #define AV_NUM_DATA_POINTERS 8