]> git.sesse.net Git - ffmpeg/commitdiff
Merge commit 'e57c4706e969afa1f2384481b955ccd9494cddb5'
authorMichael Niedermayer <michaelni@gmx.at>
Wed, 5 Dec 2012 15:25:03 +0000 (16:25 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Wed, 5 Dec 2012 15:53:12 +0000 (16:53 +0100)
* commit 'e57c4706e969afa1f2384481b955ccd9494cddb5':
  lavc: don't reuse audio buffers

This commit causes a 0.5% speedloss for mp3 and 2% for raw pcm, that is
"time ffmpeg" style tested thus includes disk IO, demux and parsing

I would not have merged it if it wasnt required for the "new" buffer API
but sadly it is.
Once the new API is in ill reimplement proper buffer reuse, which will
fix this speedloss. In case we choose not to merge the "new" buffer
API then this commit here should be reverted.

Conflicts:
libavcodec/internal.h
libavcodec/utils.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
libavcodec/internal.h
libavcodec/utils.c

index 30a8e4c40dd1d422d83783a86bd0cb6af834f09d..01620fa125e13d70da9f765eeb15df5f5d84bf17 100644 (file)
@@ -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 {
@@ -79,6 +76,12 @@ typedef struct AVCodecInternal {
      */
     int last_audio_frame;
 
+    /**
+     * The data for the last allocated audio frame.
+     * Stored here so we can free it.
+     */
+    uint8_t *audio_data;
+
     /**
      * temporary buffer used for encoders to store their bitstream
      */
index 4db94713e0c98337523ab8b479280224a790ca0d..ab96a06b7621bc90ed8092cd61975f9fc854fafd 100644 (file)
@@ -342,72 +342,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;
-
-    /* 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)) < 0)
-            return ret;
+    frame->data[0] = av_mallocz(buf_size);
+    if (!frame->data[0])
+        return AVERROR(ENOMEM);
 
-        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);
@@ -2270,18 +2227,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_freep(&buf->extended_data);
-    }
-    av_freep(&avci->buffer);
+    av_freep(&avci->audio_data);
 }
 
 void avcodec_default_free_buffers(AVCodecContext *avctx)