mp3on4: allocate temp buffer with av_malloc() instead of on the stack.
authorJustin Ruggles <justin.ruggles@gmail.com>
Sun, 25 Sep 2011 16:30:16 +0000 (12:30 -0400)
committerJustin Ruggles <justin.ruggles@gmail.com>
Fri, 21 Oct 2011 16:29:51 +0000 (12:29 -0400)
Avoids allocating unnecessary memory and ensures proper alignment.

libavcodec/mpegaudiodec.c

index 5d15d25..3bd7b02 100644 (file)
@@ -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;
                 }
             }