mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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.
This commit is contained in:
parent
c75848cd4c
commit
abd8b9e7e0
@ -44,8 +44,9 @@ typedef struct LAMEContext {
|
|||||||
AVClass *class;
|
AVClass *class;
|
||||||
AVCodecContext *avctx;
|
AVCodecContext *avctx;
|
||||||
lame_global_flags *gfp;
|
lame_global_flags *gfp;
|
||||||
uint8_t buffer[BUFFER_SIZE];
|
uint8_t *buffer;
|
||||||
int buffer_index;
|
int buffer_index;
|
||||||
|
int buffer_size;
|
||||||
int reservoir;
|
int reservoir;
|
||||||
float *samples_flt[2];
|
float *samples_flt[2];
|
||||||
AudioFrameQueue afq;
|
AudioFrameQueue afq;
|
||||||
@ -53,6 +54,26 @@ typedef struct LAMEContext {
|
|||||||
} 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)
|
static av_cold int mp3lame_encode_close(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
LAMEContext *s = avctx->priv_data;
|
LAMEContext *s = avctx->priv_data;
|
||||||
@ -62,6 +83,7 @@ static av_cold int mp3lame_encode_close(AVCodecContext *avctx)
|
|||||||
#endif
|
#endif
|
||||||
av_freep(&s->samples_flt[0]);
|
av_freep(&s->samples_flt[0]);
|
||||||
av_freep(&s->samples_flt[1]);
|
av_freep(&s->samples_flt[1]);
|
||||||
|
av_freep(&s->buffer);
|
||||||
|
|
||||||
ff_af_queue_close(&s->afq);
|
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);
|
ff_dsputil_init(&s->dsp, avctx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -154,7 +180,7 @@ error:
|
|||||||
(const buf_type *)buf_name[0], \
|
(const buf_type *)buf_name[0], \
|
||||||
(const buf_type *)buf_name[1], frame->nb_samples, \
|
(const buf_type *)buf_name[1], frame->nb_samples, \
|
||||||
s->buffer + s->buffer_index, \
|
s->buffer + s->buffer_index, \
|
||||||
BUFFER_SIZE - s->buffer_index); \
|
s->buffer_size - s->buffer_index); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
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) {
|
if (lame_result == -1) {
|
||||||
av_log(avctx, AV_LOG_ERROR,
|
av_log(avctx, AV_LOG_ERROR,
|
||||||
"lame: output buffer too small (buffer index: %d, free bytes: %d)\n",
|
"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;
|
return -1;
|
||||||
}
|
}
|
||||||
s->buffer_index += lame_result;
|
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 */
|
/* add current frame to the queue */
|
||||||
if (frame) {
|
if (frame) {
|
||||||
|
Loading…
Reference in New Issue
Block a user