[libav-commits] avfiltergraph: try to reduce format conversions in filters.

Anton Khirnov git at libav.org
Sun Apr 1 09:06:15 CEST 2012


Module: libav
Branch: master
Commit: 63736fe48c30c5db313c3a25d1462ad31b2a1671

Author:    Anton Khirnov <anton at khirnov.net>
Committer: Anton Khirnov <anton at khirnov.net>
Date:      Fri Mar 23 15:14:40 2012 +0100

avfiltergraph: try to reduce format conversions in filters.

Current code, with a filterchain such as
(input - yuv411) -> (scale - any) -> (sink - any)
will result in yuv420 being chosen for the second link, which is clearly
not right.

This commit attempts to improve in the following way:
repeat until convergence:
  loop over all filters
    find input link with exactly one format
    force this format on all output links of the same type (if possible)

---

 libavfilter/avfiltergraph.c |   48 ++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 47 insertions(+), 1 deletions(-)

diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 9b73cc9..04d9027 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -214,6 +214,49 @@ static void pick_format(AVFilterLink *link)
     avfilter_formats_unref(&link->out_formats);
 }
 
+static int reduce_formats_on_filter(AVFilterContext *filter)
+{
+    int i, j, k, ret = 0;
+
+    for (i = 0; i < filter->input_count; i++) {
+        AVFilterLink *link = filter->inputs[i];
+        int         format = link->out_formats->formats[0];
+
+        if (link->out_formats->format_count != 1)
+            continue;
+
+        for (j = 0; j < filter->output_count; j++) {
+            AVFilterLink *out_link = filter->outputs[j];
+            AVFilterFormats  *fmts = out_link->in_formats;
+
+            if (link->type != out_link->type ||
+                out_link->in_formats->format_count == 1)
+                continue;
+
+            for (k = 0; k < out_link->in_formats->format_count; k++)
+                if (fmts->formats[k] == format) {
+                    fmts->formats[0]   = format;
+                    fmts->format_count = 1;
+                    ret = 1;
+                    break;
+                }
+        }
+    }
+    return ret;
+}
+
+static void reduce_formats(AVFilterGraph *graph)
+{
+    int i, reduced;
+
+    do {
+        reduced = 0;
+
+        for (i = 0; i < graph->filter_count; i++)
+            reduced |= reduce_formats_on_filter(graph->filters[i]);
+    } while (reduced);
+}
+
 static void pick_formats(AVFilterGraph *graph)
 {
     int i, j;
@@ -237,7 +280,10 @@ int ff_avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
         return ret;
 
     /* Once everything is merged, it's possible that we'll still have
-     * multiple valid media format choices. We pick the first one. */
+     * multiple valid media format choices. We try to minimize the amount
+     * of format conversion inside filters */
+    reduce_formats(graph);
+
     pick_formats(graph);
 
     return 0;



More information about the libav-commits mailing list