Commit f507dd06 authored by Justin Ruggles's avatar Justin Ruggles

mp3on4: allocate temp buffer with av_malloc() instead of on the stack.

Avoids allocating unnecessary memory and ensures proper alignment.
parent cb72230d
...@@ -1894,6 +1894,7 @@ typedef struct MP3On4DecodeContext { ...@@ -1894,6 +1894,7 @@ typedef struct MP3On4DecodeContext {
int syncword; ///< syncword patch int syncword; ///< syncword patch
const uint8_t *coff; ///< channels offsets in output buffer const uint8_t *coff; ///< channels offsets in output buffer
MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance
OUT_INT *decoded_buf; ///< output buffer for decoded samples
} MP3On4DecodeContext; } MP3On4DecodeContext;
#include "mpeg4audio.h" #include "mpeg4audio.h"
...@@ -1913,6 +1914,20 @@ static const uint8_t chan_offset[8][5] = { ...@@ -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) static int decode_init_mp3on4(AVCodecContext * avctx)
{ {
MP3On4DecodeContext *s = avctx->priv_data; MP3On4DecodeContext *s = avctx->priv_data;
...@@ -1962,19 +1977,18 @@ static int decode_init_mp3on4(AVCodecContext * avctx) ...@@ -1962,19 +1977,18 @@ static int decode_init_mp3on4(AVCodecContext * avctx)
s->mp3decctx[i]->mpadsp = s->mp3decctx[0]->mpadsp; s->mp3decctx[i]->mpadsp = s->mp3decctx[0]->mpadsp;
} }
return 0; /* 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));
static av_cold int decode_close_mp3on4(AVCodecContext * avctx) if (!s->decoded_buf)
{ goto alloc_fail;
MP3On4DecodeContext *s = avctx->priv_data; }
int i;
for (i = 0; i < s->frames; i++)
av_free(s->mp3decctx[i]);
return 0; return 0;
alloc_fail:
decode_close_mp3on4(avctx);
return AVERROR(ENOMEM);
} }
...@@ -1989,7 +2003,6 @@ static int decode_frame_mp3on4(AVCodecContext * avctx, ...@@ -1989,7 +2003,6 @@ static int decode_frame_mp3on4(AVCodecContext * avctx,
int fsize, len = buf_size, out_size = 0; int fsize, len = buf_size, out_size = 0;
uint32_t header; uint32_t header;
OUT_INT *out_samples = data; OUT_INT *out_samples = data;
OUT_INT decoded_buf[MPA_FRAME_SIZE * MPA_MAX_CHANNELS];
OUT_INT *outptr, *bp; OUT_INT *outptr, *bp;
int fr, j, n; int fr, j, n;
...@@ -2002,7 +2015,7 @@ static int decode_frame_mp3on4(AVCodecContext * avctx, ...@@ -2002,7 +2015,7 @@ static int decode_frame_mp3on4(AVCodecContext * avctx,
return -1; return -1;
// If only one decoder interleave is not needed // 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; avctx->bit_rate = 0;
...@@ -2028,13 +2041,13 @@ static int decode_frame_mp3on4(AVCodecContext * avctx, ...@@ -2028,13 +2041,13 @@ static int decode_frame_mp3on4(AVCodecContext * avctx,
bp = out_samples + s->coff[fr]; bp = out_samples + s->coff[fr];
if(m->nb_channels == 1) { if(m->nb_channels == 1) {
for(j = 0; j < n; j++) { for(j = 0; j < n; j++) {
*bp = decoded_buf[j]; *bp = s->decoded_buf[j];
bp += avctx->channels; bp += avctx->channels;
} }
} else { } else {
for(j = 0; j < n; j++) { for(j = 0; j < n; j++) {
bp[0] = decoded_buf[j++]; bp[0] = s->decoded_buf[j++];
bp[1] = decoded_buf[j]; bp[1] = s->decoded_buf[j];
bp += avctx->channels; bp += avctx->channels;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment