From fdb5314ea7fe0ab1036b8de94d47861d99e4daeb Mon Sep 17 00:00:00 2001 From: Anton Mitrofanov Date: Fri, 28 Oct 2011 19:13:13 +0400 Subject: [PATCH 01/51] Fix decoding of lossless 10-bit 4:4:4 H.264 Signed-off-by: Ronald S. Bultje --- libavcodec/h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 880b5b7b58db4..fc20eb4286ac6 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -1779,7 +1779,7 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h, int mb_ty static const uint8_t dc_mapping[16] = { 0*16, 1*16, 4*16, 5*16, 2*16, 3*16, 6*16, 7*16, 8*16, 9*16,12*16,13*16,10*16,11*16,14*16,15*16}; for(i = 0; i < 16; i++) - dctcoef_set(h->mb+p*256, pixel_shift, dc_mapping[i], dctcoef_get(h->mb_luma_dc[p], pixel_shift, i)); + dctcoef_set(h->mb+(p*256 << pixel_shift), pixel_shift, dc_mapping[i], dctcoef_get(h->mb_luma_dc[p], pixel_shift, i)); } } }else From 640d5f1c801061844394813c78ea449e5826f6e5 Mon Sep 17 00:00:00 2001 From: Anton Mitrofanov Date: Fri, 28 Oct 2011 23:33:23 +0400 Subject: [PATCH 02/51] Fix decoding of lossless 4:2:2 H.264 Signed-off-by: Ronald S. Bultje --- libavcodec/h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index fc20eb4286ac6..f7c52cdbcdba2 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -2002,7 +2002,7 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, i } if (chroma422) { for(i=j*16+4; inon_zero_count_cache[ scan8[i] ] || dctcoef_get(h->mb, pixel_shift, i*16)) + if(h->non_zero_count_cache[ scan8[i+4] ] || dctcoef_get(h->mb, pixel_shift, i*16)) idct_add (dest[j-1] + block_offset[i+4], h->mb + (i*16 << pixel_shift), uvlinesize); } } From 38a4be3fa7a7bb83f0a553577427e916a7bda390 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 27 Oct 2011 20:37:34 -0700 Subject: [PATCH 03/51] lavf: use number of output pictures for delay checks. This fixes false positives of has_codec_delay_been_guessed() for streams where not every input picture generates an output picture, such as interlaced H264. --- libavformat/avformat.h | 1 + libavformat/utils.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index d16be90c8fd13..dd40c7fafb82a 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -657,6 +657,7 @@ typedef struct AVStream { int duration_count; double duration_error[MAX_STD_TIMEBASES]; int64_t codec_info_duration; + int nb_decoded_frames; } *info; #if !FF_API_REORDER_PRIVATE const uint8_t *cur_ptr; diff --git a/libavformat/utils.c b/libavformat/utils.c index 81eee97a84f01..1158079992a0f 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2119,7 +2119,7 @@ static int has_codec_parameters(AVCodecContext *avctx) static int has_decode_delay_been_guessed(AVStream *st) { return st->codec->codec_id != CODEC_ID_H264 || - st->codec_info_nb_frames >= 6 + st->codec->has_b_frames; + st->info->nb_decoded_frames >= 6; } static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options) @@ -2145,6 +2145,8 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option avcodec_get_frame_defaults(&picture); ret = avcodec_decode_video2(st->codec, &picture, &got_picture, avpkt); + if (got_picture) + st->info->nb_decoded_frames++; break; case AVMEDIA_TYPE_AUDIO: data_size = FFMAX(avpkt->size, AVCODEC_MAX_AUDIO_FRAME_SIZE); From bfa0f96586fe2c257cfa574ffb991da493a54da1 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 28 Oct 2011 23:48:43 -0700 Subject: [PATCH 04/51] vp8: fix overflow in segmentation map caching. --- libavcodec/vp8.c | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 95755e330ae61..836176df2b0e2 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -50,7 +50,8 @@ static int vp8_alloc_frame(VP8Context *s, AVFrame *f) int ret; if ((ret = ff_thread_get_buffer(s->avctx, f)) < 0) return ret; - if (!s->maps_are_invalid && s->num_maps_to_be_freed) { + if (s->num_maps_to_be_freed) { + assert(!s->maps_are_invalid); f->ref_index[0] = s->segmentation_maps[--s->num_maps_to_be_freed]; } else if (!(f->ref_index[0] = av_mallocz(s->mb_width * s->mb_height))) { ff_thread_release_buffer(s->avctx, f); @@ -59,39 +60,50 @@ static int vp8_alloc_frame(VP8Context *s, AVFrame *f) return 0; } -static void vp8_release_frame(VP8Context *s, AVFrame *f, int is_close) +static void vp8_release_frame(VP8Context *s, AVFrame *f, int prefer_delayed_free, int can_direct_free) { - if (!is_close) { - if (f->ref_index[0]) { - assert(s->num_maps_to_be_freed < FF_ARRAY_ELEMS(s->segmentation_maps)); - s->segmentation_maps[s->num_maps_to_be_freed++] = f->ref_index[0]; + if (f->ref_index[0]) { + if (prefer_delayed_free) { + /* Upon a size change, we want to free the maps but other threads may still + * be using them, so queue them. Upon a seek, all threads are inactive so + * we want to cache one to prevent re-allocation in the next decoding + * iteration, but the rest we can free directly. */ + int max_queued_maps = can_direct_free ? 1 : FF_ARRAY_ELEMS(s->segmentation_maps); + if (s->num_maps_to_be_freed < max_queued_maps) { + s->segmentation_maps[s->num_maps_to_be_freed++] = f->ref_index[0]; + } else if (can_direct_free) /* vp8_decode_flush(), but our queue is full */ { + av_free(f->ref_index[0]); + } /* else: MEMLEAK (should never happen, but better that than crash) */ f->ref_index[0] = NULL; + } else /* vp8_decode_free() */ { + av_free(f->ref_index[0]); } - } else { - av_freep(&f->ref_index[0]); } ff_thread_release_buffer(s->avctx, f); } -static void vp8_decode_flush_impl(AVCodecContext *avctx, int force, int is_close) +static void vp8_decode_flush_impl(AVCodecContext *avctx, + int prefer_delayed_free, int can_direct_free, int free_mem) { VP8Context *s = avctx->priv_data; int i; - if (!avctx->is_copy || force) { + if (!avctx->is_copy) { for (i = 0; i < 5; i++) if (s->frames[i].data[0]) - vp8_release_frame(s, &s->frames[i], is_close); + vp8_release_frame(s, &s->frames[i], prefer_delayed_free, can_direct_free); } memset(s->framep, 0, sizeof(s->framep)); - free_buffers(s); - s->maps_are_invalid = 1; + if (free_mem) { + free_buffers(s); + s->maps_are_invalid = 1; + } } static void vp8_decode_flush(AVCodecContext *avctx) { - vp8_decode_flush_impl(avctx, 0, 0); + vp8_decode_flush_impl(avctx, 1, 1, 0); } static int update_dimensions(VP8Context *s, int width, int height) @@ -101,7 +113,7 @@ static int update_dimensions(VP8Context *s, int width, int height) if (av_image_check_size(width, height, 0, s->avctx)) return AVERROR_INVALIDDATA; - vp8_decode_flush_impl(s->avctx, 1, 0); + vp8_decode_flush_impl(s->avctx, 1, 0, 1); avcodec_set_dimensions(s->avctx, width, height); } @@ -1580,7 +1592,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size, &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] && &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] && &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2]) - vp8_release_frame(s, &s->frames[i], 0); + vp8_release_frame(s, &s->frames[i], 1, 0); // find a free buffer for (i = 0; i < 5; i++) @@ -1596,7 +1608,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size, abort(); } if (curframe->data[0]) - ff_thread_release_buffer(avctx, curframe); + vp8_release_frame(s, curframe, 1, 0); curframe->key_frame = s->keyframe; curframe->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; @@ -1777,7 +1789,7 @@ static av_cold int vp8_decode_init(AVCodecContext *avctx) static av_cold int vp8_decode_free(AVCodecContext *avctx) { - vp8_decode_flush_impl(avctx, 0, 1); + vp8_decode_flush_impl(avctx, 0, 1, 1); release_queued_segmaps(avctx->priv_data, 1); return 0; } From 8370e426e42f2e4b9d14a1fb8107ecfe5163ce7f Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 28 Oct 2011 23:50:04 -0700 Subject: [PATCH 05/51] vp3: fix oob read for negative tokens and memleaks on error. --- libavcodec/vp3.c | 59 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index 36715bb0c77b8..ce14e63735ce8 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -45,6 +45,7 @@ #define FRAGMENT_PIXELS 8 static av_cold int vp3_decode_end(AVCodecContext *avctx); +static void vp3_decode_flush(AVCodecContext *avctx); //FIXME split things out into their own arrays typedef struct Vp3Fragment { @@ -890,7 +891,7 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, /* decode a VLC into a token */ token = get_vlc2(gb, vlc_table, 11, 3); /* use the token to get a zero run, a coefficient, and an eob run */ - if (token <= 6) { + if ((unsigned) token <= 6U) { eob_run = eob_run_base[token]; if (eob_run_get_bits[token]) eob_run += get_bits(gb, eob_run_get_bits[token]); @@ -908,7 +909,7 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, coeff_i += eob_run; eob_run = 0; } - } else { + } else if (token >= 0) { bits_to_get = coeff_get_bits[token]; if (bits_to_get) bits_to_get = get_bits(gb, bits_to_get); @@ -942,6 +943,10 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb, for (i = coeff_index+1; i <= coeff_index+zero_run; i++) s->num_coded_frags[plane][i]--; coeff_i++; + } else { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid token %d\n", token); + return -1; } } @@ -991,6 +996,8 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) /* unpack the Y plane DC coefficients */ residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_y_table], 0, 0, residual_eob_run); + if (residual_eob_run < 0) + return residual_eob_run; /* reverse prediction of the Y-plane DC coefficients */ reverse_dc_prediction(s, 0, s->fragment_width[0], s->fragment_height[0]); @@ -998,8 +1005,12 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) /* unpack the C plane DC coefficients */ residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_c_table], 0, 1, residual_eob_run); + if (residual_eob_run < 0) + return residual_eob_run; residual_eob_run = unpack_vlcs(s, gb, &s->dc_vlc[dc_c_table], 0, 2, residual_eob_run); + if (residual_eob_run < 0) + return residual_eob_run; /* reverse prediction of the C-plane DC coefficients */ if (!(s->avctx->flags & CODEC_FLAG_GRAY)) @@ -1036,11 +1047,17 @@ static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb) for (i = 1; i <= 63; i++) { residual_eob_run = unpack_vlcs(s, gb, y_tables[i], i, 0, residual_eob_run); + if (residual_eob_run < 0) + return residual_eob_run; residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i, 1, residual_eob_run); + if (residual_eob_run < 0) + return residual_eob_run; residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i, 2, residual_eob_run); + if (residual_eob_run < 0) + return residual_eob_run; } return 0; @@ -1777,10 +1794,15 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext * Vp3DecodeContext *s = dst->priv_data, *s1 = src->priv_data; int qps_changed = 0, i, err; +#define copy_fields(to, from, start_field, end_field) memcpy(&to->start_field, &from->start_field, (char*)&to->end_field - (char*)&to->start_field) + if (!s1->current_frame.data[0] ||s->width != s1->width - ||s->height!= s1->height) + ||s->height!= s1->height) { + if (s != s1) + copy_fields(s, s1, golden_frame, current_frame); return -1; + } if (s != s1) { // init tables if the first frame hasn't been decoded @@ -1796,8 +1818,6 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext * memcpy(s->motion_val[1], s1->motion_val[1], c_fragment_count * sizeof(*s->motion_val[1])); } -#define copy_fields(to, from, start_field, end_field) memcpy(&to->start_field, &from->start_field, (char*)&to->end_field - (char*)&to->start_field) - // copy previous frame data copy_fields(s, s1, golden_frame, dsp); @@ -1987,9 +2007,6 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx) Vp3DecodeContext *s = avctx->priv_data; int i; - if (avctx->is_copy && !s->current_frame.data[0]) - return 0; - av_free(s->superblock_coding); av_free(s->all_fragments); av_free(s->coded_fragment_list[0]); @@ -2016,12 +2033,7 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx) free_vlc(&s->motion_vector_vlc); /* release all frames */ - if (s->golden_frame.data[0]) - ff_thread_release_buffer(avctx, &s->golden_frame); - if (s->last_frame.data[0] && s->last_frame.type != FF_BUFFER_TYPE_COPY) - ff_thread_release_buffer(avctx, &s->last_frame); - /* no need to release the current_frame since it will always be pointing - * to the same frame as either the golden or last frame */ + vp3_decode_flush(avctx); return 0; } @@ -2341,6 +2353,23 @@ static void vp3_decode_flush(AVCodecContext *avctx) ff_thread_release_buffer(avctx, &s->current_frame); } +static int vp3_init_thread_copy(AVCodecContext *avctx) +{ + Vp3DecodeContext *s = avctx->priv_data; + + s->superblock_coding = NULL; + s->all_fragments = NULL; + s->coded_fragment_list[0] = NULL; + s->dct_tokens_base = NULL; + s->superblock_fragments = NULL; + s->macroblock_coding = NULL; + s->motion_val[0] = NULL; + s->motion_val[1] = NULL; + s->edge_emu_buffer = NULL; + + return 0; +} + AVCodec ff_theora_decoder = { .name = "theora", .type = AVMEDIA_TYPE_VIDEO, @@ -2352,6 +2381,7 @@ AVCodec ff_theora_decoder = { .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS, .flush = vp3_decode_flush, .long_name = NULL_IF_CONFIG_SMALL("Theora"), + .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context) }; #endif @@ -2367,5 +2397,6 @@ AVCodec ff_vp3_decoder = { .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS, .flush = vp3_decode_flush, .long_name = NULL_IF_CONFIG_SMALL("On2 VP3"), + .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context) }; From 9a173575fd3bd9a4391f760484e918824204e618 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Fri, 28 Oct 2011 20:40:23 +0200 Subject: [PATCH 06/51] utvideo: account for coupled lines in YUV420 format Luma slices in YUV420 colourspace should have height in multiple of two since they have the same line of chrominance data corresponding to pair of them. Signed-off-by: Ronald S. Bultje --- libavcodec/utvideo.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libavcodec/utvideo.c b/libavcodec/utvideo.c index aac3969b1594d..5faaa15a0c40b 100644 --- a/libavcodec/utvideo.c +++ b/libavcodec/utvideo.c @@ -113,6 +113,7 @@ static int decode_plane(UtvideoContext *c, int plane_no, VLC vlc; GetBitContext gb; int prev; + const int cmask = ~(!plane_no && c->avctx->pix_fmt == PIX_FMT_YUV420P); if (build_huff(src, &vlc)) { av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n"); @@ -128,7 +129,7 @@ static int decode_plane(UtvideoContext *c, int plane_no, int slice_data_start, slice_data_end, slice_size; sstart = send; - send = height * (slice + 1) / c->slices; + send = (height * (slice + 1) / c->slices) & cmask; dest = dst + sstart * stride; // slice offset and size validation was done earlier @@ -204,16 +205,17 @@ static void restore_rgb_planes(uint8_t *src, int step, int stride, int width, in } static void restore_median(uint8_t *src, int step, int stride, - int width, int height, int slices) + int width, int height, int slices, int rmode) { int i, j, slice; int A, B, C; uint8_t *bsrc; int slice_start, slice_height; + const int cmask = ~rmode; for (slice = 0; slice < slices; slice++) { - slice_start = (slice * height) / slices; - slice_height = ((slice + 1) * height) / slices - slice_start; + slice_start = ((slice * height) / slices) & cmask; + slice_height = ((((slice + 1) * height) / slices) & cmask) - slice_start; bsrc = src + slice_start * stride; @@ -337,7 +339,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (c->frame_pred == PRED_MEDIAN) restore_median(c->pic.data[0] + rgb_order[i], c->planes, c->pic.linesize[0], avctx->width, avctx->height, - c->slices); + c->slices, 0); } restore_rgb_planes(c->pic.data[0], c->planes, c->pic.linesize[0], avctx->width, avctx->height); @@ -353,7 +355,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (c->frame_pred == PRED_MEDIAN) restore_median(c->pic.data[i], 1, c->pic.linesize[i], avctx->width >> !!i, avctx->height >> !!i, - c->slices); + c->slices, !i); } break; case PIX_FMT_YUV422P: @@ -366,7 +368,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac return ret; if (c->frame_pred == PRED_MEDIAN) restore_median(c->pic.data[i], 1, c->pic.linesize[i], - avctx->width >> !!i, avctx->height, c->slices); + avctx->width >> !!i, avctx->height, c->slices, 0); } break; } From 69e7ad8dbc9896aff70f1f1125c726764f28455f Mon Sep 17 00:00:00 2001 From: Benjamin Larsson Date: Sat, 29 Oct 2011 12:57:10 +0200 Subject: [PATCH 07/51] mov: Avoid divide by zero in edit list dts handling Signed-off-by: Ronald S. Bultje --- libavformat/mov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 1747bd41a2d99..2036f5134aa9d 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1605,7 +1605,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st) if (sc->time_offset < 0) sc->time_offset = av_rescale(sc->time_offset, sc->time_scale, mov->time_scale); current_dts = -sc->time_offset; - if (sc->ctts_data && sc->stts_data && + if (sc->ctts_data && sc->stts_data && sc->stts_data[0].duration && sc->ctts_data[0].duration / sc->stts_data[0].duration > 16) { /* more than 16 frames delay, dts are likely wrong this happens with files created by iMovie */ From c25df22365b059a36f63f2810ef26abaec833231 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 26 Oct 2011 18:30:22 -0400 Subject: [PATCH 08/51] cook: output float samples instead of converting to int16 --- libavcodec/cook.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 13f2dd66a6386..d3e7de8c78a8f 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -124,7 +124,7 @@ typedef struct cook { void (* interpolate) (struct cook *q, float* buffer, int gain_index, int gain_index_next); - void (* saturate_output) (struct cook *q, int chan, int16_t *out); + void (* saturate_output) (struct cook *q, int chan, float *out); AVCodecContext* avctx; GetBitContext gb; @@ -229,7 +229,7 @@ static av_cold int init_cook_mlt(COOKContext *q) { q->mlt_window[j] *= sqrt(2.0 / q->samples_per_channel); /* Initialize the MDCT. */ - if (ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size)+1, 1, 1.0)) { + if (ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size)+1, 1, 1.0/32768.0)) { av_free(q->mlt_window); return -1; } @@ -867,22 +867,18 @@ decode_bytes_and_gain(COOKContext *q, COOKSubpacket *p, const uint8_t *inbuffer, } /** - * Saturate the output signal to signed 16bit integers. + * Saturate the output signal and interleave. * * @param q pointer to the COOKContext * @param chan channel to saturate * @param out pointer to the output vector */ -static void -saturate_output_float (COOKContext *q, int chan, int16_t *out) +static void saturate_output_float(COOKContext *q, int chan, float *out) { int j; float *output = q->mono_mdct_output + q->samples_per_channel; - /* Clip and convert floats to 16 bits. - */ for (j = 0; j < q->samples_per_channel; j++) { - out[chan + q->nb_channels * j] = - av_clip_int16(lrintf(output[j])); + out[chan + q->nb_channels * j] = av_clipf(output[j], -1.0, 1.0); } } @@ -902,7 +898,7 @@ saturate_output_float (COOKContext *q, int chan, int16_t *out) static inline void mlt_compensate_output(COOKContext *q, float *decode_buffer, cook_gains *gains_ptr, float *previous_buffer, - int16_t *out, int chan) + float *out, int chan) { imlt_gain(q, decode_buffer, gains_ptr, previous_buffer); q->saturate_output (q, chan, out); @@ -917,7 +913,9 @@ mlt_compensate_output(COOKContext *q, float *decode_buffer, * @param inbuffer pointer to the inbuffer * @param outbuffer pointer to the outbuffer */ -static void decode_subpacket(COOKContext *q, COOKSubpacket* p, const uint8_t *inbuffer, int16_t *outbuffer) { +static void decode_subpacket(COOKContext *q, COOKSubpacket *p, + const uint8_t *inbuffer, float *outbuffer) +{ int sub_packet_size = p->size; /* packet dump */ // for (i=0 ; isubpacket[i].bits_per_subpacket = (q->subpacket[i].size*8)>>q->subpacket[i].bits_per_subpdiv; q->subpacket[i].ch_idx = chidx; av_log(avctx,AV_LOG_DEBUG,"subpacket[%i] size %i js %i %i block_align %i\n",i,q->subpacket[i].size,q->subpacket[i].joint_stereo,offset,avctx->block_align); - decode_subpacket(q, &q->subpacket[i], buf + offset, (int16_t*)data); + decode_subpacket(q, &q->subpacket[i], buf + offset, data); offset += q->subpacket[i].size; chidx += q->subpacket[i].num_channels; av_log(avctx,AV_LOG_DEBUG,"subpacket[%i] %i %i\n",i,q->subpacket[i].size * 8,get_bits_count(&q->gb)); } - *data_size = sizeof(int16_t) * q->nb_channels * q->samples_per_channel; + *data_size = q->nb_channels * q->samples_per_channel * + av_get_bytes_per_sample(avctx->sample_fmt); /* Discard the first two frames: no valid audio. */ if (avctx->frame_number < 2) *data_size = 0; @@ -1240,7 +1239,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) return -1; } - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; if (channel_mask) avctx->channel_layout = channel_mask; else From 776e9815a523eb817b47dd34ac56e4cbdabff17e Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 26 Oct 2011 18:36:08 -0400 Subject: [PATCH 09/51] cook: remove unneeded #includes --- libavcodec/cook.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index d3e7de8c78a8f..93e17586659d0 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -42,12 +42,7 @@ * available. */ -#include -#include -#include - #include "libavutil/lfg.h" -#include "libavutil/random_seed.h" #include "avcodec.h" #include "get_bits.h" #include "dsputil.h" From e694831f9d0cb75225b8ce300db4f20da85b7438 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 26 Oct 2011 20:42:02 -0400 Subject: [PATCH 10/51] cook: avoid hardcoded sizes in sizeof() --- libavcodec/cook.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 93e17586659d0..25a698c21d4da 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -215,7 +215,7 @@ static av_cold int init_cook_mlt(COOKContext *q) { int j; int mlt_size = q->samples_per_channel; - if ((q->mlt_window = av_malloc(sizeof(float)*mlt_size)) == 0) + if ((q->mlt_window = av_malloc(mlt_size * sizeof(*q->mlt_window))) == 0) return -1; /* Initialize the MLT window: simple sine window. */ @@ -405,9 +405,9 @@ static void categorize(COOKContext *q, COOKSubpacket *p, int* quant_index_table, //av_log(q->avctx, AV_LOG_ERROR, "bits_left = %d\n",bits_left); } - memset(&exp_index1,0,102*sizeof(int)); - memset(&exp_index2,0,102*sizeof(int)); - memset(&tmp_categorize_array,0,128*2*sizeof(int)); + memset(&exp_index1, 0, sizeof(exp_index1)); + memset(&exp_index2, 0, sizeof(exp_index2)); + memset(&tmp_categorize_array, 0, sizeof(tmp_categorize_array)); bias=-32; @@ -628,8 +628,8 @@ static void mono_decode(COOKContext *q, COOKSubpacket *p, float* mlt_buffer) { int quant_index_table[102]; int category[128]; - memset(&category, 0, 128*sizeof(int)); - memset(&category_index, 0, 128*sizeof(int)); + memset(&category, 0, sizeof(category)); + memset(&category_index, 0, sizeof(category_index)); decode_envelope(q, p, quant_index_table); q->num_vectors = get_bits(&q->gb,p->log2_numvector_size); @@ -728,7 +728,8 @@ static void imlt_gain(COOKContext *q, float *inbuffer, } /* Save away the current to be previous block. */ - memcpy(previous_buffer, buffer0, sizeof(float)*q->samples_per_channel); + memcpy(previous_buffer, buffer0, + q->samples_per_channel * sizeof(*previous_buffer)); } @@ -806,11 +807,11 @@ static void joint_decode(COOKContext *q, COOKSubpacket *p, float* mlt_buffer1, const float* cplscale; memset(decouple_tab, 0, sizeof(decouple_tab)); - memset(decode_buffer, 0, sizeof(decode_buffer)); + memset(decode_buffer, 0, sizeof(q->decode_buffer_0)); /* Make sure the buffers are zeroed out. */ - memset(mlt_buffer1,0, 1024*sizeof(float)); - memset(mlt_buffer2,0, 1024*sizeof(float)); + memset(mlt_buffer1, 0, 1024 * sizeof(*mlt_buffer1)); + memset(mlt_buffer2, 0, 1024 * sizeof(*mlt_buffer2)); decouple_info(q, p, decouple_tab); mono_decode(q, p, decode_buffer); From f193c96f49c5a0778a06ed1279593cc6ed536052 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 26 Oct 2011 20:46:36 -0400 Subject: [PATCH 11/51] cook: return appropriate error codes instead of -1 --- libavcodec/cook.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 25a698c21d4da..957775727ba93 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -212,11 +212,11 @@ static av_cold int init_cook_vlc_tables(COOKContext *q) { } static av_cold int init_cook_mlt(COOKContext *q) { - int j; + int j, ret; int mlt_size = q->samples_per_channel; if ((q->mlt_window = av_malloc(mlt_size * sizeof(*q->mlt_window))) == 0) - return -1; + return AVERROR(ENOMEM); /* Initialize the MLT window: simple sine window. */ ff_sine_window_init(q->mlt_window, mlt_size); @@ -224,9 +224,9 @@ static av_cold int init_cook_mlt(COOKContext *q) { q->mlt_window[j] *= sqrt(2.0 / q->samples_per_channel); /* Initialize the MDCT. */ - if (ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size)+1, 1, 1.0/32768.0)) { - av_free(q->mlt_window); - return -1; + if ((ret = ff_mdct_init(&q->mdct_ctx, av_log2(mlt_size)+1, 1, 1.0/32768.0))) { + av_free(q->mlt_window); + return ret; } av_log(q->avctx,AV_LOG_DEBUG,"MDCT initialized, order = %d.\n", av_log2(mlt_size)+1); @@ -975,7 +975,7 @@ static int cook_decode_frame(AVCodecContext *avctx, q->subpacket[0].size -= q->subpacket[i].size + 1; if (q->subpacket[0].size < 0) { av_log(avctx,AV_LOG_DEBUG,"frame subpacket size total > avctx->block_align!\n"); - return -1; + return AVERROR_INVALIDDATA; } } @@ -1048,12 +1048,13 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) int extradata_size = avctx->extradata_size; int s = 0; unsigned int channel_mask = 0; + int ret; q->avctx = avctx; /* Take care of the codec specific extradata. */ if (extradata_size <= 0) { av_log(avctx,AV_LOG_ERROR,"Necessary extradata missing!\n"); - return -1; + return AVERROR_INVALIDDATA; } av_log(avctx,AV_LOG_DEBUG,"codecdata_length=%d\n",avctx->extradata_size); @@ -1098,7 +1099,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) case MONO: if (q->nb_channels != 1) { av_log_ask_for_sample(avctx, "Container channels != 1.\n"); - return -1; + return AVERROR(ENOTSUP); } av_log(avctx,AV_LOG_DEBUG,"MONO\n"); break; @@ -1112,7 +1113,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) case JOINT_STEREO: if (q->nb_channels != 2) { av_log_ask_for_sample(avctx, "Container channels != 2.\n"); - return -1; + return AVERROR(ENOTSUP); } av_log(avctx,AV_LOG_DEBUG,"JOINT_STEREO\n"); if (avctx->extradata_size >= 16){ @@ -1150,12 +1151,12 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) break; default: av_log_ask_for_sample(avctx, "Unknown Cook version.\n"); - return -1; + return AVERROR(ENOTSUP); } if(s > 1 && q->subpacket[s].samples_per_channel != q->samples_per_channel) { av_log(avctx,AV_LOG_ERROR,"different number of samples per channel!\n"); - return -1; + return AVERROR_INVALIDDATA; } else q->samples_per_channel = q->subpacket[0].samples_per_channel; @@ -1166,18 +1167,18 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) /* Try to catch some obviously faulty streams, othervise it might be exploitable */ if (q->subpacket[s].total_subbands > 53) { av_log_ask_for_sample(avctx, "total_subbands > 53\n"); - return -1; + return AVERROR(ENOTSUP); } if ((q->subpacket[s].js_vlc_bits > 6) || (q->subpacket[s].js_vlc_bits < 2*q->subpacket[s].joint_stereo)) { av_log(avctx,AV_LOG_ERROR,"js_vlc_bits = %d, only >= %d and <= 6 allowed!\n", q->subpacket[s].js_vlc_bits, 2*q->subpacket[s].joint_stereo); - return -1; + return AVERROR_INVALIDDATA; } if (q->subpacket[s].subbands > 50) { av_log_ask_for_sample(avctx, "subbands > 50\n"); - return -1; + return AVERROR(ENOTSUP); } q->subpacket[s].gains1.now = q->subpacket[s].gain_1; q->subpacket[s].gains1.previous = q->subpacket[s].gain_2; @@ -1188,7 +1189,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) s++; if (s > MAX_SUBPACKETS) { av_log_ask_for_sample(avctx, "Too many subpackets > 5\n"); - return -1; + return AVERROR(ENOTSUP); } } /* Generate tables */ @@ -1196,12 +1197,12 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) init_gain_table(q); init_cplscales_table(q); - if (init_cook_vlc_tables(q) != 0) - return -1; + if ((ret = init_cook_vlc_tables(q))) + return ret; if(avctx->block_align >= UINT_MAX/2) - return -1; + return AVERROR(EINVAL); /* Pad the databuffer with: DECODE_BYTES_PAD1 or DECODE_BYTES_PAD2 for decode_bytes(), @@ -1211,11 +1212,11 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) + DECODE_BYTES_PAD1(avctx->block_align) + FF_INPUT_BUFFER_PADDING_SIZE); if (q->decoded_bytes_buffer == NULL) - return -1; + return AVERROR(ENOMEM); /* Initialize transform. */ - if ( init_cook_mlt(q) != 0 ) - return -1; + if ((ret = init_cook_mlt(q))) + return ret; /* Initialize COOK signal arithmetic handling */ if (1) { @@ -1232,7 +1233,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) av_log_ask_for_sample(avctx, "unknown amount of samples_per_channel = %d\n", q->samples_per_channel); - return -1; + return AVERROR(ENOTSUP); } avctx->sample_fmt = AV_SAMPLE_FMT_FLT; From c9c841e2314ab9812f4956441e91f90193fcac5e Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 26 Oct 2011 20:59:14 -0400 Subject: [PATCH 12/51] cook: simplify decouple_info() --- libavcodec/cook.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 957775727ba93..7157a8ce0178e 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -740,27 +740,24 @@ static void imlt_gain(COOKContext *q, float *inbuffer, * @param decouple_tab decoupling array * */ +static void decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab) +{ + int i; + int vlc = get_bits1(&q->gb); + int start = cplband[p->js_subband_start]; + int end = cplband[p->subbands-1]; + int length = end - start + 1; -static void decouple_info(COOKContext *q, COOKSubpacket *p, int* decouple_tab){ - int length, i; - - if(get_bits1(&q->gb)) { - if(cplband[p->js_subband_start] > cplband[p->subbands-1]) return; - - length = cplband[p->subbands-1] - cplband[p->js_subband_start] + 1; - for (i=0 ; ijs_subband_start] + i] = get_vlc2(&q->gb, p->ccpl.table, p->ccpl.bits, 2); - } + if (start > end) return; - } - if(cplband[p->js_subband_start] > cplband[p->subbands-1]) return; - - length = cplband[p->subbands-1] - cplband[p->js_subband_start] + 1; - for (i=0 ; ijs_subband_start] + i] = get_bits(&q->gb, p->js_vlc_bits); + if (vlc) { + for (i = 0; i < length; i++) + decouple_tab[start + i] = get_vlc2(&q->gb, p->ccpl.table, p->ccpl.bits, 2); + } else { + for (i = 0; i < length; i++) + decouple_tab[start + i] = get_bits(&q->gb, p->js_vlc_bits); } - return; } /* From b277ebd508a0ceeb187d5ae8c463ce6ffb06b4c8 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 26 Oct 2011 21:03:49 -0400 Subject: [PATCH 13/51] cook: remove pointless return statements --- libavcodec/cook.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 7157a8ce0178e..462a8c40fc976 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -658,14 +658,12 @@ static void interpolate_float(COOKContext *q, float* buffer, for(i=0 ; igain_size_factor ; i++){ buffer[i]*=fc1; } - return; } else { //smooth gain fc2 = q->gain_table[11 + (gain_index_next-gain_index)]; for(i=0 ; igain_size_factor ; i++){ buffer[i]*=fc1; fc1*=fc2; } - return; } } From 6631294c26b82f11b1862bdc3a6685a201afd19d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 26 Oct 2011 21:08:57 -0400 Subject: [PATCH 14/51] cook: do not needlessly set *data_size to 0 --- libavcodec/cook.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 462a8c40fc976..eefbf4ad48111 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -975,7 +975,6 @@ static int cook_decode_frame(AVCodecContext *avctx, } /* decode supbackets */ - *data_size = 0; for(i=0;inum_subpackets;i++){ q->subpacket[i].bits_per_subpacket = (q->subpacket[i].size*8)>>q->subpacket[i].bits_per_subpdiv; q->subpacket[i].ch_idx = chidx; From e34c6c9708336b9445574bb6ddb48416368af963 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 26 Oct 2011 21:11:13 -0400 Subject: [PATCH 15/51] cook: check output buffer size before decoding --- libavcodec/cook.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index eefbf4ad48111..9e3cd624a0468 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -955,13 +955,20 @@ static int cook_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; COOKContext *q = avctx->priv_data; - int i; + int i, out_size; int offset = 0; int chidx = 0; if (buf_size < avctx->block_align) return buf_size; + out_size = q->nb_channels * q->samples_per_channel * + av_get_bytes_per_sample(avctx->sample_fmt); + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); + } + /* estimate subpacket sizes */ q->subpacket[0].size = avctx->block_align; @@ -984,8 +991,7 @@ static int cook_decode_frame(AVCodecContext *avctx, chidx += q->subpacket[i].num_channels; av_log(avctx,AV_LOG_DEBUG,"subpacket[%i] %i %i\n",i,q->subpacket[i].size * 8,get_bits_count(&q->gb)); } - *data_size = q->nb_channels * q->samples_per_channel * - av_get_bytes_per_sample(avctx->sample_fmt); + *data_size = out_size; /* Discard the first two frames: no valid audio. */ if (avctx->frame_number < 2) *data_size = 0; From 5c353eb8e38d4861e325a767fb18d24b316e9799 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 29 Oct 2011 14:31:11 -0400 Subject: [PATCH 16/51] cook: return AVERROR_PATCHWELCOME instead of ENOTSUP ENOTSUP is not defined on some systems --- libavcodec/cook.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 9e3cd624a0468..5a3822d4c7cef 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -1099,7 +1099,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) case MONO: if (q->nb_channels != 1) { av_log_ask_for_sample(avctx, "Container channels != 1.\n"); - return AVERROR(ENOTSUP); + return AVERROR_PATCHWELCOME; } av_log(avctx,AV_LOG_DEBUG,"MONO\n"); break; @@ -1113,7 +1113,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) case JOINT_STEREO: if (q->nb_channels != 2) { av_log_ask_for_sample(avctx, "Container channels != 2.\n"); - return AVERROR(ENOTSUP); + return AVERROR_PATCHWELCOME; } av_log(avctx,AV_LOG_DEBUG,"JOINT_STEREO\n"); if (avctx->extradata_size >= 16){ @@ -1151,7 +1151,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) break; default: av_log_ask_for_sample(avctx, "Unknown Cook version.\n"); - return AVERROR(ENOTSUP); + return AVERROR_PATCHWELCOME; } if(s > 1 && q->subpacket[s].samples_per_channel != q->samples_per_channel) { @@ -1167,7 +1167,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) /* Try to catch some obviously faulty streams, othervise it might be exploitable */ if (q->subpacket[s].total_subbands > 53) { av_log_ask_for_sample(avctx, "total_subbands > 53\n"); - return AVERROR(ENOTSUP); + return AVERROR_PATCHWELCOME; } if ((q->subpacket[s].js_vlc_bits > 6) || (q->subpacket[s].js_vlc_bits < 2*q->subpacket[s].joint_stereo)) { @@ -1178,7 +1178,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) if (q->subpacket[s].subbands > 50) { av_log_ask_for_sample(avctx, "subbands > 50\n"); - return AVERROR(ENOTSUP); + return AVERROR_PATCHWELCOME; } q->subpacket[s].gains1.now = q->subpacket[s].gain_1; q->subpacket[s].gains1.previous = q->subpacket[s].gain_2; @@ -1189,7 +1189,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) s++; if (s > MAX_SUBPACKETS) { av_log_ask_for_sample(avctx, "Too many subpackets > 5\n"); - return AVERROR(ENOTSUP); + return AVERROR_PATCHWELCOME; } } /* Generate tables */ @@ -1233,7 +1233,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) av_log_ask_for_sample(avctx, "unknown amount of samples_per_channel = %d\n", q->samples_per_channel); - return AVERROR(ENOTSUP); + return AVERROR_PATCHWELCOME; } avctx->sample_fmt = AV_SAMPLE_FMT_FLT; From 33684b9c12b74c0140fb91e8150263db4a48d55e Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 14 Oct 2011 00:16:31 -0400 Subject: [PATCH 17/51] atrac1: check output buffer size before decoding --- libavcodec/atrac1.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index 0ba2cf6bddea0..371f21ae3d67f 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -276,7 +276,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AT1Ctx *q = avctx->priv_data; - int ch, ret, i; + int ch, ret, i, out_size; GetBitContext gb; float* samples = data; @@ -286,6 +286,13 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, return -1; } + out_size = q->channels * AT1_SU_SAMPLES * + av_get_bytes_per_sample(avctx->sample_fmt); + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); + } + for (ch = 0; ch < q->channels; ch++) { AT1SUCtx* su = &q->SUs[ch]; @@ -318,7 +325,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, } } - *data_size = q->channels * AT1_SU_SAMPLES * sizeof(*samples); + *data_size = out_size; return avctx->block_align; } From 9a35ff384124a08209a8ee5355fdec93440d0e37 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 14 Oct 2011 00:22:01 -0400 Subject: [PATCH 18/51] atrac1: decode mono audio directly to output buffer For stereo we need to use intermediate planar buffers, but mono does not need to be deinterleaved so the output buffer can be used directly. --- libavcodec/atrac1.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index 371f21ae3d67f..4647e0c35175f 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -310,15 +310,11 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, ret = at1_imdct_block(su, q); if (ret < 0) return ret; - at1_subband_synthesis(q, su, q->out_samples[ch]); + at1_subband_synthesis(q, su, q->channels == 1 ? samples : q->out_samples[ch]); } /* interleave; FIXME, should create/use a DSP function */ - if (q->channels == 1) { - /* mono */ - memcpy(samples, q->out_samples[0], AT1_SU_SAMPLES * 4); - } else { - /* stereo */ + if (q->channels == 2) { for (i = 0; i < AT1_SU_SAMPLES; i++) { samples[i * 2] = q->out_samples[0][i]; samples[i * 2 + 1] = q->out_samples[1][i]; From bff5b2c1ca1290ea30587ff2f76171f9e3854872 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 14 Oct 2011 00:24:50 -0400 Subject: [PATCH 19/51] atrac1: validate number of channels --- libavcodec/atrac1.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index 4647e0c35175f..1ba580cbacaea 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -332,6 +332,11 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + if (avctx->channels < 1 || avctx->channels > AT1_MAX_CHANNELS) { + av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %d\n", + avctx->channels); + return AVERROR(EINVAL); + } q->channels = avctx->channels; /* Init the mdct transforms */ From 96b5702efe62180f57ea4d4be9b60fadd7d269b0 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 14 Oct 2011 00:30:42 -0400 Subject: [PATCH 20/51] atrac1: fix a typo --- libavcodec/atrac1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index 1ba580cbacaea..d129f102f3778 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -282,7 +282,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, if (buf_size < 212 * q->channels) { - av_log(q,AV_LOG_ERROR,"Not enought data to decode!\n"); + av_log(q,AV_LOG_ERROR,"Not enough data to decode!\n"); return -1; } From 21dcecc310e701d035b6a877139b9dd8e2a82a1a Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 14 Oct 2011 15:25:01 -0400 Subject: [PATCH 21/51] atrac1: use optimized float_interleave() function for stereo interleaving --- libavcodec/atrac1.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index d129f102f3778..c646ba9fc1d79 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -36,6 +36,7 @@ #include "get_bits.h" #include "dsputil.h" #include "fft.h" +#include "fmtconvert.h" #include "sinewin.h" #include "atrac.h" @@ -78,10 +79,11 @@ typedef struct { DECLARE_ALIGNED(32, float, mid)[256]; DECLARE_ALIGNED(32, float, high)[512]; float* bands[3]; - DECLARE_ALIGNED(32, float, out_samples)[AT1_MAX_CHANNELS][AT1_SU_SAMPLES]; + float *out_samples[AT1_MAX_CHANNELS]; FFTContext mdct_ctx[3]; int channels; DSPContext dsp; + FmtConvertContext fmt_conv; } AT1Ctx; /** size of the transform in samples in the long mode for each QMF band */ @@ -276,7 +278,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AT1Ctx *q = avctx->priv_data; - int ch, ret, i, out_size; + int ch, ret, out_size; GetBitContext gb; float* samples = data; @@ -313,12 +315,10 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, at1_subband_synthesis(q, su, q->channels == 1 ? samples : q->out_samples[ch]); } - /* interleave; FIXME, should create/use a DSP function */ + /* interleave */ if (q->channels == 2) { - for (i = 0; i < AT1_SU_SAMPLES; i++) { - samples[i * 2] = q->out_samples[0][i]; - samples[i * 2 + 1] = q->out_samples[1][i]; - } + q->fmt_conv.float_interleave(samples, (const float **)q->out_samples, + AT1_SU_SAMPLES, 2); } *data_size = out_size; @@ -339,6 +339,15 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx) } q->channels = avctx->channels; + if (avctx->channels == 2) { + q->out_samples[0] = av_malloc(2 * AT1_SU_SAMPLES * sizeof(*q->out_samples[0])); + q->out_samples[1] = q->out_samples[0] + AT1_SU_SAMPLES; + if (!q->out_samples[0]) { + av_freep(&q->out_samples[0]); + return AVERROR(ENOMEM); + } + } + /* Init the mdct transforms */ ff_mdct_init(&q->mdct_ctx[0], 6, 1, -1.0/ (1 << 15)); ff_mdct_init(&q->mdct_ctx[1], 8, 1, -1.0/ (1 << 15)); @@ -349,6 +358,7 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx) atrac_generate_tables(); dsputil_init(&q->dsp, avctx); + ff_fmt_convert_init(&q->fmt_conv, avctx); q->bands[0] = q->low; q->bands[1] = q->mid; @@ -367,6 +377,8 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx) static av_cold int atrac1_decode_end(AVCodecContext * avctx) { AT1Ctx *q = avctx->priv_data; + av_freep(&q->out_samples[0]); + ff_mdct_end(&q->mdct_ctx[0]); ff_mdct_end(&q->mdct_ctx[1]); ff_mdct_end(&q->mdct_ctx[2]); From 6dc7dd7af45aa1e341b471fd054f85ae2747775b Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 28 Oct 2011 13:07:20 -0400 Subject: [PATCH 22/51] atrac1: check for ff_mdct_init() failure --- libavcodec/atrac1.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index c646ba9fc1d79..3f42deaa7e96d 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -326,9 +326,24 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, } +static av_cold int atrac1_decode_end(AVCodecContext * avctx) +{ + AT1Ctx *q = avctx->priv_data; + + av_freep(&q->out_samples[0]); + + ff_mdct_end(&q->mdct_ctx[0]); + ff_mdct_end(&q->mdct_ctx[1]); + ff_mdct_end(&q->mdct_ctx[2]); + + return 0; +} + + static av_cold int atrac1_decode_init(AVCodecContext *avctx) { AT1Ctx *q = avctx->priv_data; + int ret; avctx->sample_fmt = AV_SAMPLE_FMT_FLT; @@ -349,9 +364,13 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx) } /* Init the mdct transforms */ - ff_mdct_init(&q->mdct_ctx[0], 6, 1, -1.0/ (1 << 15)); - ff_mdct_init(&q->mdct_ctx[1], 8, 1, -1.0/ (1 << 15)); - ff_mdct_init(&q->mdct_ctx[2], 9, 1, -1.0/ (1 << 15)); + if ((ret = ff_mdct_init(&q->mdct_ctx[0], 6, 1, -1.0/ (1 << 15))) || + (ret = ff_mdct_init(&q->mdct_ctx[1], 8, 1, -1.0/ (1 << 15))) || + (ret = ff_mdct_init(&q->mdct_ctx[2], 9, 1, -1.0/ (1 << 15)))) { + av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n"); + atrac1_decode_end(avctx); + return ret; + } ff_init_ff_sine_windows(5); @@ -374,18 +393,6 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx) } -static av_cold int atrac1_decode_end(AVCodecContext * avctx) { - AT1Ctx *q = avctx->priv_data; - - av_freep(&q->out_samples[0]); - - ff_mdct_end(&q->mdct_ctx[0]); - ff_mdct_end(&q->mdct_ctx[1]); - ff_mdct_end(&q->mdct_ctx[2]); - return 0; -} - - AVCodec ff_atrac1_decoder = { .name = "atrac1", .type = AVMEDIA_TYPE_AUDIO, From f20dd574f1a9933abe5e9405908bcf2c4111cc25 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 28 Oct 2011 13:10:27 -0400 Subject: [PATCH 23/51] atrac1: return appropriate error codes instead of -1 --- libavcodec/atrac1.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index 3f42deaa7e96d..ef5156c650790 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -131,7 +131,7 @@ static int at1_imdct_block(AT1SUCtx* su, AT1Ctx *q) nbits = mdct_long_nbits[band_num] - log2_block_count; if (nbits != 5 && nbits != 7 && nbits != 8) - return -1; + return AVERROR_INVALIDDATA; } else { block_size = 32; nbits = 5; @@ -175,14 +175,14 @@ static int at1_parse_bsm(GetBitContext* gb, int log2_block_cnt[AT1_QMF_BANDS]) /* low and mid band */ log2_block_count_tmp = get_bits(gb, 2); if (log2_block_count_tmp & 1) - return -1; + return AVERROR_INVALIDDATA; log2_block_cnt[i] = 2 - log2_block_count_tmp; } /* high band */ log2_block_count_tmp = get_bits(gb, 2); if (log2_block_count_tmp != 0 && log2_block_count_tmp != 3) - return -1; + return AVERROR_INVALIDDATA; log2_block_cnt[IDX_HIGH_BAND] = 3 - log2_block_count_tmp; skip_bits(gb, 2); @@ -231,7 +231,7 @@ static int at1_unpack_dequant(GetBitContext* gb, AT1SUCtx* su, /* check for bitstream overflow */ if (bits_used > AT1_SU_MAX_BITS) - return -1; + return AVERROR_INVALIDDATA; /* get the position of the 1st spec according to the block size mode */ pos = su->log2_block_count[band_num] ? bfu_start_short[bfu_num] : bfu_start_long[bfu_num]; @@ -285,7 +285,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, if (buf_size < 212 * q->channels) { av_log(q,AV_LOG_ERROR,"Not enough data to decode!\n"); - return -1; + return AVERROR_INVALIDDATA; } out_size = q->channels * AT1_SU_SAMPLES * From c4a6fde33feeb0519588f52a64082083c4afdbe6 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 14 Oct 2011 16:13:30 -0400 Subject: [PATCH 24/51] atrac3: decode output to float samples instead of converting to s16 --- libavcodec/atrac3.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index accaae3d65e6f..ee70cfe345522 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -208,7 +208,7 @@ static av_cold void init_atrac3_transforms(ATRAC3Context *q) { } /* Initialize the MDCT transform. */ - ff_mdct_init(&q->mdct_ctx, 9, 1, 1.0); + ff_mdct_init(&q->mdct_ctx, 9, 1, 1.0 / 32768); } /** @@ -825,7 +825,7 @@ static int atrac3_decode_frame(AVCodecContext *avctx, ATRAC3Context *q = avctx->priv_data; int result = 0, i; const uint8_t* databuf; - int16_t* samples = data; + float *samples = data; if (buf_size < avctx->block_align) { av_log(avctx, AV_LOG_ERROR, @@ -852,16 +852,15 @@ static int atrac3_decode_frame(AVCodecContext *avctx, if (q->channels == 1) { /* mono */ for (i = 0; i<1024; i++) - samples[i] = av_clip_int16(round(q->outSamples[i])); - *data_size = 1024 * sizeof(int16_t); + samples[i] = q->outSamples[i]; } else { /* stereo */ for (i = 0; i < 1024; i++) { - samples[i*2] = av_clip_int16(round(q->outSamples[i])); - samples[i*2+1] = av_clip_int16(round(q->outSamples[1024+i])); + samples[i*2] = q->outSamples[i]; + samples[i*2+1] = q->outSamples[1024+i]; } - *data_size = 2048 * sizeof(int16_t); } + *data_size = 1024 * q->channels * av_get_bytes_per_sample(avctx->sample_fmt); return avctx->block_align; } @@ -1014,7 +1013,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; return 0; } From 8af33cb38a00a5b80901854d8d6efaa1dba25373 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 14 Oct 2011 16:32:55 -0400 Subject: [PATCH 25/51] atrac3: decode mono directly to the output buffer --- libavcodec/atrac3.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index ee70cfe345522..f809f9a287a5d 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -719,7 +719,8 @@ static int decodeChannelSoundUnit (ATRAC3Context *q, GetBitContext *gb, channel_ * @param databuf the input data */ -static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf) +static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf, + float *out_samples) { int result, i; float *p1, *p2, *p3, *p4; @@ -731,7 +732,7 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf) /* decode Sound Unit 1 */ init_get_bits(&q->gb,databuf,q->bits_per_frame); - result = decodeChannelSoundUnit(q,&q->gb, q->pUnits, q->outSamples, 0, JOINT_STEREO); + result = decodeChannelSoundUnit(q,&q->gb, q->pUnits, out_samples, 0, JOINT_STEREO); if (result != 0) return (result); @@ -772,14 +773,14 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf) } /* Decode Sound Unit 2. */ - result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[1], &q->outSamples[1024], 1, JOINT_STEREO); + result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[1], &out_samples[1024], 1, JOINT_STEREO); if (result != 0) return (result); /* Reconstruct the channel coefficients. */ - reverseMatrixing(q->outSamples, &q->outSamples[1024], q->matrix_coeff_index_prev, q->matrix_coeff_index_now); + reverseMatrixing(out_samples, &out_samples[1024], q->matrix_coeff_index_prev, q->matrix_coeff_index_now); - channelWeighting(q->outSamples, &q->outSamples[1024], q->weighting_delay); + channelWeighting(out_samples, &out_samples[1024], q->weighting_delay); } else { /* normal stereo mode or mono */ @@ -789,14 +790,14 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf) /* Set the bitstream reader at the start of a channel sound unit. */ init_get_bits(&q->gb, databuf+((i*q->bytes_per_frame)/q->channels), (q->bits_per_frame)/q->channels); - result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[i], &q->outSamples[i*1024], i, q->codingMode); + result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[i], &out_samples[i*1024], i, q->codingMode); if (result != 0) return (result); } } /* Apply the iQMF synthesis filter. */ - p1= q->outSamples; + p1 = out_samples; for (i=0 ; ichannels ; i++) { p2= p1+256; p3= p2+256; @@ -842,19 +843,15 @@ static int atrac3_decode_frame(AVCodecContext *avctx, databuf = buf; } - result = decodeFrame(q, databuf); + result = decodeFrame(q, databuf, q->channels == 2 ? q->outSamples : samples); if (result != 0) { av_log(NULL,AV_LOG_ERROR,"Frame decoding error!\n"); return -1; } - if (q->channels == 1) { - /* mono */ - for (i = 0; i<1024; i++) - samples[i] = q->outSamples[i]; - } else { - /* stereo */ + /* interleave */ + if (q->channels == 2) { for (i = 0; i < 1024; i++) { samples[i*2] = q->outSamples[i]; samples[i*2+1] = q->outSamples[1024+i]; From 5e76b8bb760e1d81e5a23552e94c4173b6a625d1 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 14 Oct 2011 16:47:03 -0400 Subject: [PATCH 26/51] atrac3: use optimized float_interleave() function for stereo interleaving --- libavcodec/atrac3.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index f809f9a287a5d..ab14910e28f3d 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -41,6 +41,7 @@ #include "dsputil.h" #include "bytestream.h" #include "fft.h" +#include "fmtconvert.h" #include "atrac.h" #include "atrac3data.h" @@ -107,7 +108,7 @@ typedef struct { //@} //@{ /** data buffers */ - float outSamples[2048]; + float *outSamples[2]; uint8_t* decoded_bytes_buffer; float tempBuf[1070]; //@} @@ -120,6 +121,7 @@ typedef struct { //@} FFTContext mdct_ctx; + FmtConvertContext fmt_conv; } ATRAC3Context; static DECLARE_ALIGNED(32, float, mdct_window)[512]; @@ -221,6 +223,8 @@ static av_cold int atrac3_decode_close(AVCodecContext *avctx) av_free(q->pUnits); av_free(q->decoded_bytes_buffer); + av_freep(&q->outSamples[0]); + ff_mdct_end(&q->mdct_ctx); return 0; @@ -824,7 +828,7 @@ static int atrac3_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; ATRAC3Context *q = avctx->priv_data; - int result = 0, i; + int result = 0; const uint8_t* databuf; float *samples = data; @@ -843,7 +847,7 @@ static int atrac3_decode_frame(AVCodecContext *avctx, databuf = buf; } - result = decodeFrame(q, databuf, q->channels == 2 ? q->outSamples : samples); + result = decodeFrame(q, databuf, q->channels == 2 ? q->outSamples[0] : samples); if (result != 0) { av_log(NULL,AV_LOG_ERROR,"Frame decoding error!\n"); @@ -852,10 +856,8 @@ static int atrac3_decode_frame(AVCodecContext *avctx, /* interleave */ if (q->channels == 2) { - for (i = 0; i < 1024; i++) { - samples[i*2] = q->outSamples[i]; - samples[i*2+1] = q->outSamples[1024+i]; - } + q->fmt_conv.float_interleave(samples, (const float **)q->outSamples, + 1024, 2); } *data_size = 1024 * q->channels * av_get_bytes_per_sample(avctx->sample_fmt); @@ -1003,6 +1005,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) } dsputil_init(&dsp, avctx); + ff_fmt_convert_init(&q->fmt_conv, avctx); q->pUnits = av_mallocz(sizeof(channel_unit)*q->channels); if (!q->pUnits) { @@ -1010,6 +1013,15 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } + if (avctx->channels > 1) { + q->outSamples[0] = av_mallocz(1024 * 2 * sizeof(*q->outSamples[0])); + q->outSamples[1] = q->outSamples[0] + 1024; + if (!q->outSamples[0]) { + atrac3_decode_close(avctx); + return AVERROR(ENOMEM); + } + } + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; return 0; } From 6ba7f78bbb6cd10ecd3bf5db51295ff288e352ce Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 28 Oct 2011 13:29:41 -0400 Subject: [PATCH 27/51] atrac3: use separate pointers for each channel in decodeFrame() --- libavcodec/atrac3.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index ab14910e28f3d..8bd6adffd1744 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -724,7 +724,7 @@ static int decodeChannelSoundUnit (ATRAC3Context *q, GetBitContext *gb, channel_ */ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf, - float *out_samples) + float **out_samples) { int result, i; float *p1, *p2, *p3, *p4; @@ -736,7 +736,7 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf, /* decode Sound Unit 1 */ init_get_bits(&q->gb,databuf,q->bits_per_frame); - result = decodeChannelSoundUnit(q,&q->gb, q->pUnits, out_samples, 0, JOINT_STEREO); + result = decodeChannelSoundUnit(q,&q->gb, q->pUnits, out_samples[0], 0, JOINT_STEREO); if (result != 0) return (result); @@ -777,14 +777,14 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf, } /* Decode Sound Unit 2. */ - result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[1], &out_samples[1024], 1, JOINT_STEREO); + result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[1], out_samples[1], 1, JOINT_STEREO); if (result != 0) return (result); /* Reconstruct the channel coefficients. */ - reverseMatrixing(out_samples, &out_samples[1024], q->matrix_coeff_index_prev, q->matrix_coeff_index_now); + reverseMatrixing(out_samples[0], out_samples[1], q->matrix_coeff_index_prev, q->matrix_coeff_index_now); - channelWeighting(out_samples, &out_samples[1024], q->weighting_delay); + channelWeighting(out_samples[0], out_samples[1], q->weighting_delay); } else { /* normal stereo mode or mono */ @@ -794,22 +794,21 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf, /* Set the bitstream reader at the start of a channel sound unit. */ init_get_bits(&q->gb, databuf+((i*q->bytes_per_frame)/q->channels), (q->bits_per_frame)/q->channels); - result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[i], &out_samples[i*1024], i, q->codingMode); + result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[i], out_samples[i], i, q->codingMode); if (result != 0) return (result); } } /* Apply the iQMF synthesis filter. */ - p1 = out_samples; for (i=0 ; ichannels ; i++) { + p1 = out_samples[i]; p2= p1+256; p3= p2+256; p4= p3+256; atrac_iqmf (p1, p2, 256, p1, q->pUnits[i].delayBuf1, q->tempBuf); atrac_iqmf (p4, p3, 256, p3, q->pUnits[i].delayBuf2, q->tempBuf); atrac_iqmf (p1, p3, 512, p1, q->pUnits[i].delayBuf3, q->tempBuf); - p1 +=1024; } return 0; @@ -847,7 +846,7 @@ static int atrac3_decode_frame(AVCodecContext *avctx, databuf = buf; } - result = decodeFrame(q, databuf, q->channels == 2 ? q->outSamples[0] : samples); + result = decodeFrame(q, databuf, q->channels == 2 ? q->outSamples : &samples); if (result != 0) { av_log(NULL,AV_LOG_ERROR,"Frame decoding error!\n"); From 7e4881a2d074a7dfba7ee1990b3e17c9276f985d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 14 Oct 2011 17:09:58 -0400 Subject: [PATCH 28/51] atrac3: check output buffer size before decoding --- libavcodec/atrac3.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index 8bd6adffd1744..6828ff054ea66 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -827,7 +827,7 @@ static int atrac3_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; ATRAC3Context *q = avctx->priv_data; - int result = 0; + int result = 0, out_size; const uint8_t* databuf; float *samples = data; @@ -838,6 +838,12 @@ static int atrac3_decode_frame(AVCodecContext *avctx, return buf_size; } + out_size = 1024 * q->channels * av_get_bytes_per_sample(avctx->sample_fmt); + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); + } + /* Check if we need to descramble and what buffer to pass on. */ if (q->scrambled_stream) { decode_bytes(buf, q->decoded_bytes_buffer, avctx->block_align); @@ -858,7 +864,7 @@ static int atrac3_decode_frame(AVCodecContext *avctx, q->fmt_conv.float_interleave(samples, (const float **)q->outSamples, 1024, 2); } - *data_size = 1024 * q->channels * av_get_bytes_per_sample(avctx->sample_fmt); + *data_size = out_size; return avctx->block_align; } From 1fead73d7b3a71a662a986559d665e0dd0916688 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 14 Oct 2011 17:10:33 -0400 Subject: [PATCH 29/51] atrac3: return error if packet is too small --- libavcodec/atrac3.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index 6828ff054ea66..37245ef6a0ca5 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -834,8 +834,7 @@ static int atrac3_decode_frame(AVCodecContext *avctx, if (buf_size < avctx->block_align) { av_log(avctx, AV_LOG_ERROR, "Frame too small (%d bytes). Truncated file?\n", buf_size); - *data_size = 0; - return buf_size; + return AVERROR_INVALIDDATA; } out_size = 1024 * q->channels * av_get_bytes_per_sample(avctx->sample_fmt); From c91613857d618080af2cb61260c9391a1b23f75e Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 14 Oct 2011 17:17:46 -0400 Subject: [PATCH 30/51] atrac3: add a couple macro constants --- libavcodec/atrac3.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index 37245ef6a0ca5..76ceac8571a87 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -49,6 +49,8 @@ #define JOINT_STEREO 0x12 #define STEREO 0x2 +#define SAMPLES_PER_FRAME 1024 +#define MDCT_SIZE 512 /* These structures are needed to store the parsed gain control data. */ typedef struct { @@ -71,12 +73,12 @@ typedef struct { int bandsCoded; int numComponents; tonal_component components[64]; - float prevFrame[1024]; + float prevFrame[SAMPLES_PER_FRAME]; int gcBlkSwitch; gain_block gainBlock[2]; - DECLARE_ALIGNED(32, float, spectrum)[1024]; - DECLARE_ALIGNED(32, float, IMDCT_buf)[1024]; + DECLARE_ALIGNED(32, float, spectrum)[SAMPLES_PER_FRAME]; + DECLARE_ALIGNED(32, float, IMDCT_buf)[SAMPLES_PER_FRAME]; float delayBuf1[46]; ///mdct_ctx.imdct_calc(&q->mdct_ctx,pOutput,pInput); /* Perform windowing on the output. */ - dsp.vector_fmul(pOutput, pOutput, mdct_window, 512); + dsp.vector_fmul(pOutput, pOutput, mdct_window, MDCT_SIZE); } @@ -344,7 +346,7 @@ static int decodeSpectrum (GetBitContext *gb, float *pOut) /* Clear the subbands that were not coded. */ first = subbandTab[cnt]; - memset(pOut+first, 0, (1024 - first) * sizeof(float)); + memset(pOut+first, 0, (SAMPLES_PER_FRAME - first) * sizeof(float)); return numSubbands; } @@ -400,7 +402,7 @@ static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent for (k=0; kchannels * av_get_bytes_per_sample(avctx->sample_fmt); + out_size = SAMPLES_PER_FRAME * q->channels * + av_get_bytes_per_sample(avctx->sample_fmt); if (*data_size < out_size) { av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); return AVERROR(EINVAL); @@ -861,7 +864,7 @@ static int atrac3_decode_frame(AVCodecContext *avctx, /* interleave */ if (q->channels == 2) { q->fmt_conv.float_interleave(samples, (const float **)q->outSamples, - 1024, 2); + SAMPLES_PER_FRAME, 2); } *data_size = out_size; @@ -901,7 +904,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) av_log(avctx,AV_LOG_DEBUG,"[12-13] %d\n",bytestream_get_le16(&edata_ptr)); //Unknown always 0 /* setup */ - q->samples_per_frame = 1024 * q->channels; + q->samples_per_frame = SAMPLES_PER_FRAME * q->channels; q->atrac3version = 4; q->delay = 0x88E; if (q->codingMode) @@ -937,7 +940,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) return -1; } - if (q->samples_per_frame != 1024 && q->samples_per_frame != 2048) { + if (q->samples_per_frame != SAMPLES_PER_FRAME && q->samples_per_frame != SAMPLES_PER_FRAME*2) { av_log(avctx,AV_LOG_ERROR,"Unknown amount of samples per frame %d.\n",q->samples_per_frame); return -1; } @@ -1018,8 +1021,8 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) } if (avctx->channels > 1) { - q->outSamples[0] = av_mallocz(1024 * 2 * sizeof(*q->outSamples[0])); - q->outSamples[1] = q->outSamples[0] + 1024; + q->outSamples[0] = av_mallocz(SAMPLES_PER_FRAME * 2 * sizeof(*q->outSamples[0])); + q->outSamples[1] = q->outSamples[0] + SAMPLES_PER_FRAME; if (!q->outSamples[0]) { atrac3_decode_close(avctx); return AVERROR(ENOMEM); From 47b617021dffab86b5594f6c08aa304dee7bbbc0 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 28 Oct 2011 12:53:11 -0400 Subject: [PATCH 31/51] atrac3: make sure all memory is freed on init failure --- libavcodec/atrac3.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index 76ceac8571a87..80aa9c8b4c39f 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -196,7 +196,7 @@ static int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){ } -static av_cold void init_atrac3_transforms(ATRAC3Context *q) { +static av_cold int init_atrac3_transforms(ATRAC3Context *q) { float enc_window[256]; int i; @@ -212,7 +212,7 @@ static av_cold void init_atrac3_transforms(ATRAC3Context *q) { } /* Initialize the MDCT transform. */ - ff_mdct_init(&q->mdct_ctx, 9, 1, 1.0 / 32768); + return ff_mdct_init(&q->mdct_ctx, 9, 1, 1.0 / 32768); } /** @@ -880,7 +880,7 @@ static int atrac3_decode_frame(AVCodecContext *avctx, static av_cold int atrac3_decode_init(AVCodecContext *avctx) { - int i; + int i, ret; const uint8_t *edata_ptr = avctx->extradata; ATRAC3Context *q = avctx->priv_data; static VLC_TYPE atrac3_vlc_table[4096][2]; @@ -986,7 +986,11 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) vlcs_initialized = 1; } - init_atrac3_transforms(q); + if ((ret = init_atrac3_transforms(q))) { + av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n"); + av_freep(&q->decoded_bytes_buffer); + return ret; + } atrac_generate_tables(); @@ -1016,7 +1020,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) q->pUnits = av_mallocz(sizeof(channel_unit)*q->channels); if (!q->pUnits) { - av_free(q->decoded_bytes_buffer); + atrac3_decode_close(avctx); return AVERROR(ENOMEM); } From 8f98577d4dec38bf2618568ac012bc7094e95b09 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 28 Oct 2011 13:00:53 -0400 Subject: [PATCH 32/51] atrac3: return appropriate error codes instead of -1 --- libavcodec/atrac3.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index 80aa9c8b4c39f..b5bf061f688d0 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -376,7 +376,7 @@ static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent coding_mode_selector = get_bits(gb,2); if (coding_mode_selector == 2) - return -1; + return AVERROR_INVALIDDATA; coding_mode = coding_mode_selector & 1; @@ -388,7 +388,7 @@ static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent quant_step_index = get_bits(gb,3); if (quant_step_index <= 1) - return -1; + return AVERROR_INVALIDDATA; if (coding_mode_selector == 3) coding_mode = get_bits1(gb); @@ -451,7 +451,7 @@ static int decodeGainControl (GetBitContext *gb, gain_block *pGb, int numBands) pLevel[cf]= get_bits(gb,4); pLoc [cf]= get_bits(gb,5); if(cf && pLoc[cf] <= pLoc[cf-1]) - return -1; + return AVERROR_INVALIDDATA; } } @@ -668,12 +668,12 @@ static int decodeChannelSoundUnit (ATRAC3Context *q, GetBitContext *gb, channel_ if (codingMode == JOINT_STEREO && channelNum == 1) { if (get_bits(gb,2) != 3) { av_log(NULL,AV_LOG_ERROR,"JS mono Sound Unit id != 3.\n"); - return -1; + return AVERROR_INVALIDDATA; } } else { if (get_bits(gb,6) != 0x28) { av_log(NULL,AV_LOG_ERROR,"Sound Unit id != 0x28.\n"); - return -1; + return AVERROR_INVALIDDATA; } } @@ -760,7 +760,7 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf, ptr1 = q->decoded_bytes_buffer; for (i = 4; *ptr1 == 0xF8; i++, ptr1++) { if (i >= q->bytes_per_frame) - return -1; + return AVERROR_INVALIDDATA; } @@ -858,7 +858,7 @@ static int atrac3_decode_frame(AVCodecContext *avctx, if (result != 0) { av_log(NULL,AV_LOG_ERROR,"Frame decoding error!\n"); - return -1; + return result; } /* interleave */ @@ -917,7 +917,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) if ((q->bytes_per_frame == 96*q->channels*q->frame_factor) || (q->bytes_per_frame == 152*q->channels*q->frame_factor) || (q->bytes_per_frame == 192*q->channels*q->frame_factor)) { } else { av_log(avctx,AV_LOG_ERROR,"Unknown frame/channel/frame_factor configuration %d/%d/%d\n", q->bytes_per_frame, q->channels, q->frame_factor); - return -1; + return AVERROR_INVALIDDATA; } } else if (avctx->extradata_size == 10) { @@ -937,17 +937,17 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) if (q->atrac3version != 4) { av_log(avctx,AV_LOG_ERROR,"Version %d != 4.\n",q->atrac3version); - return -1; + return AVERROR_INVALIDDATA; } if (q->samples_per_frame != SAMPLES_PER_FRAME && q->samples_per_frame != SAMPLES_PER_FRAME*2) { av_log(avctx,AV_LOG_ERROR,"Unknown amount of samples per frame %d.\n",q->samples_per_frame); - return -1; + return AVERROR_INVALIDDATA; } if (q->delay != 0x88E) { av_log(avctx,AV_LOG_ERROR,"Unknown amount of delay %x != 0x88E.\n",q->delay); - return -1; + return AVERROR_INVALIDDATA; } if (q->codingMode == STEREO) { @@ -956,17 +956,17 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) av_log(avctx,AV_LOG_DEBUG,"Joint stereo detected.\n"); } else { av_log(avctx,AV_LOG_ERROR,"Unknown channel coding mode %x!\n",q->codingMode); - return -1; + return AVERROR_INVALIDDATA; } if (avctx->channels <= 0 || avctx->channels > 2 /*|| ((avctx->channels * 1024) != q->samples_per_frame)*/) { av_log(avctx,AV_LOG_ERROR,"Channel configuration error!\n"); - return -1; + return AVERROR(EINVAL); } if(avctx->block_align >= UINT_MAX/2) - return -1; + return AVERROR(EINVAL); /* Pad the data buffer with FF_INPUT_BUFFER_PADDING_SIZE, * this is for the bitstream reader. */ From a047851329d2c90462246a22a9c07cc3d61d66cb Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 28 Oct 2011 13:02:15 -0400 Subject: [PATCH 33/51] atrac3: add CODEC_CAP_SUBFRAMES capability the decoder can handle multiple frames in a packet --- libavcodec/atrac3.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index b5bf061f688d0..bbe562cfb3450 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -1047,5 +1047,6 @@ AVCodec ff_atrac3_decoder = .init = atrac3_decode_init, .close = atrac3_decode_close, .decode = atrac3_decode_frame, + .capabilities = CODEC_CAP_SUBFRAMES, .long_name = NULL_IF_CONFIG_SMALL("Atrac 3 (Adaptive TRansform Acoustic Coding 3)"), }; From 2073224697af3942af89fbad4d26891deb6be2a9 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 28 Oct 2011 16:36:47 -0400 Subject: [PATCH 34/51] atrac3: support float or int16 output using request_sample_fmt --- libavcodec/atrac3.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index bbe562cfb3450..3a48a5a64776f 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -196,7 +196,7 @@ static int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){ } -static av_cold int init_atrac3_transforms(ATRAC3Context *q) { +static av_cold int init_atrac3_transforms(ATRAC3Context *q, int is_float) { float enc_window[256]; int i; @@ -212,7 +212,7 @@ static av_cold int init_atrac3_transforms(ATRAC3Context *q) { } /* Initialize the MDCT transform. */ - return ff_mdct_init(&q->mdct_ctx, 9, 1, 1.0 / 32768); + return ff_mdct_init(&q->mdct_ctx, 9, 1, is_float ? 1.0 / 32768 : 1.0); } /** @@ -831,7 +831,8 @@ static int atrac3_decode_frame(AVCodecContext *avctx, ATRAC3Context *q = avctx->priv_data; int result = 0, out_size; const uint8_t* databuf; - float *samples = data; + float *samples_flt = data; + int16_t *samples_s16 = data; if (buf_size < avctx->block_align) { av_log(avctx, AV_LOG_ERROR, @@ -854,7 +855,10 @@ static int atrac3_decode_frame(AVCodecContext *avctx, databuf = buf; } - result = decodeFrame(q, databuf, q->channels == 2 ? q->outSamples : &samples); + if (q->channels == 1 && avctx->sample_fmt == AV_SAMPLE_FMT_FLT) + result = decodeFrame(q, databuf, &samples_flt); + else + result = decodeFrame(q, databuf, q->outSamples); if (result != 0) { av_log(NULL,AV_LOG_ERROR,"Frame decoding error!\n"); @@ -862,9 +866,14 @@ static int atrac3_decode_frame(AVCodecContext *avctx, } /* interleave */ - if (q->channels == 2) { - q->fmt_conv.float_interleave(samples, (const float **)q->outSamples, + if (q->channels == 2 && avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { + q->fmt_conv.float_interleave(samples_flt, + (const float **)q->outSamples, SAMPLES_PER_FRAME, 2); + } else if (avctx->sample_fmt == AV_SAMPLE_FMT_S16) { + q->fmt_conv.float_to_int16_interleave(samples_s16, + (const float **)q->outSamples, + SAMPLES_PER_FRAME, q->channels); } *data_size = out_size; @@ -986,7 +995,12 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) vlcs_initialized = 1; } - if ((ret = init_atrac3_transforms(q))) { + if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + else + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + + if ((ret = init_atrac3_transforms(q, avctx->sample_fmt == AV_SAMPLE_FMT_FLT))) { av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n"); av_freep(&q->decoded_bytes_buffer); return ret; @@ -1024,8 +1038,8 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } - if (avctx->channels > 1) { - q->outSamples[0] = av_mallocz(SAMPLES_PER_FRAME * 2 * sizeof(*q->outSamples[0])); + if (avctx->channels > 1 || avctx->sample_fmt == AV_SAMPLE_FMT_S16) { + q->outSamples[0] = av_mallocz(SAMPLES_PER_FRAME * avctx->channels * sizeof(*q->outSamples[0])); q->outSamples[1] = q->outSamples[0] + SAMPLES_PER_FRAME; if (!q->outSamples[0]) { atrac3_decode_close(avctx); @@ -1033,7 +1047,6 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) } } - avctx->sample_fmt = AV_SAMPLE_FMT_FLT; return 0; } From 101ef19ef4dc9f5c3d536aee8fcc10fff2af4d9e Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 25 Oct 2011 13:47:50 -0400 Subject: [PATCH 35/51] binkaudio: add some buffer overread checks. This stops decoding before overreads instead of after. --- libavcodec/binkaudio.c | 47 +++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index 2ed39e9e7a342..27e8ff5a84995 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -152,11 +152,18 @@ static const uint8_t rle_length_tab[16] = { 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64 }; +#define GET_BITS_SAFE(out, nbits) do { \ + if (get_bits_left(gb) < nbits) \ + return AVERROR_INVALIDDATA; \ + out = get_bits(gb, nbits); \ +} while (0) + /** * Decode Bink Audio block * @param[out] out Output buffer (must contain s->block_size elements) + * @return 0 on success, negative error code on failure */ -static void decode_block(BinkAudioContext *s, short *out, int use_dct) +static int decode_block(BinkAudioContext *s, short *out, int use_dct) { int ch, i, j, k; float q, quant[25]; @@ -169,13 +176,19 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct) for (ch = 0; ch < s->channels; ch++) { FFTSample *coeffs = s->coeffs_ptr[ch]; if (s->version_b) { + if (get_bits_left(gb) < 64) + return AVERROR_INVALIDDATA; coeffs[0] = av_int2flt(get_bits(gb, 32)) * s->root; coeffs[1] = av_int2flt(get_bits(gb, 32)) * s->root; } else { + if (get_bits_left(gb) < 58) + return AVERROR_INVALIDDATA; coeffs[0] = get_float(gb) * s->root; coeffs[1] = get_float(gb) * s->root; } + if (get_bits_left(gb) < s->num_bands * 8) + return AVERROR_INVALIDDATA; for (i = 0; i < s->num_bands; i++) { /* constant is result of 0.066399999/log10(M_E) */ int value = get_bits(gb, 8); @@ -190,15 +203,20 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct) while (i < s->frame_len) { if (s->version_b) { j = i + 16; - } else if (get_bits1(gb)) { - j = i + rle_length_tab[get_bits(gb, 4)] * 8; } else { - j = i + 8; + int v; + GET_BITS_SAFE(v, 1); + if (v) { + GET_BITS_SAFE(v, 4); + j = i + rle_length_tab[v] * 8; + } else { + j = i + 8; + } } j = FFMIN(j, s->frame_len); - width = get_bits(gb, 4); + GET_BITS_SAFE(width, 4); if (width == 0) { memset(coeffs + i, 0, (j - i) * sizeof(*coeffs)); i = j; @@ -208,9 +226,11 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct) while (i < j) { if (s->bands[k] == i) q = quant[k++]; - coeff = get_bits(gb, width); + GET_BITS_SAFE(coeff, width); if (coeff) { - if (get_bits1(gb)) + int v; + GET_BITS_SAFE(v, 1); + if (v) coeffs[i] = -q * coeff; else coeffs[i] = q * coeff; @@ -246,6 +266,8 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct) s->overlap_len * s->channels * sizeof(*out)); s->first = 0; + + return 0; } static av_cold int decode_end(AVCodecContext *avctx) @@ -277,12 +299,17 @@ static int decode_frame(AVCodecContext *avctx, int reported_size; GetBitContext *gb = &s->gb; + if (buf_size < 4) { + av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); + return AVERROR_INVALIDDATA; + } + init_get_bits(gb, buf, buf_size * 8); reported_size = get_bits_long(gb, 32); - while (get_bits_count(gb) / 8 < buf_size && - samples + s->block_size <= samples_end) { - decode_block(s, samples, avctx->codec->id == CODEC_ID_BINKAUDIO_DCT); + while (samples + s->block_size <= samples_end) { + if (decode_block(s, samples, avctx->codec->id == CODEC_ID_BINKAUDIO_DCT)) + break; samples += s->block_size; get_bits_align32(gb); } From 9f48039a37b5e0064fe66c74bc3533043b3c0815 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 25 Oct 2011 15:13:19 -0400 Subject: [PATCH 36/51] binkaudio: pre-calculate quantization factors --- libavcodec/binkaudio.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index 27e8ff5a84995..ae1997d961059 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -39,6 +39,8 @@ extern const uint16_t ff_wma_critical_freqs[25]; +static float quant_table[95]; + #define MAX_CHANNELS 2 #define BINK_BLOCK_MAX_SIZE (MAX_CHANNELS << 11) @@ -107,6 +109,10 @@ static av_cold int decode_init(AVCodecContext *avctx) s->block_size = (s->frame_len - s->overlap_len) * s->channels; sample_rate_half = (sample_rate + 1) / 2; s->root = 2.0 / sqrt(s->frame_len); + for (i = 0; i < 95; i++) { + /* constant is result of 0.066399999/log10(M_E) */ + quant_table[i] = expf(i * 0.15289164787221953823f) * s->root; + } /* calculate number of bands */ for (s->num_bands = 1; s->num_bands < 25; s->num_bands++) @@ -190,9 +196,8 @@ static int decode_block(BinkAudioContext *s, short *out, int use_dct) if (get_bits_left(gb) < s->num_bands * 8) return AVERROR_INVALIDDATA; for (i = 0; i < s->num_bands; i++) { - /* constant is result of 0.066399999/log10(M_E) */ int value = get_bits(gb, 8); - quant[i] = expf(FFMIN(value, 95) * 0.15289164787221953823f) * s->root; + quant[i] = quant_table[FFMIN(value, 95)]; } k = 0; From eaddd29e00850110e64982451e606efff8422eb4 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 26 Oct 2011 10:18:39 -0400 Subject: [PATCH 37/51] binkaudio: store interleaved overlap samples in BinkAudioContext. This fixes the requirement for the buffer size to be larger than the number of samples actually decoded. --- libavcodec/binkaudio.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index ae1997d961059..815fbb7f774cd 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -59,7 +59,9 @@ typedef struct { float root; DECLARE_ALIGNED(32, FFTSample, coeffs)[BINK_BLOCK_MAX_SIZE]; DECLARE_ALIGNED(16, short, previous)[BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block + DECLARE_ALIGNED(16, int16_t, current)[BINK_BLOCK_MAX_SIZE / 16]; float *coeffs_ptr[MAX_CHANNELS]; ///< pointers to the coeffs arrays for float_to_int16_interleave + float *prev_ptr[MAX_CHANNELS]; ///< pointers to the overlap points in the coeffs array union { RDFTContext rdft; DCTContext dct; @@ -132,8 +134,10 @@ static av_cold int decode_init(AVCodecContext *avctx) s->first = 1; avctx->sample_fmt = AV_SAMPLE_FMT_S16; - for (i = 0; i < s->channels; i++) + for (i = 0; i < s->channels; i++) { s->coeffs_ptr[i] = s->coeffs + i * s->frame_len; + s->prev_ptr[i] = s->coeffs_ptr[i] + s->frame_len - s->overlap_len; + } if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT) ff_rdft_init(&s->trans.rdft, frame_len_bits, DFT_C2R); @@ -256,8 +260,12 @@ static int decode_block(BinkAudioContext *s, short *out, int use_dct) s->trans.rdft.rdft_calc(&s->trans.rdft, coeffs); } + s->fmt_conv.float_to_int16_interleave(s->current, + (const float **)s->prev_ptr, + s->overlap_len, s->channels); s->fmt_conv.float_to_int16_interleave(out, (const float **)s->coeffs_ptr, - s->frame_len, s->channels); + s->frame_len - s->overlap_len, + s->channels); if (!s->first) { int count = s->overlap_len * s->channels; @@ -267,8 +275,8 @@ static int decode_block(BinkAudioContext *s, short *out, int use_dct) } } - memcpy(s->previous, out + s->block_size, - s->overlap_len * s->channels * sizeof(*out)); + memcpy(s->previous, s->current, + s->overlap_len * s->channels * sizeof(*s->previous)); s->first = 0; From 4f4e19480a1b254d1d049cffffb11f13ae54b53a Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 26 Oct 2011 11:02:12 -0400 Subject: [PATCH 38/51] binkaudio: only decode one block at a time. This prevents truncating output due to an output buffer that is too small for all blocks. There is no limit on the number of blocks in a packet. --- libavcodec/binkaudio.c | 55 +++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index 815fbb7f774cd..742682f1c569f 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -62,6 +62,7 @@ typedef struct { DECLARE_ALIGNED(16, int16_t, current)[BINK_BLOCK_MAX_SIZE / 16]; float *coeffs_ptr[MAX_CHANNELS]; ///< pointers to the coeffs arrays for float_to_int16_interleave float *prev_ptr[MAX_CHANNELS]; ///< pointers to the overlap points in the coeffs array + uint8_t *packet_buffer; union { RDFTContext rdft; DCTContext dct; @@ -287,6 +288,7 @@ static av_cold int decode_end(AVCodecContext *avctx) { BinkAudioContext * s = avctx->priv_data; av_freep(&s->bands); + av_freep(&s->packet_buffer); if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT) ff_rdft_end(&s->trans.rdft); else if (CONFIG_BINKAUDIO_DCT_DECODER) @@ -305,30 +307,47 @@ static int decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { BinkAudioContext *s = avctx->priv_data; - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; short *samples = data; - short *samples_end = (short*)((uint8_t*)data + *data_size); - int reported_size; GetBitContext *gb = &s->gb; - - if (buf_size < 4) { - av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); - return AVERROR_INVALIDDATA; + int out_size, consumed = 0; + + if (!get_bits_left(gb)) { + uint8_t *buf; + /* handle end-of-stream */ + if (!avpkt->size) { + *data_size = 0; + return 0; + } + if (avpkt->size < 4) { + av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); + return AVERROR_INVALIDDATA; + } + buf = av_realloc(s->packet_buffer, avpkt->size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!buf) + return AVERROR(ENOMEM); + s->packet_buffer = buf; + memcpy(s->packet_buffer, avpkt->data, avpkt->size); + init_get_bits(gb, s->packet_buffer, avpkt->size * 8); + consumed = avpkt->size; + + /* skip reported size */ + skip_bits_long(gb, 32); } - init_get_bits(gb, buf, buf_size * 8); + out_size = s->block_size * av_get_bytes_per_sample(avctx->sample_fmt); + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); + } - reported_size = get_bits_long(gb, 32); - while (samples + s->block_size <= samples_end) { - if (decode_block(s, samples, avctx->codec->id == CODEC_ID_BINKAUDIO_DCT)) - break; - samples += s->block_size; - get_bits_align32(gb); + if (decode_block(s, samples, avctx->codec->id == CODEC_ID_BINKAUDIO_DCT)) { + av_log(avctx, AV_LOG_ERROR, "Incomplete packet\n"); + return AVERROR_INVALIDDATA; } + get_bits_align32(gb); - *data_size = FFMIN(reported_size, (uint8_t*)samples - (uint8_t*)data); - return buf_size; + *data_size = out_size; + return consumed; } AVCodec ff_binkaudio_rdft_decoder = { @@ -339,6 +358,7 @@ AVCodec ff_binkaudio_rdft_decoder = { .init = decode_init, .close = decode_end, .decode = decode_frame, + .capabilities = CODEC_CAP_DELAY, .long_name = NULL_IF_CONFIG_SMALL("Bink Audio (RDFT)") }; @@ -350,5 +370,6 @@ AVCodec ff_binkaudio_dct_decoder = { .init = decode_init, .close = decode_end, .decode = decode_frame, + .capabilities = CODEC_CAP_DELAY, .long_name = NULL_IF_CONFIG_SMALL("Bink Audio (DCT)") }; From 425a84350507e18c57ba0bee32366eb5963a9da5 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 26 Oct 2011 11:08:49 -0400 Subject: [PATCH 39/51] binkaudio: change short to int16_t --- libavcodec/binkaudio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index 742682f1c569f..a90467abfb580 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -58,7 +58,7 @@ typedef struct { unsigned int *bands; float root; DECLARE_ALIGNED(32, FFTSample, coeffs)[BINK_BLOCK_MAX_SIZE]; - DECLARE_ALIGNED(16, short, previous)[BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block + DECLARE_ALIGNED(16, int16_t, previous)[BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block DECLARE_ALIGNED(16, int16_t, current)[BINK_BLOCK_MAX_SIZE / 16]; float *coeffs_ptr[MAX_CHANNELS]; ///< pointers to the coeffs arrays for float_to_int16_interleave float *prev_ptr[MAX_CHANNELS]; ///< pointers to the overlap points in the coeffs array @@ -174,7 +174,7 @@ static const uint8_t rle_length_tab[16] = { * @param[out] out Output buffer (must contain s->block_size elements) * @return 0 on success, negative error code on failure */ -static int decode_block(BinkAudioContext *s, short *out, int use_dct) +static int decode_block(BinkAudioContext *s, int16_t *out, int use_dct) { int ch, i, j, k; float q, quant[25]; @@ -307,7 +307,7 @@ static int decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { BinkAudioContext *s = avctx->priv_data; - short *samples = data; + int16_t *samples = data; GetBitContext *gb = &s->gb; int out_size, consumed = 0; From 46e1af3b0f2c28936dfa88063cc5a35f466f5ac3 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sat, 29 Oct 2011 19:35:20 +0200 Subject: [PATCH 40/51] utvideo: handle empty Huffman trees If the frame is filled with the same colour, encoder may produce no data and the fill value is indicated by zero code length (the rest of symbols will have 0xFF for code length, meaning invalid). So such Huffman trees should be treated specially. Signed-off-by: Luca Barbato --- libavcodec/utvideo.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/libavcodec/utvideo.c b/libavcodec/utvideo.c index 5faaa15a0c40b..4c3b2a1621a2f 100644 --- a/libavcodec/utvideo.c +++ b/libavcodec/utvideo.c @@ -66,7 +66,7 @@ static int huff_cmp(const void *a, const void *b) return (aa->len - bb->len)*256 + aa->sym - bb->sym; } -static int build_huff(const uint8_t *src, VLC *vlc) +static int build_huff(const uint8_t *src, VLC *vlc, int *fsym) { int i; HuffEntry he[256]; @@ -76,13 +76,18 @@ static int build_huff(const uint8_t *src, VLC *vlc) uint8_t syms[256]; uint32_t code; + *fsym = -1; for (i = 0; i < 256; i++) { he[i].sym = i; he[i].len = *src++; } qsort(he, 256, sizeof(*he), huff_cmp); - if (!he[0].len || he[0].len > 32) + if (!he[0].len) { + *fsym = he[0].sym; + return 0; + } + if (he[0].len > 32) return -1; last = 255; @@ -112,13 +117,37 @@ static int decode_plane(UtvideoContext *c, int plane_no, int sstart, send; VLC vlc; GetBitContext gb; - int prev; + int prev, fsym; const int cmask = ~(!plane_no && c->avctx->pix_fmt == PIX_FMT_YUV420P); - if (build_huff(src, &vlc)) { + if (build_huff(src, &vlc, &fsym)) { av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n"); return AVERROR_INVALIDDATA; } + if (fsym >= 0) { // build_huff reported a symbol to fill slices with + send = 0; + for (slice = 0; slice < c->slices; slice++) { + uint8_t *dest; + + sstart = send; + send = (height * (slice + 1) / c->slices) & cmask; + dest = dst + sstart * stride; + + prev = 0x80; + for (j = sstart; j < send; j++) { + for (i = 0; i < width * step; i += step) { + pix = fsym; + if (use_pred) { + prev += pix; + pix = prev; + } + dest[i] = pix; + } + dest += stride; + } + } + return 0; + } src += 256; src_size -= 256; From f44059d26094c20277a6ec9f966c3bd453b6b9cf Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 27 Oct 2011 11:41:02 -0400 Subject: [PATCH 41/51] dca: return proper error codes instead of -1 --- libavcodec/dca.c | 49 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/libavcodec/dca.c b/libavcodec/dca.c index 3233f60d4a921..518fd30dbccd5 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -529,15 +529,15 @@ static int dca_parse_frame_header(DCAContext * s) s->sample_blocks = get_bits(&s->gb, 7) + 1; s->frame_size = get_bits(&s->gb, 14) + 1; if (s->frame_size < 95) - return -1; + return AVERROR_INVALIDDATA; s->amode = get_bits(&s->gb, 6); s->sample_rate = dca_sample_rates[get_bits(&s->gb, 4)]; if (!s->sample_rate) - return -1; + return AVERROR_INVALIDDATA; s->bit_rate_index = get_bits(&s->gb, 5); s->bit_rate = dca_bit_rates[s->bit_rate_index]; if (!s->bit_rate) - return -1; + return AVERROR_INVALIDDATA; s->downmix = get_bits(&s->gb, 1); s->dynrange = get_bits(&s->gb, 1); @@ -627,7 +627,7 @@ static int dca_subframe_header(DCAContext * s, int base_channel, int block_index int j, k; if (get_bits_left(&s->gb) < 0) - return -1; + return AVERROR_INVALIDDATA; if (!base_channel) { s->subsubframes[s->current_subframe] = get_bits(&s->gb, 2) + 1; @@ -659,7 +659,7 @@ static int dca_subframe_header(DCAContext * s, int base_channel, int block_index else if (s->bitalloc_huffman[j] == 7) { av_log(s->avctx, AV_LOG_ERROR, "Invalid bit allocation index\n"); - return -1; + return AVERROR_INVALIDDATA; } else { s->bitalloc[j][k] = get_bitalloc(&s->gb, &dca_bitalloc_index, s->bitalloc_huffman[j]); @@ -668,7 +668,7 @@ static int dca_subframe_header(DCAContext * s, int base_channel, int block_index if (s->bitalloc[j][k] > 26) { // av_log(s->avctx,AV_LOG_DEBUG,"bitalloc index [%i][%i] too big (%i)\n", // j, k, s->bitalloc[j][k]); - return -1; + return AVERROR_INVALIDDATA; } } } @@ -686,7 +686,7 @@ static int dca_subframe_header(DCAContext * s, int base_channel, int block_index } if (get_bits_left(&s->gb) < 0) - return -1; + return AVERROR_INVALIDDATA; for (j = base_channel; j < s->prim_channels; j++) { const uint32_t *scale_table; @@ -724,7 +724,7 @@ static int dca_subframe_header(DCAContext * s, int base_channel, int block_index } if (get_bits_left(&s->gb) < 0) - return -1; + return AVERROR_INVALIDDATA; /* Scale factors for joint subband coding */ for (j = base_channel; j < s->prim_channels; j++) { @@ -1055,7 +1055,7 @@ static int decode_blockcode(int code, int levels, int *values) return 0; else { av_log(NULL, AV_LOG_ERROR, "ERROR: block code look-up failed\n"); - return -1; + return AVERROR_INVALIDDATA; } } @@ -1095,7 +1095,7 @@ static int dca_subsubframe(DCAContext * s, int base_channel, int block_index) for (k = base_channel; k < s->prim_channels; k++) { if (get_bits_left(&s->gb) < 0) - return -1; + return AVERROR_INVALIDDATA; for (l = 0; l < s->vq_start_subband[k]; l++) { int m; @@ -1274,12 +1274,13 @@ static int dca_subframe_footer(DCAContext * s, int base_channel) static int dca_decode_block(DCAContext * s, int base_channel, int block_index) { + int ret; /* Sanity check */ if (s->current_subframe >= s->subframes) { av_log(s->avctx, AV_LOG_DEBUG, "check failed: %i>%i", s->current_subframe, s->subframes); - return -1; + return AVERROR_INVALIDDATA; } if (!s->current_subsubframe) { @@ -1287,16 +1288,16 @@ static int dca_decode_block(DCAContext * s, int base_channel, int block_index) av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subframe_header\n"); #endif /* Read subframe header */ - if (dca_subframe_header(s, base_channel, block_index)) - return -1; + if ((ret = dca_subframe_header(s, base_channel, block_index))) + return ret; } /* Read subsubframe */ #ifdef TRACE av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subsubframe\n"); #endif - if (dca_subsubframe(s, base_channel, block_index)) - return -1; + if ((ret = dca_subsubframe(s, base_channel, block_index))) + return ret; /* Update state */ s->current_subsubframe++; @@ -1309,8 +1310,8 @@ static int dca_decode_block(DCAContext * s, int base_channel, int block_index) av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subframe_footer\n"); #endif /* Read subframe footer */ - if (dca_subframe_footer(s, base_channel)) - return -1; + if ((ret = dca_subframe_footer(s, base_channel))) + return ret; } return 0; @@ -1353,7 +1354,7 @@ static int dca_convert_bitstream(const uint8_t * src, int src_size, uint8_t * ds flush_put_bits(&pb); return (put_bits_count(&pb) + 7) >> 3; default: - return -1; + return AVERROR_INVALIDDATA; } } @@ -1649,9 +1650,9 @@ static int dca_decode_frame(AVCodecContext * avctx, s->dca_buffer_size = dca_convert_bitstream(buf, buf_size, s->dca_buffer, DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE); - if (s->dca_buffer_size == -1) { + if (s->dca_buffer_size == AVERROR_INVALIDDATA) { av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n"); - return -1; + return AVERROR_INVALIDDATA; } init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8); @@ -1798,7 +1799,7 @@ static int dca_decode_frame(AVCodecContext * avctx, if (channels > !!s->lfe && s->channel_order_tab[channels - 1 - !!s->lfe] < 0) - return -1; + return AVERROR_INVALIDDATA; if (avctx->request_channels == 2 && s->prim_channels > 2) { channels = 2; @@ -1807,7 +1808,7 @@ static int dca_decode_frame(AVCodecContext * avctx, } } else { av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n",s->amode); - return -1; + return AVERROR_INVALIDDATA; } @@ -1823,13 +1824,13 @@ static int dca_decode_frame(AVCodecContext * avctx, if (avctx->channels != channels) { av_log(avctx, AV_LOG_ERROR, "DCA decoder does not support number of " "channels changing in stream. Skipping frame.\n"); - return -1; + return AVERROR_PATCHWELCOME; } out_size = 256 / 8 * s->sample_blocks * channels * av_get_bytes_per_sample(avctx->sample_fmt); if (*data_size < out_size) - return -1; + return AVERROR(EINVAL); *data_size = out_size; /* filter to get final output */ From aae6eead6a6e9bbab1c808d7552da5631ac78576 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 27 Oct 2011 11:42:23 -0400 Subject: [PATCH 42/51] dca: return error if the frame header is invalid --- libavcodec/dca.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libavcodec/dca.c b/libavcodec/dca.c index 518fd30dbccd5..deb7245256d44 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -1637,7 +1637,7 @@ static int dca_decode_frame(AVCodecContext * avctx, int lfe_samples; int num_core_channels = 0; - int i; + int i, ret; float *samples_flt = data; int16_t *samples_s16 = data; int out_size; @@ -1656,10 +1656,9 @@ static int dca_decode_frame(AVCodecContext * avctx, } init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8); - if (dca_parse_frame_header(s) < 0) { + if ((ret = dca_parse_frame_header(s)) < 0) { //seems like the frame is corrupt, try with the next one - *data_size=0; - return buf_size; + return ret; } //set AVCodec values with parsed data avctx->sample_rate = s->sample_rate; From 272fcc32bb0d3b552390d15213201756fdf27d74 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 27 Oct 2011 11:45:50 -0400 Subject: [PATCH 43/51] dca: handle errors from dca_decode_block() Return error if core block decoding fails. Do not enable XCh if XCh extension block decoding fails. --- libavcodec/dca.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libavcodec/dca.c b/libavcodec/dca.c index deb7245256d44..7f7bcf9cfd077 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -1668,7 +1668,10 @@ static int dca_decode_frame(AVCodecContext * avctx, s->profile = FF_PROFILE_DTS; for (i = 0; i < (s->sample_blocks / 8); i++) { - dca_decode_block(s, 0, i); + if ((ret = dca_decode_block(s, 0, i))) { + av_log(avctx, AV_LOG_ERROR, "error decoding block\n"); + return ret; + } } /* record number of core channels incase less than max channels are requested */ @@ -1724,7 +1727,10 @@ static int dca_decode_frame(AVCodecContext * avctx, dca_parse_audio_coding_header(s, s->xch_base_channel); for (i = 0; i < (s->sample_blocks / 8); i++) { - dca_decode_block(s, s->xch_base_channel, i); + if ((ret = dca_decode_block(s, s->xch_base_channel, i))) { + av_log(avctx, AV_LOG_ERROR, "error decoding XCh extension\n"); + continue; + } } s->xch_present = 1; From 5bd0343bee1ed3df9cae1093bd909d07d07fa145 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 27 Oct 2011 14:29:28 -0400 Subject: [PATCH 44/51] flacdec: use av_get_bytes_per_sample() to get sample size --- libavcodec/flacdec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index 633a1386ae32e..95cf2bccb45ee 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -587,7 +587,8 @@ static int flac_decode_frame(AVCodecContext *avctx, bytes_read = (get_bits_count(&s->gb)+7)/8; /* check if allocated data size is large enough for output */ - output_size = s->blocksize * s->channels * (s->is32 ? 4 : 2); + output_size = s->blocksize * s->channels * + av_get_bytes_per_sample(avctx->sample_fmt); if (output_size > alloc_data_size) { av_log(s->avctx, AV_LOG_ERROR, "output data size is larger than " "allocated data size\n"); From 44d2a982acd858ebb518710b4c7738bf7258558b Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 27 Oct 2011 12:46:32 -0400 Subject: [PATCH 45/51] dsicin: fix several audio-related fields in the CIN demuxer bits_per_coded_sample should be 8. block_align is calculated incorrectly, but it is not needed anyway. packet pts should be calculated in samples. packet duration can be set. --- libavformat/dsicin.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavformat/dsicin.c b/libavformat/dsicin.c index 3c7589b55678d..5f02f79501a54 100644 --- a/libavformat/dsicin.c +++ b/libavformat/dsicin.c @@ -131,9 +131,8 @@ static int cin_read_header(AVFormatContext *s, AVFormatParameters *ap) st->codec->codec_tag = 0; /* no tag */ st->codec->channels = 1; st->codec->sample_rate = 22050; - st->codec->bits_per_coded_sample = 16; + st->codec->bits_per_coded_sample = 8; st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample * st->codec->channels; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; return 0; } @@ -211,7 +210,8 @@ static int cin_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->stream_index = cin->audio_stream_index; pkt->pts = cin->audio_stream_pts; - cin->audio_stream_pts += cin->audio_buffer_size * 2 / cin->file_header.audio_frame_size; + pkt->duration = cin->audio_buffer_size - (pkt->pts == 0); + cin->audio_stream_pts += pkt->duration; cin->audio_buffer_size = 0; return 0; } From 664eb77dc3cb63dcb82d27d62540058a78bdab48 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 27 Oct 2011 13:28:33 -0400 Subject: [PATCH 46/51] cin audio: remove unneeded AVCodecContext pointer from CinAudioContext --- libavcodec/dsicinav.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index 3b545e7b8fe80..953d232d9bf31 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -43,7 +43,6 @@ typedef struct CinVideoContext { } CinVideoContext; typedef struct CinAudioContext { - AVCodecContext *avctx; int initial_decode_frame; int delta; } CinAudioContext; @@ -308,7 +307,6 @@ static av_cold int cinaudio_decode_init(AVCodecContext *avctx) { CinAudioContext *cin = avctx->priv_data; - cin->avctx = avctx; cin->initial_decode_frame = 1; cin->delta = 0; avctx->sample_fmt = AV_SAMPLE_FMT_S16; From 03381c12b3a45200918dea877e970c5705f7cf5a Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 27 Oct 2011 13:33:57 -0400 Subject: [PATCH 47/51] cin audio: validate the channel count --- libavcodec/dsicinav.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index 953d232d9bf31..832efab0561f5 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -307,6 +307,11 @@ static av_cold int cinaudio_decode_init(AVCodecContext *avctx) { CinAudioContext *cin = avctx->priv_data; + if (avctx->channels != 1) { + av_log_ask_for_sample(avctx, "Number of channels is not supported\n"); + return AVERROR_PATCHWELCOME; + } + cin->initial_decode_frame = 1; cin->delta = 0; avctx->sample_fmt = AV_SAMPLE_FMT_S16; From 64e19ba48b6240828680a0a1cc506bdba7d98ad7 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 27 Oct 2011 13:35:25 -0400 Subject: [PATCH 48/51] cin audio: remove unneeded cast from void* --- libavcodec/dsicinav.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index 832efab0561f5..cafcaa7719418 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -327,7 +327,7 @@ static int cinaudio_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; CinAudioContext *cin = avctx->priv_data; const uint8_t *src = buf; - int16_t *samples = (int16_t *)data; + int16_t *samples = data; buf_size = FFMIN(buf_size, *data_size/2); From 859bdc33e4c7b0bbb7a549df484b99e341dec074 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 27 Oct 2011 13:41:02 -0400 Subject: [PATCH 49/51] cin audio: use local variable for delta value --- libavcodec/dsicinav.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index cafcaa7719418..245b569433690 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -328,21 +328,24 @@ static int cinaudio_decode_frame(AVCodecContext *avctx, CinAudioContext *cin = avctx->priv_data; const uint8_t *src = buf; int16_t *samples = data; + int delta; buf_size = FFMIN(buf_size, *data_size/2); + delta = cin->delta; if (cin->initial_decode_frame) { cin->initial_decode_frame = 0; - cin->delta = (int16_t)AV_RL16(src); src += 2; - *samples++ = cin->delta; + delta = (int16_t)AV_RL16(src); src += 2; + *samples++ = delta; buf_size -= 2; } while (buf_size > 0) { - cin->delta += cinaudio_delta16_table[*src++]; - cin->delta = av_clip_int16(cin->delta); - *samples++ = cin->delta; + delta += cinaudio_delta16_table[*src++]; + delta = av_clip_int16(delta); + *samples++ = delta; --buf_size; } + cin->delta = delta; *data_size = (uint8_t *)samples - (uint8_t *)data; From 405af431040a57c630716b3940d7240021e8b80c Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 27 Oct 2011 13:50:02 -0400 Subject: [PATCH 50/51] cin audio: restructure decoding loop to avoid a separate counter variable Also check output buffer size instead of truncating output. --- libavcodec/dsicinav.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index 245b569433690..a6a4ff1c6e1dd 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -324,32 +324,35 @@ static int cinaudio_decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; CinAudioContext *cin = avctx->priv_data; - const uint8_t *src = buf; + const uint8_t *buf_end = buf + avpkt->size; int16_t *samples = data; - int delta; + int delta, out_size; - buf_size = FFMIN(buf_size, *data_size/2); + out_size = (avpkt->size - cin->initial_decode_frame) * + av_get_bytes_per_sample(avctx->sample_fmt); + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); + return AVERROR(EINVAL); + } delta = cin->delta; if (cin->initial_decode_frame) { cin->initial_decode_frame = 0; - delta = (int16_t)AV_RL16(src); src += 2; + delta = (int16_t)AV_RL16(buf); + buf += 2; *samples++ = delta; - buf_size -= 2; } - while (buf_size > 0) { - delta += cinaudio_delta16_table[*src++]; + while (buf < buf_end) { + delta += cinaudio_delta16_table[*buf++]; delta = av_clip_int16(delta); *samples++ = delta; - --buf_size; } cin->delta = delta; - *data_size = (uint8_t *)samples - (uint8_t *)data; + *data_size = out_size; - return src - buf; + return avpkt->size; } From 7d1b17b83330aefe2f32a66fe84effe46ae51014 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 27 Oct 2011 13:58:05 -0400 Subject: [PATCH 51/51] cin audio: use sign_extend() instead of casting to int16_t --- libavcodec/dsicinav.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index a6a4ff1c6e1dd..cbf7c4a6f821c 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -26,6 +26,7 @@ #include "avcodec.h" #include "bytestream.h" +#include "mathops.h" typedef enum CinVideoBitmapIndex { @@ -339,7 +340,7 @@ static int cinaudio_decode_frame(AVCodecContext *avctx, delta = cin->delta; if (cin->initial_decode_frame) { cin->initial_decode_frame = 0; - delta = (int16_t)AV_RL16(buf); + delta = sign_extend(AV_RL16(buf), 16); buf += 2; *samples++ = delta; }