diff --git a/libavcodec/alac.c b/libavcodec/alac.c index 4e8903114d..180ef53105 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -573,10 +573,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, "expected %d extradata bytes\n", - ALAC_EXTRADATA_SIZE); - return -1; + if (alac->avctx->extradata_size < ALAC_EXTRADATA_SIZE) { + av_log(avctx, AV_LOG_ERROR, "extradata is too small\n"); + return AVERROR_INVALIDDATA; } if (alac_set_info(alac)) { av_log(avctx, AV_LOG_ERROR, "set_info failed\n"); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 0241c8a96b..9ee9af1311 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1074,14 +1074,22 @@ enum AVSideDataParamChangeFlags { */ /** - * Audio Video Frame. - * New fields can be added to the end of AVFRAME with minor version - * bumps. Similarly fields that are marked as to be only accessed by + * 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. + * Similarly fields that are marked as to be only accessed by * av_opt_ptr() can be reordered. This allows 2 forks to add fields * without breaking compatibility with each other. - * Removal, reordering and changes in the remaining cases require - * a major version bump. - * sizeof(AVFrame) must not be used outside libavcodec. */ typedef struct AVFrame { #define AV_NUM_DATA_POINTERS 8 diff --git a/libavcodec/tta.c b/libavcodec/tta.c index 27efceba03..09dc046809 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; @@ -176,6 +176,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; @@ -242,27 +243,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); - - if (s->total_frames < 0) - return AVERROR_INVALIDDATA; + 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 (avctx->extradata_size < 26 + s->total_frames * 4 || 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))){ @@ -309,11 +307,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) { @@ -332,6 +325,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; @@ -408,9 +402,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; diff --git a/libavutil/opt.c b/libavutil/opt.c index 48078e3274..61c76daa6e 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -65,7 +65,8 @@ const AVOption *av_opt_next(void *obj, const AVOption *last) AVClass *class = *(AVClass**)obj; if (!last && class->option && class->option[0].name) return class->option; - if (last && last[1].name) return ++last; + if (last && last[1].name) + return ++last; return NULL; }