[FFmpeg-devel] [PATCH] avfilter/avfiltergraph: auto insert idet filters in case of supported formats after video sources

Michael Niedermayer michaelni at gmx.at
Mon Jan 19 06:09:29 CET 2015


This should allow changing the default of scale filters to autodetect interlacing

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
 libavfilter/avfiltergraph.c |   80 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index a859ecb..679b23f 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -1089,6 +1089,84 @@ static int pick_formats(AVFilterGraph *graph)
     return 0;
 }
 
+static int inject_idets(AVFilterGraph *graph, AVClass *log_ctx)
+{
+    int i, j, k;
+    int idet_count = 0;
+    int ret;
+
+    for (i = 0; i < graph->nb_filters; i++) {
+        AVFilterContext *filter = graph->filters[i];
+        if (filter->nb_inputs || !filter->nb_outputs)
+            continue;
+
+        for (j = 0; j < filter->nb_outputs; j++) {
+            AVFilterLink *link = filter->outputs[j];
+            if (link->type != AVMEDIA_TYPE_VIDEO)
+                continue;
+            if (link->in_formats) {
+                int progressive = 1;
+
+                for (k = 0; k < link->in_formats->nb_formats; k++) {
+                    switch (link->in_formats->formats[k]) {
+                    case AV_PIX_FMT_YUV420P:
+                    case AV_PIX_FMT_YUV422P:
+                    case AV_PIX_FMT_YUV444P:
+                        progressive = 0;
+                    }
+                }
+                if (!progressive) {
+                    AVFilterContext *detect;
+                    AVFilter *filter;
+                    AVFilterLink *inlink, *outlink;
+                    char scale_args[256];
+                    char inst_name[30];
+
+                    if (!(filter = avfilter_get_by_name("idet"))) {
+                        av_log(log_ctx, AV_LOG_ERROR, "'idet' filter "
+                               "not present, cannot perform interlace detection.\n");
+                        return AVERROR(EINVAL);
+                    }
+
+                    snprintf(inst_name, sizeof(inst_name), "auto-inserted idet %d",
+                             idet_count++);
+
+                    if ((ret = avfilter_graph_create_filter(&detect, filter,
+                                                            inst_name, "analyze_interlaced_flag=10"/*graph->idet_opts*/, NULL,
+                                                            graph)) < 0)
+                        return ret;
+
+
+                    if ((ret = avfilter_insert_filter(link, detect, 0, 0)) < 0)
+                        return ret;
+
+                    if ((ret = filter_query_formats(detect)) < 0)
+                        return ret;
+
+                    inlink  = detect->inputs[0];
+                    outlink = detect->outputs[0];
+                    av_assert0( inlink-> in_formats->refcount > 0);
+                    av_assert0( inlink->out_formats->refcount > 0);
+                    av_assert0(outlink-> in_formats->refcount > 0);
+                    av_assert0(outlink->out_formats->refcount > 0);
+                    if (!ff_merge_formats( inlink->in_formats,  inlink->out_formats,  inlink->type) ||
+                        !ff_merge_formats(outlink->in_formats, outlink->out_formats, outlink->type))
+                        ret = AVERROR(ENOSYS);
+
+                    if (ret < 0) {
+                        av_log(log_ctx, AV_LOG_ERROR,
+                            "Impossible to link in idet filter between "
+                            "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
+                        return ret;
+                    }
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
 /**
  * Configure the formats of all the links in the graph.
  */
@@ -1102,6 +1180,8 @@ static int graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
     if (ret < 0)
         return ret;
 
+    inject_idets(graph, log_ctx);
+
     /* Once everything is merged, it's possible that we'll still have
      * multiple valid media format choices. We try to minimize the amount
      * of format conversion inside filters */
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list