aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustin Ruggles <justin.ruggles@gmail.com>2011-09-25 12:30:16 -0400
committerJustin Ruggles <justin.ruggles@gmail.com>2011-10-21 12:29:51 -0400
commitf507dd067aec52b251f25e265cdb8b333db33b42 (patch)
tree32f4ce3da1789bf9ac437bd63b3a10222e007269
parentcb72230dfadb28651e036d717dc12d33b18a6893 (diff)
downloadffmpeg-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.c45
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;
}
}