aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2014-05-19 06:19:23 +0200
committerMichael Niedermayer <michaelni@gmx.at>2014-06-02 22:59:49 +0200
commit9ea1e82d68c1308657e4cbbfab0e6610c4d4aeb9 (patch)
tree511728269dfeb9b45502cfeb19edfffa4d2a8fb4
parent5cd2cdf33fcd5d6ce0485369e2506ccd9d8be4da (diff)
downloadffmpeg-9ea1e82d68c1308657e4cbbfab0e6610c4d4aeb9.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)
-rw-r--r--libavcodec/diracdec.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c
index 8ab0eb0872..06d8b79b12 100644
--- a/libavcodec/diracdec.c
+++ b/libavcodec/diracdec.c
@@ -201,6 +201,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];
@@ -343,19 +344,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;
}
@@ -382,6 +405,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);
@@ -1854,6 +1878,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;