diff options
author | Janne Grunau <janne-libav@jannau.net> | 2012-11-25 22:42:07 +0100 |
---|---|---|
committer | Janne Grunau <janne-libav@jannau.net> | 2012-12-18 19:48:30 +0100 |
commit | f1d8763a02b5fce9a7d9789e049d74a45b15e1e8 (patch) | |
tree | c319ee271c465de1c768fb61d6f51bea0c33d465 /libavcodec/h264.c | |
parent | ed2d7d5868a4a5d914f1e5488d63ea696a3b2937 (diff) | |
download | ffmpeg-f1d8763a02b5fce9a7d9789e049d74a45b15e1e8.tar.gz |
mpegvideo: allocate scratch buffers after linesize is known
Since we can't know which stride a custom get_buffer() implementation is
going to use we have to allocate this scratch buffers after the linesize
is known. It was pretty safe for 8 bit per pixel pixel formats since we
always allocated memory for up to 16 bits per pixel. It broke hoever
with cmdutis.c's alloc_buffer() and high pixel bit depth since it
allocated larger edges than mpegvideo expected.
Fixes fuzzed sample nasa-8s2.ts_s244342.
Diffstat (limited to 'libavcodec/h264.c')
-rw-r--r-- | libavcodec/h264.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c index f568858792..3d6da2ec54 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -2292,8 +2292,10 @@ static int field_end(H264Context *h, int in_setup) /** * Replicate H264 "master" context to thread contexts. */ -static void clone_slice(H264Context *dst, H264Context *src) +static int clone_slice(H264Context *dst, H264Context *src) { + int ret; + memcpy(dst->block_offset, src->block_offset, sizeof(dst->block_offset)); dst->s.current_picture_ptr = src->s.current_picture_ptr; dst->s.current_picture = src->s.current_picture; @@ -2301,6 +2303,13 @@ static void clone_slice(H264Context *dst, H264Context *src) dst->s.uvlinesize = src->s.uvlinesize; dst->s.first_field = src->s.first_field; + if (!dst->s.edge_emu_buffer && + (ret = ff_mpv_frame_size_alloc(&dst->s, dst->s.linesize))) { + av_log(dst->s.avctx, AV_LOG_ERROR, + "Failed to allocate scratch buffers\n"); + return ret; + } + dst->prev_poc_msb = src->prev_poc_msb; dst->prev_poc_lsb = src->prev_poc_lsb; dst->prev_frame_num_offset = src->prev_frame_num_offset; @@ -2314,6 +2323,8 @@ static void clone_slice(H264Context *dst, H264Context *src) memcpy(dst->dequant4_coeff, src->dequant4_coeff, sizeof(src->dequant4_coeff)); memcpy(dst->dequant8_coeff, src->dequant8_coeff, sizeof(src->dequant8_coeff)); + + return 0; } /** @@ -2847,8 +2858,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0) ff_release_unused_pictures(s, 0); } } - if (h != h0) - clone_slice(h, h0); + if (h != h0 && (ret = clone_slice(h, h0)) < 0) + return ret; s->current_picture_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup |