lavc: don't reuse audio buffers

Any performance gain from this is negligible and not worth the extra
code.
This commit is contained in:
Anton Khirnov 2012-11-12 19:56:55 +01:00
parent ff953fecff
commit e57c4706e9
2 changed files with 17 additions and 68 deletions

View File

@ -39,9 +39,6 @@ typedef struct InternalBuffer {
int width; int width;
int height; int height;
enum AVPixelFormat pix_fmt; enum AVPixelFormat pix_fmt;
uint8_t **extended_data;
int audio_data_size;
int nb_channels;
} InternalBuffer; } InternalBuffer;
typedef struct AVCodecInternal { typedef struct AVCodecInternal {
@ -78,6 +75,12 @@ typedef struct AVCodecInternal {
* padded with silence. Reject all subsequent frames. * padded with silence. Reject all subsequent frames.
*/ */
int last_audio_frame; int last_audio_frame;
/**
* The data for the last allocated audio frame.
* Stored here so we can free it.
*/
uint8_t *audio_data;
} AVCodecInternal; } AVCodecInternal;
struct AVCodecDefault { struct AVCodecDefault {

View File

@ -300,72 +300,29 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame)
{ {
AVCodecInternal *avci = avctx->internal; AVCodecInternal *avci = avctx->internal;
InternalBuffer *buf;
int buf_size, ret; int buf_size, ret;
av_freep(&avci->audio_data);
buf_size = av_samples_get_buffer_size(NULL, avctx->channels, buf_size = av_samples_get_buffer_size(NULL, avctx->channels,
frame->nb_samples, avctx->sample_fmt, frame->nb_samples, avctx->sample_fmt,
0); 0);
if (buf_size < 0) if (buf_size < 0)
return AVERROR(EINVAL); return AVERROR(EINVAL);
/* allocate InternalBuffer if needed */ frame->data[0] = av_mallocz(buf_size);
if (!avci->buffer) { if (!frame->data[0])
avci->buffer = av_mallocz(sizeof(InternalBuffer)); return AVERROR(ENOMEM);
if (!avci->buffer)
return AVERROR(ENOMEM);
}
buf = avci->buffer;
/* if there is a previously-used internal buffer, check its size and ret = avcodec_fill_audio_frame(frame, avctx->channels, avctx->sample_fmt,
* channel count to see if we can reuse it */ frame->data[0], buf_size, 0);
if (buf->extended_data) { if (ret < 0) {
/* if current buffer is too small, free it */ av_freep(&frame->data[0]);
if (buf->extended_data[0] && buf_size > buf->audio_data_size) { return ret;
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));
} }
frame->type = FF_BUFFER_TYPE_INTERNAL; frame->type = FF_BUFFER_TYPE_INTERNAL;
avci->audio_data = frame->data[0];
if (avctx->debug & FF_DEBUG_BUFFERS) if (avctx->debug & FF_DEBUG_BUFFERS)
av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p, " av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p, "
"internal audio buffer used\n", frame); "internal audio buffer used\n", frame);
@ -1787,18 +1744,7 @@ static void video_free_buffers(AVCodecContext *s)
static void audio_free_buffers(AVCodecContext *avctx) static void audio_free_buffers(AVCodecContext *avctx)
{ {
AVCodecInternal *avci = avctx->internal; AVCodecInternal *avci = avctx->internal;
InternalBuffer *buf; av_freep(&avci->audio_data);
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);
} }
void avcodec_default_free_buffers(AVCodecContext *avctx) void avcodec_default_free_buffers(AVCodecContext *avctx)