From dcad4677d637cd2f701917e38361fa96b8c9a418 Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Thu, 23 Jun 2016 18:07:02 +0100 Subject: [PATCH] diracdec: do not allocate and free slice parameters every frame Signed-off-by: Rostislav Pehlivanov --- libavcodec/diracdec.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index e95ce9e10e..ef0274ab5c 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -121,6 +121,14 @@ typedef struct Plane { SubBand band[MAX_DWT_LEVELS][4]; } Plane; +/* Used by Low Delay and High Quality profiles */ +typedef struct DiracSlice { + GetBitContext gb; + int slice_x; + int slice_y; + int bytes; +} DiracSlice; + typedef struct DiracContext { AVCodecContext *avctx; MpegvideoEncDSPContext mpvencdsp; @@ -167,6 +175,9 @@ typedef struct DiracContext { int threads_num_buf; /* Current # of buffers allocated */ int thread_buf_size; /* Each thread has a buffer this size */ + DiracSlice *slice_params_buf; + int slice_params_num_buf; + struct { unsigned width; unsigned height; @@ -417,6 +428,7 @@ static av_cold int dirac_decode_end(AVCodecContext *avctx) av_frame_free(&s->all_frames[i].avframe); av_freep(&s->thread_buf); + av_freep(&s->slice_params_buf); return 0; } @@ -724,15 +736,6 @@ static void decode_subband(DiracContext *s, GetBitContext *gb, int quant, } } -/* Used by Low Delay and High Quality profiles */ -typedef struct DiracSlice { - GetBitContext gb; - int slice_x; - int slice_y; - int bytes; -} DiracSlice; - - /** * Dirac Specification -> * 13.5.2 Slices. slice(sx,sy) @@ -904,9 +907,15 @@ static int decode_lowdelay(DiracContext *s) SliceCoeffs tmp[MAX_DWT_LEVELS]; int slice_num = 0; - slices = av_mallocz_array(s->num_x, s->num_y * sizeof(DiracSlice)); - if (!slices) - return AVERROR(ENOMEM); + if (s->slice_params_num_buf != (s->num_x * s->num_y)) { + s->slice_params_buf = av_realloc_f(s->thread_buf, s->num_x * s->num_y, sizeof(DiracSlice)); + if (!s->slice_params_buf) { + av_log(s->avctx, AV_LOG_ERROR, "slice params buffer allocation failure\n"); + return AVERROR(ENOMEM); + } + s->slice_params_num_buf = s->num_x * s->num_y; + } + slices = s->slice_params_buf; /* 8 becacuse that's how much the golomb reader could overread junk data * from another plane/slice at most, and 512 because SIMD */ @@ -941,7 +950,6 @@ static int decode_lowdelay(DiracContext *s) } if (bytes >= INT_MAX || bytes*8 > bufsize) { av_log(s->avctx, AV_LOG_ERROR, "too many bytes\n"); - av_free(slices); return AVERROR_INVALIDDATA; } @@ -998,7 +1006,7 @@ static int decode_lowdelay(DiracContext *s) intra_dc_prediction_8(&s->plane[2].band[0][0]); } } - av_free(slices); + return 0; }