Browse Source

lavfi: add layout negotiation fields and helper functions.

Mina Nagy Zaki 13 years ago
parent
commit
fd2c0a5db2

+ 9 - 0
doc/APIchanges

@@ -13,6 +13,15 @@ libavutil:   2011-04-18
 
 API changes, most recent first:
 
+2011-06-19 - xxxxxxx - lavfi 2.23.0 - avfilter.h
+  Add layout negotiation fields and helper functions.
+
+  In particular, add in_chlayouts and out_chlayouts to AVFilterLink,
+  and the functions:
+  avfilter_set_common_sample_formats()
+  avfilter_set_common_channel_layouts()
+  avfilter_all_channel_layouts()
+
 2011-06-19 - xxxxxxx - lavfi 2.22.0 - AVFilterFormats
   Change type of AVFilterFormats.formats from int * to int64_t *,
   and update formats handling API accordingly.

+ 1 - 1
ffplay.c

@@ -1644,7 +1644,7 @@ static int input_query_formats(AVFilterContext *ctx)
         priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE
     };
 
-    avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+    avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts));
     return 0;
 }
 

+ 3 - 0
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;
 }

+ 23 - 11
libavfilter/avfilter.h

@@ -26,7 +26,7 @@
 #include "libavutil/samplefmt.h"
 
 #define LIBAVFILTER_VERSION_MAJOR  2
-#define LIBAVFILTER_VERSION_MINOR 22
+#define LIBAVFILTER_VERSION_MINOR 23
 #define LIBAVFILTER_VERSION_MICRO  0
 
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
@@ -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_channel_layouts(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
@@ -466,11 +471,13 @@ 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_pixel_formats(AVFilterContext *ctx, AVFilterFormats *formats);
+void avfilter_set_common_sample_formats(AVFilterContext *ctx, AVFilterFormats *formats);
+void avfilter_set_common_channel_layouts(AVFilterContext *ctx, AVFilterFormats *formats);
 
 /** Default handler for query_formats() */
 int avfilter_default_query_formats(AVFilterContext *ctx);
@@ -521,9 +528,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
@@ -593,13 +600,18 @@ 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.
+     *
      */
     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

+ 8 - 1
libavfilter/avfiltergraph.c

@@ -195,9 +195,16 @@ 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)

+ 40 - 31
libavfilter/defaults.c

@@ -197,45 +197,54 @@ int avfilter_default_config_output_link(AVFilterLink *link)
     return 0;
 }
 
-/**
- * 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.
- *
- * FIXME: this will need changed for filters with a mix of pad types
- * (video + audio, etc)
- */
-void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
+static void set_common_formats(AVFilterContext *ctx, AVFilterFormats *fmts,
+                               enum AVMediaType type, int offin, int offout)
 {
-    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++;
-        }
+    int i;
+    for (i = 0; i < ctx->input_count; i++)
+        if (ctx->inputs[i] && ctx->inputs[i]->type == type)
+            avfilter_formats_ref(fmts,
+                                 (AVFilterFormats**)((void*)ctx->inputs[i]+offout));
+
+    for (i = 0; i < ctx->output_count; i++)
+        if (ctx->outputs[i] && ctx->outputs[i]->type == type)
+            avfilter_formats_ref(fmts,
+                                 (AVFilterFormats**)((void*)ctx->outputs[i]+offin));
+
+    if (!fmts->refcount) {
+        av_free(fmts->formats);
+        av_free(fmts->refs);
+        av_free(fmts);
     }
+}
 
-    if (!count) {
-        av_free(formats->formats);
-        av_free(formats->refs);
-        av_free(formats);
-    }
+void avfilter_set_common_pixel_formats(AVFilterContext *ctx, AVFilterFormats *formats)
+{
+    set_common_formats(ctx, formats, AVMEDIA_TYPE_VIDEO,
+                       offsetof(AVFilterLink, in_formats),
+                       offsetof(AVFilterLink, out_formats));
+}
+
+void avfilter_set_common_sample_formats(AVFilterContext *ctx, AVFilterFormats *formats)
+{
+    set_common_formats(ctx, formats, AVMEDIA_TYPE_AUDIO,
+                       offsetof(AVFilterLink, in_formats),
+                       offsetof(AVFilterLink, out_formats));
+}
+
+void avfilter_set_common_channel_layouts(AVFilterContext *ctx, AVFilterFormats *formats)
+{
+    set_common_formats(ctx, formats, AVMEDIA_TYPE_AUDIO,
+                       offsetof(AVFilterLink, in_chlayouts),
+                       offsetof(AVFilterLink, out_chlayouts));
 }
 
 int avfilter_default_query_formats(AVFilterContext *ctx)
 {
-    enum AVMediaType type = ctx->inputs  && ctx->inputs [0] ? ctx->inputs [0]->type :
-                            ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
-                            AVMEDIA_TYPE_VIDEO;
+    avfilter_set_common_pixel_formats(ctx, avfilter_all_formats(AVMEDIA_TYPE_VIDEO));
+    avfilter_set_common_sample_formats(ctx, avfilter_all_formats(AVMEDIA_TYPE_AUDIO));
+    avfilter_set_common_channel_layouts(ctx, avfilter_all_channel_layouts());
 
-    avfilter_set_common_formats(ctx, avfilter_all_formats(type));
     return 0;
 }
 

+ 22 - 0
libavfilter/formats.c

@@ -20,6 +20,7 @@
  */
 
 #include "libavutil/pixdesc.h"
+#include "libavutil/audioconvert.h"
 #include "avfilter.h"
 
 /**
@@ -139,6 +140,27 @@ AVFilterFormats *avfilter_all_formats(enum AVMediaType type)
     return ret;
 }
 
+AVFilterFormats *avfilter_all_channel_layouts(void)
+{
+    static 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_format64_list(chlayouts);
+}
+
 void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
 {
     *ref = f;

+ 1 - 1
libavfilter/vf_blackframe.c

@@ -44,7 +44,7 @@ static int query_formats(AVFilterContext *ctx)
         PIX_FMT_NONE
     };
 
-    avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+    avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts));
     return 0;
 }
 

+ 1 - 1
libavfilter/vf_crop.c

@@ -104,7 +104,7 @@ static int query_formats(AVFilterContext *ctx)
         PIX_FMT_NONE
     };
 
-    avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+    avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts));
 
     return 0;
 }

+ 1 - 1
libavfilter/vf_cropdetect.c

@@ -46,7 +46,7 @@ static int query_formats(AVFilterContext *ctx)
         PIX_FMT_NONE
     };
 
-    avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+    avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts));
     return 0;
 }
 

Some files were not shown because too many files changed in this diff