Commit abd8b9e7 authored by Justin Ruggles's avatar Justin Ruggles

libmp3lame: resize the output buffer if needed

The LAME API documentation for the required buffer size refers to the size for
a single encode call. However, we store multiple frames in the same output
buffer but only read 1 frame at a time out of it. As a result, the buffer size
given in lame_encode_buffer() is actually smaller than what it should be.
Since we do not know how many frames it will end up buffering, it is best to
just reallocate if needed.
parent c75848cd
......@@ -44,8 +44,9 @@ typedef struct LAMEContext {
AVClass *class;
AVCodecContext *avctx;
lame_global_flags *gfp;
uint8_t buffer[BUFFER_SIZE];
uint8_t *buffer;
int buffer_index;
int buffer_size;
int reservoir;
float *samples_flt[2];
AudioFrameQueue afq;
......@@ -53,6 +54,26 @@ typedef struct LAMEContext {
} LAMEContext;
static int realloc_buffer(LAMEContext *s)
{
if (!s->buffer || s->buffer_size - s->buffer_index < BUFFER_SIZE) {
uint8_t *tmp;
int new_size = s->buffer_index + 2 * BUFFER_SIZE;
av_dlog(s->avctx, "resizing output buffer: %d -> %d\n", s->buffer_size,
new_size);
tmp = av_realloc(s->buffer, new_size);
if (!tmp) {
av_freep(&s->buffer);
s->buffer_size = s->buffer_index = 0;
return AVERROR(ENOMEM);
}
s->buffer = tmp;
s->buffer_size = new_size;
}
return 0;
}
static av_cold int mp3lame_encode_close(AVCodecContext *avctx)
{
LAMEContext *s = avctx->priv_data;
......@@ -62,6 +83,7 @@ static av_cold int mp3lame_encode_close(AVCodecContext *avctx)
#endif
av_freep(&s->samples_flt[0]);
av_freep(&s->samples_flt[1]);
av_freep(&s->buffer);
ff_af_queue_close(&s->afq);
......@@ -141,6 +163,10 @@ static av_cold int mp3lame_encode_init(AVCodecContext *avctx)
}
}
ret = realloc_buffer(s);
if (ret < 0)
goto error;
ff_dsputil_init(&s->dsp, avctx);
return 0;
......@@ -154,7 +180,7 @@ error:
(const buf_type *)buf_name[0], \
(const buf_type *)buf_name[1], frame->nb_samples, \
s->buffer + s->buffer_index, \
BUFFER_SIZE - s->buffer_index); \
s->buffer_size - s->buffer_index); \
} while (0)
static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
......@@ -197,11 +223,16 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
if (lame_result == -1) {
av_log(avctx, AV_LOG_ERROR,
"lame: output buffer too small (buffer index: %d, free bytes: %d)\n",
s->buffer_index, BUFFER_SIZE - s->buffer_index);
s->buffer_index, s->buffer_size - s->buffer_index);
}
return -1;
}
s->buffer_index += lame_result;
ret = realloc_buffer(s);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "error reallocating output buffer\n");
return ret;
}
/* add current frame to the queue */
if (frame) {
......
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