From 63736fe48c30c5db313c3a25d1462ad31b2a1671 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 23 Mar 2012 15:14:40 +0100 Subject: 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 file changed, 47 insertions(+), 1 deletion(-) (limited to 'libavfilter/avfiltergraph.c') diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 9b73cc95ab..04d9027527 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; -- cgit v1.2.3