mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
lavc: don't reuse audio buffers
Any performance gain from this is negligible and not worth the extra code.
This commit is contained in:
parent
ff953fecff
commit
e57c4706e9
@ -39,9 +39,6 @@ typedef struct InternalBuffer {
|
||||
int width;
|
||||
int height;
|
||||
enum AVPixelFormat pix_fmt;
|
||||
uint8_t **extended_data;
|
||||
int audio_data_size;
|
||||
int nb_channels;
|
||||
} InternalBuffer;
|
||||
|
||||
typedef struct AVCodecInternal {
|
||||
@ -78,6 +75,12 @@ typedef struct AVCodecInternal {
|
||||
* padded with silence. Reject all subsequent frames.
|
||||
*/
|
||||
int last_audio_frame;
|
||||
|
||||
/**
|
||||
* The data for the last allocated audio frame.
|
||||
* Stored here so we can free it.
|
||||
*/
|
||||
uint8_t *audio_data;
|
||||
} AVCodecInternal;
|
||||
|
||||
struct AVCodecDefault {
|
||||
|
@ -300,72 +300,29 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
|
||||
static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame)
|
||||
{
|
||||
AVCodecInternal *avci = avctx->internal;
|
||||
InternalBuffer *buf;
|
||||
int buf_size, ret;
|
||||
|
||||
av_freep(&avci->audio_data);
|
||||
buf_size = av_samples_get_buffer_size(NULL, avctx->channels,
|
||||
frame->nb_samples, avctx->sample_fmt,
|
||||
0);
|
||||
if (buf_size < 0)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
/* allocate InternalBuffer if needed */
|
||||
if (!avci->buffer) {
|
||||
avci->buffer = av_mallocz(sizeof(InternalBuffer));
|
||||
if (!avci->buffer)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
buf = avci->buffer;
|
||||
frame->data[0] = av_mallocz(buf_size);
|
||||
if (!frame->data[0])
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
/* if there is a previously-used internal buffer, check its size and
|
||||
* channel count to see if we can reuse it */
|
||||
if (buf->extended_data) {
|
||||
/* if current buffer is too small, free it */
|
||||
if (buf->extended_data[0] && buf_size > buf->audio_data_size) {
|
||||
av_free(buf->extended_data[0]);
|
||||
if (buf->extended_data != buf->data)
|
||||
av_free(buf->extended_data);
|
||||
buf->extended_data = NULL;
|
||||
buf->data[0] = NULL;
|
||||
}
|
||||
/* if number of channels has changed, reset and/or free extended data
|
||||
* pointers but leave data buffer in buf->data[0] for reuse */
|
||||
if (buf->nb_channels != avctx->channels) {
|
||||
if (buf->extended_data != buf->data)
|
||||
av_free(buf->extended_data);
|
||||
buf->extended_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* if there is no previous buffer or the previous buffer cannot be used
|
||||
* as-is, allocate a new buffer and/or rearrange the channel pointers */
|
||||
if (!buf->extended_data) {
|
||||
if (!buf->data[0]) {
|
||||
if (!(buf->data[0] = av_mallocz(buf_size)))
|
||||
return AVERROR(ENOMEM);
|
||||
buf->audio_data_size = buf_size;
|
||||
}
|
||||
if ((ret = avcodec_fill_audio_frame(frame, avctx->channels,
|
||||
avctx->sample_fmt, buf->data[0],
|
||||
buf->audio_data_size, 0)))
|
||||
return ret;
|
||||
|
||||
if (frame->extended_data == frame->data)
|
||||
buf->extended_data = buf->data;
|
||||
else
|
||||
buf->extended_data = frame->extended_data;
|
||||
memcpy(buf->data, frame->data, sizeof(frame->data));
|
||||
buf->linesize[0] = frame->linesize[0];
|
||||
buf->nb_channels = avctx->channels;
|
||||
} else {
|
||||
/* copy InternalBuffer info to the AVFrame */
|
||||
frame->extended_data = buf->extended_data;
|
||||
frame->linesize[0] = buf->linesize[0];
|
||||
memcpy(frame->data, buf->data, sizeof(frame->data));
|
||||
ret = avcodec_fill_audio_frame(frame, avctx->channels, avctx->sample_fmt,
|
||||
frame->data[0], buf_size, 0);
|
||||
if (ret < 0) {
|
||||
av_freep(&frame->data[0]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
frame->type = FF_BUFFER_TYPE_INTERNAL;
|
||||
|
||||
avci->audio_data = frame->data[0];
|
||||
if (avctx->debug & FF_DEBUG_BUFFERS)
|
||||
av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p, "
|
||||
"internal audio buffer used\n", frame);
|
||||
@ -1787,18 +1744,7 @@ static void video_free_buffers(AVCodecContext *s)
|
||||
static void audio_free_buffers(AVCodecContext *avctx)
|
||||
{
|
||||
AVCodecInternal *avci = avctx->internal;
|
||||
InternalBuffer *buf;
|
||||
|
||||
if (!avci->buffer)
|
||||
return;
|
||||
buf = avci->buffer;
|
||||
|
||||
if (buf->extended_data) {
|
||||
av_free(buf->extended_data[0]);
|
||||
if (buf->extended_data != buf->data)
|
||||
av_free(buf->extended_data);
|
||||
}
|
||||
av_freep(&avci->buffer);
|
||||
av_freep(&avci->audio_data);
|
||||
}
|
||||
|
||||
void avcodec_default_free_buffers(AVCodecContext *avctx)
|
||||
|
Loading…
Reference in New Issue
Block a user