diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-05-19 06:19:23 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-06-25 23:15:37 +0200 |
commit | 4533e8b30a384e8b9bff9d228a028c1f58b4c6aa (patch) | |
tree | 92555066099325839d49a2a79eb1b5c1651571c9 | |
parent | a8dd7fe5b9943500ace8ec9c51f8fdfdb8472ea7 (diff) | |
download | ffmpeg-4533e8b30a384e8b9bff9d228a028c1f58b4c6aa.tar.gz |
avcodec/diracdec: move mc buffer allocation to per frame
Fixes out of array accesses for non default buffers with large strides
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 4a30f08505a4e85718896ff233c97be41a9754ca)
(cherry picked from commit 9c9fc79d9237d28e33161cb2e75082d8ad232b2e)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/diracdec.c | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index 2f1a4a58dd..fa342cc7e1 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -200,6 +200,7 @@ typedef struct DiracContext { uint16_t *mctmp; /* buffer holding the MC data multipled by OBMC weights */ uint8_t *mcscratch; + int buffer_stride; DECLARE_ALIGNED(16, uint8_t, obmc_weight)[3][MAX_BLOCKSIZE*MAX_BLOCKSIZE]; @@ -342,19 +343,41 @@ static int alloc_sequence_buffers(DiracContext *s) return AVERROR(ENOMEM); } - w = s->source.width; - h = s->source.height; - /* fixme: allocate using real stride here */ - s->sbsplit = av_malloc(sbwidth * sbheight); - s->blmotion = av_malloc(sbwidth * sbheight * 16 * sizeof(*s->blmotion)); - s->edge_emu_buffer_base = av_malloc((w+64)*MAX_BLOCKSIZE); + s->sbsplit = av_malloc_array(sbwidth, sbheight); + s->blmotion = av_malloc_array(sbwidth, sbheight * 16 * sizeof(*s->blmotion)); + + if (!s->sbsplit || !s->blmotion) + return AVERROR(ENOMEM); + return 0; +} + +static int alloc_buffers(DiracContext *s, int stride) +{ + int w = s->source.width; + int h = s->source.height; + + av_assert0(stride >= w); + stride += 64; + + if (s->buffer_stride >= stride) + return 0; + s->buffer_stride = 0; + + av_freep(&s->edge_emu_buffer_base); + memset(s->edge_emu_buffer, 0, sizeof(s->edge_emu_buffer)); + av_freep(&s->mctmp); + av_freep(&s->mcscratch); - s->mctmp = av_malloc((w+64+MAX_BLOCKSIZE) * (h+MAX_BLOCKSIZE) * sizeof(*s->mctmp)); - s->mcscratch = av_malloc((w+64)*MAX_BLOCKSIZE); + s->edge_emu_buffer_base = av_malloc_array(stride, MAX_BLOCKSIZE); - if (!s->sbsplit || !s->blmotion || !s->mctmp || !s->mcscratch) + s->mctmp = av_malloc_array((stride+MAX_BLOCKSIZE), (h+MAX_BLOCKSIZE) * sizeof(*s->mctmp)); + s->mcscratch = av_malloc_array(stride, MAX_BLOCKSIZE); + + if (!s->edge_emu_buffer_base || !s->mctmp || !s->mcscratch) return AVERROR(ENOMEM); + + s->buffer_stride = stride; return 0; } @@ -381,6 +404,7 @@ static void free_sequence_buffers(DiracContext *s) av_freep(&s->plane[i].idwt_tmp); } + s->buffer_stride = 0; av_freep(&s->sbsplit); av_freep(&s->blmotion); av_freep(&s->edge_emu_buffer_base); @@ -1817,6 +1841,9 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int s->plane[1].stride = pic->avframe.linesize[1]; s->plane[2].stride = pic->avframe.linesize[2]; + if (alloc_buffers(s, FFMAX3(FFABS(s->plane[0].stride), FFABS(s->plane[1].stride), FFABS(s->plane[2].stride))) < 0) + return AVERROR(ENOMEM); + /* [DIRAC_STD] 11.1 Picture parse. picture_parse() */ if (dirac_decode_picture_header(s)) return -1; |