[FFmpeg-cvslog] lavfi: add extended_data to AVFilterBuffer.

Anton Khirnov git at videolan.org
Thu May 10 02:33:21 CEST 2012


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Mon Apr 16 14:01:26 2012 +0200| [9453c9e1dec6ba44a6bedbfc02b72433e89c03dd] | committer: Anton Khirnov

lavfi: add extended_data to AVFilterBuffer.

This is similar to what has previously been done in AVFrame to allow
dealing with more than 8 channels.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9453c9e1dec6ba44a6bedbfc02b72433e89c03dd
---

 libavfilter/avfilter.c |   33 +++++++++++++++++++++++++++++++++
 libavfilter/avfilter.h |   32 ++++++++++++++++++++++++++++++++
 libavfilter/defaults.c |    2 ++
 3 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index f12ca3a..5973e6b 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -57,6 +57,7 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
             return NULL;
         }
         *ret->video = *ref->video;
+        ret->extended_data = ret->data;
     } else if (ref->type == AVMEDIA_TYPE_AUDIO) {
         ret->audio = av_malloc(sizeof(AVFilterBufferRefAudioProps));
         if (!ret->audio) {
@@ -64,6 +65,19 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
             return NULL;
         }
         *ret->audio = *ref->audio;
+
+        if (ref->extended_data != ref->data) {
+            int nb_channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout);
+            if (!(ret->extended_data = av_malloc(sizeof(*ret->extended_data) *
+                                                 nb_channels))) {
+                av_freep(&ret->audio);
+                av_freep(&ret);
+                return NULL;
+            }
+            memcpy(ret->extended_data, ref->extended_data,
+                   sizeof(*ret->extended_data) * nb_channels);
+        } else
+            ret->extended_data = ret->data;
     }
     ret->perms &= pmask;
     ret->buf->refcount ++;
@@ -76,6 +90,8 @@ void avfilter_unref_buffer(AVFilterBufferRef *ref)
         return;
     if (!(--ref->buf->refcount))
         ref->buf->free(ref->buf);
+    if (ref->extended_data != ref->data)
+        av_freep(&ref->extended_data);
     av_free(ref->video);
     av_free(ref->audio);
     av_free(ref);
@@ -338,6 +354,9 @@ avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int
     memcpy(picref->data,     pic->data,     sizeof(picref->data));
     memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
 
+    pic->   extended_data = pic->data;
+    picref->extended_data = picref->data;
+
     return picref;
 
 fail:
@@ -710,6 +729,8 @@ int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src)
 
 int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src)
 {
+    int planes, nb_channels;
+
     memcpy(dst->data, src->data, sizeof(dst->data));
     memcpy(dst->linesize, src->linesize, sizeof(dst->linesize));
 
@@ -727,6 +748,18 @@ int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src)
         dst->pict_type           = src->video->pict_type;
         break;
     case AVMEDIA_TYPE_AUDIO:
+        nb_channels = av_get_channel_layout_nb_channels(src->audio->channel_layout);
+        planes      = av_sample_fmt_is_planar(src->format) ? nb_channels : 1;
+
+        if (planes > FF_ARRAY_ELEMS(dst->data)) {
+            dst->extended_data = av_mallocz(planes * sizeof(*dst->extended_data));
+            if (!dst->extended_data)
+                return AVERROR(ENOMEM);
+            memcpy(dst->extended_data, src->extended_data,
+                   planes * sizeof(dst->extended_data));
+        } else
+            dst->extended_data = dst->data;
+
         dst->sample_rate         = src->audio->sample_rate;
         dst->channel_layout      = src->audio->channel_layout;
         dst->nb_samples          = src->audio->nb_samples;
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index ef61a5d..8965094 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -76,6 +76,22 @@ typedef struct AVFilterBuffer {
 
     int format;                 ///< media format
     int w, h;                   ///< width and height of the allocated buffer
+
+    /**
+     * pointers to the data planes/channels.
+     *
+     * For video, this should simply point to data[].
+     *
+     * For planar audio, each channel has a separate data pointer, and
+     * linesize[0] contains the size of each channel buffer.
+     * For packed audio, there is just one data pointer, and linesize[0]
+     * contains the total size of the buffer for all channels.
+     *
+     * Note: Both data and extended_data will always be set, but for planar
+     * audio with more channels that can fit in data, extended_data must be used
+     * in order to access all channels.
+     */
+    uint8_t **extended_data;
 } AVFilterBuffer;
 
 #define AV_PERM_READ     0x01   ///< can read from the buffer
@@ -140,6 +156,22 @@ typedef struct AVFilterBufferRef {
     enum AVMediaType type;      ///< media type of buffer data
     AVFilterBufferRefVideoProps *video; ///< video buffer specific properties
     AVFilterBufferRefAudioProps *audio; ///< audio buffer specific properties
+
+    /**
+     * pointers to the data planes/channels.
+     *
+     * For video, this should simply point to data[].
+     *
+     * For planar audio, each channel has a separate data pointer, and
+     * linesize[0] contains the size of each channel buffer.
+     * For packed audio, there is just one data pointer, and linesize[0]
+     * contains the total size of the buffer for all channels.
+     *
+     * Note: Both data and extended_data will always be set, but for planar
+     * audio with more channels that can fit in data, extended_data must be used
+     * in order to access all channels.
+     */
+    uint8_t **extended_data;
 } AVFilterBufferRef;
 
 /**
diff --git a/libavfilter/defaults.c b/libavfilter/defaults.c
index 6d9003d..086fcc0 100644
--- a/libavfilter/defaults.c
+++ b/libavfilter/defaults.c
@@ -28,6 +28,8 @@
 /* TODO: buffer pool.  see comment for avfilter_default_get_video_buffer() */
 void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
 {
+    if (ptr->extended_data != ptr->data)
+        av_freep(&ptr->extended_data);
     av_free(ptr->data[0]);
     av_free(ptr);
 }



More information about the ffmpeg-cvslog mailing list