diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2011-09-25 12:30:16 -0400 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2011-10-21 12:29:51 -0400 |
commit | f507dd067aec52b251f25e265cdb8b333db33b42 (patch) | |
tree | 32f4ce3da1789bf9ac437bd63b3a10222e007269 | |
parent | cb72230dfadb28651e036d717dc12d33b18a6893 (diff) | |
download | ffmpeg-f507dd067aec52b251f25e265cdb8b333db33b42.tar.gz |
mp3on4: allocate temp buffer with av_malloc() instead of on the stack.
Avoids allocating unnecessary memory and ensures proper alignment.
-rw-r--r-- | libavcodec/mpegaudiodec.c | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index 5d15d25e48..3bd7b02b9c 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -1894,6 +1894,7 @@ typedef struct MP3On4DecodeContext { int syncword; ///< syncword patch const uint8_t *coff; ///< channels offsets in output buffer MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance + OUT_INT *decoded_buf; ///< output buffer for decoded samples } MP3On4DecodeContext; #include "mpeg4audio.h" @@ -1913,6 +1914,20 @@ static const uint8_t chan_offset[8][5] = { }; +static av_cold int decode_close_mp3on4(AVCodecContext * avctx) +{ + MP3On4DecodeContext *s = avctx->priv_data; + int i; + + for (i = 0; i < s->frames; i++) + av_free(s->mp3decctx[i]); + + av_freep(&s->decoded_buf); + + return 0; +} + + static int decode_init_mp3on4(AVCodecContext * avctx) { MP3On4DecodeContext *s = avctx->priv_data; @@ -1962,19 +1977,18 @@ static int decode_init_mp3on4(AVCodecContext * avctx) s->mp3decctx[i]->mpadsp = s->mp3decctx[0]->mpadsp; } - return 0; -} - - -static av_cold int decode_close_mp3on4(AVCodecContext * avctx) -{ - MP3On4DecodeContext *s = avctx->priv_data; - int i; - - for (i = 0; i < s->frames; i++) - av_free(s->mp3decctx[i]); + /* Allocate buffer for multi-channel output if needed */ + if (s->frames > 1) { + s->decoded_buf = av_malloc(MPA_FRAME_SIZE * MPA_MAX_CHANNELS * + sizeof(*s->decoded_buf)); + if (!s->decoded_buf) + goto alloc_fail; + } return 0; +alloc_fail: + decode_close_mp3on4(avctx); + return AVERROR(ENOMEM); } @@ -1989,7 +2003,6 @@ static int decode_frame_mp3on4(AVCodecContext * avctx, int fsize, len = buf_size, out_size = 0; uint32_t header; OUT_INT *out_samples = data; - OUT_INT decoded_buf[MPA_FRAME_SIZE * MPA_MAX_CHANNELS]; OUT_INT *outptr, *bp; int fr, j, n; @@ -2002,7 +2015,7 @@ static int decode_frame_mp3on4(AVCodecContext * avctx, return -1; // If only one decoder interleave is not needed - outptr = s->frames == 1 ? out_samples : decoded_buf; + outptr = s->frames == 1 ? out_samples : s->decoded_buf; avctx->bit_rate = 0; @@ -2028,13 +2041,13 @@ static int decode_frame_mp3on4(AVCodecContext * avctx, bp = out_samples + s->coff[fr]; if(m->nb_channels == 1) { for(j = 0; j < n; j++) { - *bp = decoded_buf[j]; + *bp = s->decoded_buf[j]; bp += avctx->channels; } } else { for(j = 0; j < n; j++) { - bp[0] = decoded_buf[j++]; - bp[1] = decoded_buf[j]; + bp[0] = s->decoded_buf[j++]; + bp[1] = s->decoded_buf[j]; bp += avctx->channels; } } |