[FFmpeg-devel] [PATCH 2/2] lavfi: add layout negotiation fields and helper functions.

Mina Nagy Zaki mnzaki at gmail.com
Thu Jun 9 12:27:50 CEST 2011


---
 libavfilter/avfilter.c      |    3 ++
 libavfilter/avfilter.h      |   30 +++++++++++++++++-------
 libavfilter/avfiltergraph.c |   10 +++++++-
 libavfilter/defaults.c      |   52 +++++++++++++++++++++++++++---------------
 libavfilter/formats.c       |   22 ++++++++++++++++++
 5 files changed, 88 insertions(+), 29 deletions(-)

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index acab816..815a5f5 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -217,6 +217,9 @@ int avfilter_insert_filter(AVFilterLink *link, 
AVFilterContext *filt,
     if (link->out_formats)
         avfilter_formats_changeref(&link->out_formats,
                                    &filt->outputs[filt_dstpad_idx]-
>out_formats);
+    if (link->out_chlayouts)
+        avfilter_formats_changeref(&link->out_chlayouts,
+                                   &filt->outputs[filt_dstpad_idx]-
>out_chlayouts);
 
     return 0;
 }
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 3a71fb4..483758a 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -255,6 +255,11 @@ int avfilter_add_format(AVFilterFormats **avff, int64_t 
fmt);
 AVFilterFormats *avfilter_all_formats(enum AVMediaType type);
 
 /**
+ * Return a list of all channel layouts supported by FFmpeg.
+ */
+AVFilterFormats *avfilter_all_chlayouts(void);
+
+/**
  * Return a format list which contains the intersection of the formats of
  * a and b. Also, all the references of a, all the references of b, and
  * a and b themselves will be deallocated.
@@ -465,11 +470,12 @@ AVFilterBufferRef 
*avfilter_default_get_audio_buffer(AVFilterLink *link, int per
                                                      int64_t channel_layout, 
int planar);
 
 /**
- * A helper for query_formats() which sets all links to the same list of
- * formats. If there are no links hooked to this filter, the list of formats 
is
- * freed.
+ * Helpers for query_formats() which set all links to the same list of
+ * formats/layouts. If there are no links hooked to this filter, the list
+ * of formats is freed.
  */
 void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats 
*formats);
+void avfilter_set_common_chlayouts(AVFilterContext *ctx, AVFilterFormats 
*formats);
 
 /** Default handler for query_formats() */
 int avfilter_default_query_formats(AVFilterContext *ctx);
@@ -520,9 +526,9 @@ typedef struct AVFilter {
     void (*uninit)(AVFilterContext *ctx);
 
     /**
-     * Queries formats supported by the filter and its pads, and sets the
-     * in_formats for links connected to its output pads, and out_formats
-     * for links connected to its input pads.
+     * Queries formats/layouts supported by the filter and its pads, and sets
+     * the in_formats/in_chlayouts for links connected to its output pads,
+     * and out_formats/out_chlayouts for links connected to its input pads.
      *
      * @return zero on success, a negative value corresponding to an
      * AVERROR code otherwise
@@ -592,13 +598,19 @@ struct AVFilterLink {
     int format;                 ///< agreed upon media format
 
     /**
-     * Lists of formats supported by the input and output filters 
respectively.
-     * These lists are used for negotiating the format to actually be used,
-     * which will be loaded into the format member, above, when chosen.
+     * Lists of formats and channel layouts supported by the input and output
+     * filters respectively. These lists are used for negotiating the format
+     * to actually be used, which will be loaded into the format and
+     * channel_layout members, above, when chosen.
+     *
+     * An empty list indicates that all formats are supported.
      */
     AVFilterFormats *in_formats;
     AVFilterFormats *out_formats;
 
+    AVFilterFormats *in_chlayouts;
+    AVFilterFormats *out_chlayouts;
+
     /**
      * The buffer reference currently being sent across the link by the source
      * filter. This is used internally by the filter system to allow
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index bdf22b3..080f29f 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -195,9 +195,17 @@ static void pick_format(AVFilterLink *link)
 
     link->in_formats->format_count = 1;
     link->format = link->in_formats->formats[0];
-
     avfilter_formats_unref(&link->in_formats);
     avfilter_formats_unref(&link->out_formats);
+
+    if (link->type == AVMEDIA_TYPE_AUDIO) {
+        link->in_chlayouts->format_count = 1;
+        link->channel_layout = link->in_chlayouts->formats[0];
+        avfilter_formats_unref(&link->in_chlayouts);
+        avfilter_formats_unref(&link->out_chlayouts);
+
+    }
+
 }
 
 static void pick_formats(AVFilterGraph *graph)
diff --git a/libavfilter/defaults.c b/libavfilter/defaults.c
index c98dfa9..505a24f 100644
--- a/libavfilter/defaults.c
+++ b/libavfilter/defaults.c
@@ -204,28 +204,38 @@ int avfilter_default_config_output_link(AVFilterLink 
*link)
  * FIXME: this will need changed for filters with a mix of pad types
  * (video + audio, etc)
  */
+
+#define SET_COMMON_ELEMS(type) do {                                         \
+    int count = 0, i;                                                       \
+                                                                            \
+    for (i = 0; i < ctx->input_count; i++) {                                \
+        if (ctx->inputs[i]) {                                               \
+            avfilter_formats_ref(formats, &ctx->inputs[i]->out_##type);     \
+            count++;                                                        \
+        }                                                                   \
+    }                                                                       \
+    for (i = 0; i < ctx->output_count; i++) {                               \
+        if (ctx->outputs[i]) {                                              \
+            avfilter_formats_ref(formats, &ctx->outputs[i]->in_##type);     \
+            count++;                                                        \
+        }                                                                   \
+    }                                                                       \
+                                                                            \
+    if (!count) {                                                           \
+        av_free(formats->formats);                                          \
+        av_free(formats->refs);                                             \
+        av_free(formats);                                                   \
+    }                                                                       \
+} while(0)
+
 void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats 
*formats)
 {
-    int count = 0, i;
-
-    for (i = 0; i < ctx->input_count; i++) {
-        if (ctx->inputs[i]) {
-            avfilter_formats_ref(formats, &ctx->inputs[i]->out_formats);
-            count++;
-        }
-    }
-    for (i = 0; i < ctx->output_count; i++) {
-        if (ctx->outputs[i]) {
-            avfilter_formats_ref(formats, &ctx->outputs[i]->in_formats);
-            count++;
-        }
-    }
+    SET_COMMON_ELEMS(formats);
+}
 
-    if (!count) {
-        av_free(formats->formats);
-        av_free(formats->refs);
-        av_free(formats);
-    }
+void avfilter_set_common_chlayouts(AVFilterContext *ctx, AVFilterFormats 
*formats)
+{
+    SET_COMMON_ELEMS(chlayouts);
 }
 
 int avfilter_default_query_formats(AVFilterContext *ctx)
@@ -235,6 +245,10 @@ int avfilter_default_query_formats(AVFilterContext *ctx)
                             AVMEDIA_TYPE_VIDEO;
 
     avfilter_set_common_formats(ctx, avfilter_all_formats(type));
+
+    if (type == AVMEDIA_TYPE_AUDIO)
+        avfilter_set_common_chlayouts(ctx, avfilter_all_chlayouts());
+
     return 0;
 }
 
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index 962a915..181a671 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -20,6 +20,7 @@
  */
 
 #include "libavutil/pixdesc.h"
+#include "libavutil/audioconvert.h"
 #include "avfilter.h"
 
 /**
@@ -123,6 +124,27 @@ AVFilterFormats *avfilter_all_formats(enum AVMediaType 
type)
     return ret;
 }
 
+AVFilterFormats *avfilter_all_chlayouts(void)
+{
+    int64_t chlayouts[] = {
+        AV_CH_LAYOUT_MONO,
+        AV_CH_LAYOUT_STEREO,
+        AV_CH_LAYOUT_4POINT0,
+        AV_CH_LAYOUT_QUAD,
+        AV_CH_LAYOUT_5POINT0,
+        AV_CH_LAYOUT_5POINT0_BACK,
+        AV_CH_LAYOUT_5POINT1,
+        AV_CH_LAYOUT_5POINT1_BACK,
+        AV_CH_LAYOUT_5POINT1|AV_CH_LAYOUT_STEREO_DOWNMIX,
+        AV_CH_LAYOUT_7POINT1,
+        AV_CH_LAYOUT_7POINT1_WIDE,
+        AV_CH_LAYOUT_7POINT1|AV_CH_LAYOUT_STEREO_DOWNMIX,
+        -1,
+    };
+
+    return avfilter_make_format_list(chlayouts);
+}
+
 void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
 {
     *ref = f;
-- 
1.7.4.4


More information about the ffmpeg-devel mailing list