From 89baf35996a0feb8cf81535f74cef2946a92d477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 17 Feb 2012 23:10:21 +0200 Subject: dct-test: Remove a stray declaration of a nonexistent function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/dct-test.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/dct-test.c b/libavcodec/dct-test.c index 133fdbf..2c59cd9 100644 --- a/libavcodec/dct-test.c +++ b/libavcodec/dct-test.c @@ -48,8 +48,6 @@ void ff_mmx_idct(DCTELEM *data); void ff_mmxext_idct(DCTELEM *data); -void odivx_idct_c(short *block); - // BFIN void ff_bfin_idct(DCTELEM *block); void ff_bfin_fdct(DCTELEM *block); -- cgit v1.1 From 07333750592e983f8c382491c48f7b402213cca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 17 Feb 2012 23:12:25 +0200 Subject: dct-test: Add the missing ff_ prefix to the altivec functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/dct-test.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/dct-test.c b/libavcodec/dct-test.c index 2c59cd9..1787ef6 100644 --- a/libavcodec/dct-test.c +++ b/libavcodec/dct-test.c @@ -53,8 +53,8 @@ void ff_bfin_idct(DCTELEM *block); void ff_bfin_fdct(DCTELEM *block); // ALTIVEC -void fdct_altivec(DCTELEM *block); -//void idct_altivec(DCTELEM *block);?? no routine +void ff_fdct_altivec(DCTELEM *block); +//void ff_idct_altivec(DCTELEM *block);?? no routine // ARM void ff_j_rev_dct_arm(DCTELEM *data); @@ -95,7 +95,7 @@ static const struct algo fdct_tab[] = { #endif #if HAVE_ALTIVEC - { "altivecfdct", fdct_altivec, NO_PERM, AV_CPU_FLAG_ALTIVEC }, + { "altivecfdct", ff_fdct_altivec, NO_PERM, AV_CPU_FLAG_ALTIVEC }, #endif #if ARCH_BFIN -- cgit v1.1 From 84c202cc37024bd78261e4222e46631ea73c48dd Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 17 Feb 2012 15:00:47 -0800 Subject: huffyuv: error out on bit overrun. On EOF, get_bits() will continuously return 0, causing an infinite loop. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/huffyuv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libavcodec') diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c index ebbfc45..0c5f6be 100644 --- a/libavcodec/huffyuv.c +++ b/libavcodec/huffyuv.c @@ -184,7 +184,7 @@ static int read_len_table(uint8_t *dst, GetBitContext *gb){ if(repeat==0) repeat= get_bits(gb, 8); //printf("%d %d\n", val, repeat); - if(i+repeat > 256) { + if(i+repeat > 256 || get_bits_left(gb) < 0) { av_log(NULL, AV_LOG_ERROR, "Error reading huffman table\n"); return -1; } -- cgit v1.1 From c0994e39d7fd63b4f4adfe4714fa6e41bff82a7c Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 17 Feb 2012 14:51:29 -0800 Subject: mpc7: assign an error level + context to av_log() msg. --- libavcodec/mpc7.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libavcodec') diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c index 0739bf2..2e8271a 100644 --- a/libavcodec/mpc7.c +++ b/libavcodec/mpc7.c @@ -298,7 +298,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data, bits_used = get_bits_count(&gb); bits_avail = buf_size * 8; if (!last_frame && ((bits_avail < bits_used) || (bits_used + 32 <= bits_avail))) { - av_log(NULL,0, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail); + av_log(avctx, AV_LOG_ERROR, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail); return -1; } if(c->frames_to_skip){ -- cgit v1.1 From 3e13005cac6e076053276b515f5fcf59a3f4b65d Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 17 Feb 2012 15:20:27 -0800 Subject: mp3on4: require a minimum framesize. If bufsize < headersize, init_get_bits() will be called with a negative number, causing it to fail and any subsequent call to get_bits() will crash because it reads from a NULL pointer. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/mpegaudiodec.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libavcodec') diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index af125d5..6c08862 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -1917,6 +1917,10 @@ static int decode_frame_mp3on4(AVCodecContext *avctx, void *data, m = s->mp3decctx[fr]; assert(m != NULL); + if (fsize < HEADER_SIZE) { + av_log(avctx, AV_LOG_ERROR, "Frame size smaller than header size\n"); + return AVERROR_INVALIDDATA; + } header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header if (ff_mpa_check_header(header) < 0) // Bad header, discard block -- cgit v1.1 From ce7aee9b733134649a6ce2fa743e51733f33e67e Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Fri, 17 Feb 2012 14:13:40 -0800 Subject: dpcm: ignore extra unpaired bytes in stereo streams. Fixes: CVE-2011-3951 Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind --- libavcodec/dpcm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'libavcodec') diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 1b0f6b0..7f5dbfe 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -183,6 +183,11 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int stereo = s->channels - 1; int16_t *output_samples; + if (stereo && (buf_size & 1)) { + buf_size--; + buf_end--; + } + /* calculate output size */ switch(avctx->codec->id) { case CODEC_ID_ROQ_DPCM: @@ -317,7 +322,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, *got_frame_ptr = 1; *(AVFrame *)data = s->frame; - return buf_size; + return avpkt->size; } #define DPCM_DECODER(id_, name_, long_name_) \ -- cgit v1.1 From b1af4e9c27e2cd4a7deab26b88feae8490d673ba Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 16 Feb 2012 21:42:55 -0800 Subject: vp8dsp: split long line. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavcodec/vp8dsp.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'libavcodec') diff --git a/libavcodec/vp8dsp.h b/libavcodec/vp8dsp.h index 5429e98..81e19f4 100644 --- a/libavcodec/vp8dsp.h +++ b/libavcodec/vp8dsp.h @@ -29,7 +29,9 @@ #include "dsputil.h" -typedef void (*vp8_mc_func)(uint8_t *dst/*align 8*/, int dstStride, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y); +typedef void (*vp8_mc_func)(uint8_t *dst/*align 8*/, int dstStride, + uint8_t *src/*align 1*/, int srcStride, + int h, int x, int y); typedef struct VP8DSPContext { void (*vp8_luma_dc_wht)(DCTELEM block[4][4][16], DCTELEM dc[16]); -- cgit v1.1 From 74699ac8c8b562e9f8d26e21482b89585365774a Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 17 Feb 2012 16:27:36 -0800 Subject: mjpegb: don't return 0 at the end of frame decoding. Return 0 indicates "please return the same data again", i.e. it causes an infinite loop. Instead, return that we consumed the buffer if we finished decoding succesfully, or return an error if an error occurred. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/mjpegbdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c index c89a5bd..10c5add 100644 --- a/libavcodec/mjpegbdec.c +++ b/libavcodec/mjpegbdec.c @@ -69,7 +69,7 @@ read_header: if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g')) { av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n"); - return 0; + return AVERROR_INVALIDDATA; } field_size = get_bits_long(&hgb, 32); /* field size */ @@ -149,7 +149,7 @@ read_header: picture->quality*= FF_QP2LAMBDA; } - return buf_ptr - buf; + return buf_size; } AVCodec ff_mjpegb_decoder = { -- cgit v1.1 From 9d3050d3e95e307ebc34a943484c7add838d1220 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 17 Feb 2012 16:57:00 -0800 Subject: wma: don't return 0 on invalid packets. Return 0 means "please return the same data again", i.e. it causes an infinite loop. Instead, return an error. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/wmadec.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index 41b2a8e..b9fc21f 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -817,8 +817,12 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, s->last_superframe_len = 0; return 0; } - if (buf_size < s->block_align) - return 0; + if (buf_size < s->block_align) { + av_log(avctx, AV_LOG_ERROR, + "Input packet size too small (%d < %d)\n", + buf_size, s->block_align); + return AVERROR_INVALIDDATA; + } buf_size = s->block_align; init_get_bits(&s->gb, buf, buf_size*8); -- cgit v1.1 From c742ab4e81bb9dcabfdab006d6b8b09a5808c4ce Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 17 Feb 2012 14:18:22 -0800 Subject: vc1parse: call vc1_init_common(). The parser uses VLC tables initialized in vc1_common_init(), therefore we should call this function on parser init also. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/vc1.h | 1 + libavcodec/vc1_parser.c | 2 +- libavcodec/vc1dec.c | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index f895aad..d07ad89 100644 --- a/libavcodec/vc1.h +++ b/libavcodec/vc1.h @@ -447,5 +447,6 @@ int ff_vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContex int ff_vc1_parse_frame_header (VC1Context *v, GetBitContext *gb); int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext *gb); +int ff_vc1_init_common(VC1Context *v); #endif /* AVCODEC_VC1_H */ diff --git a/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c index dfbb1f5..bf29032 100644 --- a/libavcodec/vc1_parser.c +++ b/libavcodec/vc1_parser.c @@ -188,7 +188,7 @@ static int vc1_parse_init(AVCodecParserContext *s) { VC1ParseContext *vpc = s->priv_data; vpc->v.s.slice_context_count = 1; - return 0; + return ff_vc1_init_common(&vpc->v); } AVCodecParser ff_vc1_parser = { diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index e48aabc..8ab92b4 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -67,7 +67,7 @@ static const int offset_table2[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 }; * @param v The VC1Context to initialize * @return Status */ -static int vc1_init_common(VC1Context *v) +int ff_vc1_init_common(VC1Context *v) { static int done = 0; int i = 0; @@ -5274,7 +5274,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) avctx->idct_algo = FF_IDCT_WMV2; } - if (vc1_init_common(v) < 0) + if (ff_vc1_init_common(v) < 0) return -1; ff_vc1dsp_init(&v->vc1dsp); -- cgit v1.1 From 6d702dc072ffc255cd0f709132e55661698313e7 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Wed, 15 Feb 2012 21:04:12 +0100 Subject: proresenc: force bitrate not to exceed given limit Apple ProRes Format Specifications mentions target data size for every frame, so make sure frame meets it. This also allows encoder to demand much smaller packet sizes for output. --- libavcodec/proresenc.c | 72 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 10 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/proresenc.c b/libavcodec/proresenc.c index 73f7f7d..7e3e066 100644 --- a/libavcodec/proresenc.c +++ b/libavcodec/proresenc.c @@ -139,11 +139,14 @@ struct TrellisNode { int score; }; +#define MAX_STORED_Q 16 + typedef struct ProresContext { AVClass *class; DECLARE_ALIGNED(16, DCTELEM, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE]; DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16]; - int16_t quants[16][64]; + int16_t quants[MAX_STORED_Q][64]; + int16_t custom_q[64]; ProresDSPContext dsp; ScanTable scantable; @@ -156,6 +159,8 @@ typedef struct ProresContext { int num_planes; int bits_per_mb; + int frame_size; + int profile; const struct prores_profile *profile_info; @@ -348,6 +353,15 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int slice_width_factor = av_log2(mbs_per_slice); int num_cblocks, pwidth; int plane_factor, is_chroma; + uint16_t *qmat; + + if (quant < MAX_STORED_Q) { + qmat = ctx->quants[quant]; + } else { + qmat = ctx->custom_q; + for (i = 0; i < 64; i++) + qmat[i] = ctx->profile_info->quant[i] * quant; + } for (i = 0; i < ctx->num_planes; i++) { is_chroma = (i == 1 || i == 2); @@ -373,7 +387,7 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, sizes[i] = encode_slice_plane(ctx, pb, src, pic->linesize[i], mbs_per_slice, ctx->blocks[0], num_cblocks, plane_factor, - ctx->quants[quant]); + qmat); total_size += sizes[i]; } return total_size; @@ -500,6 +514,8 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic, int error, bits, bits_limit; int mbs, prev, cur, new_score; int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH]; + int overquant; + uint16_t *qmat; mbs = x + mbs_per_slice; @@ -526,7 +542,7 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic, mbs_per_slice, num_cblocks[i]); } - for (q = min_quant; q <= max_quant; q++) { + for (q = min_quant; q < max_quant + 2; q++) { ctx->nodes[trellis_node + q].prev_node = -1; ctx->nodes[trellis_node + q].quant = q; } @@ -549,12 +565,43 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic, slice_bits[q] = bits; slice_score[q] = error; } + if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) { + slice_bits[max_quant + 1] = slice_bits[max_quant]; + slice_score[max_quant + 1] = slice_score[max_quant] + 1; + overquant = max_quant; + } else { + for (q = max_quant + 1; q < 128; q++) { + bits = 0; + error = 0; + if (q < MAX_STORED_Q) { + qmat = ctx->quants[q]; + } else { + qmat = ctx->custom_q; + for (i = 0; i < 64; i++) + qmat[i] = ctx->profile_info->quant[i] * q; + } + for (i = 0; i < ctx->num_planes; i++) { + bits += estimate_slice_plane(ctx, &error, i, + src, pic->linesize[i], + mbs_per_slice, + num_cblocks[i], plane_factor[i], + qmat); + } + if (bits <= ctx->bits_per_mb * mbs_per_slice) + break; + } + + slice_bits[max_quant + 1] = bits; + slice_score[max_quant + 1] = error; + overquant = q; + } + ctx->nodes[trellis_node + max_quant + 1].quant = overquant; bits_limit = mbs * ctx->bits_per_mb; - for (pq = min_quant; pq <= max_quant; pq++) { + for (pq = min_quant; pq < max_quant + 2; pq++) { prev = trellis_node - TRELLIS_WIDTH + pq; - for (q = min_quant; q <= max_quant; q++) { + for (q = min_quant; q < max_quant + 2; q++) { cur = trellis_node + q; bits = ctx->nodes[prev].bits + slice_bits[q]; @@ -578,7 +625,7 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic, error = ctx->nodes[trellis_node + min_quant].score; pq = trellis_node + min_quant; - for (q = min_quant + 1; q <= max_quant; q++) { + for (q = min_quant + 1; q < max_quant + 2; q++) { if (ctx->nodes[trellis_node + q].score <= error) { error = ctx->nodes[trellis_node + q].score; pq = trellis_node + q; @@ -606,8 +653,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; avctx->coded_frame->key_frame = 1; - pkt_size = ctx->mb_width * ctx->mb_height * 64 * 3 * 12 - + ctx->num_slices * 2 + 200 + FF_MIN_BUFFER_SIZE; + pkt_size = ctx->frame_size + FF_MIN_BUFFER_SIZE; if ((ret = ff_alloc_packet(pkt, pkt_size)) < 0) { av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n"); @@ -762,9 +808,13 @@ static av_cold int encode_init(AVCodecContext *avctx) break; ctx->bits_per_mb = ctx->profile_info->br_tab[i]; + ctx->frame_size = ctx->num_slices * (2 + 2 * ctx->num_planes + + (2 * mps * ctx->bits_per_mb) / 8) + + 200; + min_quant = ctx->profile_info->min_quant; max_quant = ctx->profile_info->max_quant; - for (i = min_quant; i <= max_quant; i++) { + for (i = min_quant; i < MAX_STORED_Q; i++) { for (j = 0; j < 64; j++) ctx->quants[i][j] = ctx->profile_info->quant[j] * i; } @@ -773,6 +823,8 @@ static av_cold int encode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_DEBUG, "profile %d, %d slices, %d bits per MB\n", ctx->profile, ctx->num_slices, ctx->bits_per_mb); + av_log(avctx, AV_LOG_DEBUG, "estimated frame size %d\n", + ctx->frame_size); ctx->nodes = av_malloc((ctx->slices_width + 1) * TRELLIS_WIDTH * sizeof(*ctx->nodes)); @@ -780,7 +832,7 @@ static av_cold int encode_init(AVCodecContext *avctx) encode_close(avctx); return AVERROR(ENOMEM); } - for (i = min_quant; i <= max_quant; i++) { + for (i = min_quant; i < max_quant + 2; i++) { ctx->nodes[i].prev_node = -1; ctx->nodes[i].bits = 0; ctx->nodes[i].score = 0; -- cgit v1.1