[PATCH] Implement ff_avfilter_graph_adjust() and vflipfix auto-insertion.

Stefano Sabatini stefano.sabatini-lala
Sat Nov 6 21:52:55 CET 2010


---
 libavfilter/avfiltergraph.c |   51 +++++++++++++++++++++++++++++++++++++++++++
 libavfilter/internal.h      |    8 ++++++
 2 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index b138e69..fff2b4d 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -83,6 +83,55 @@ int ff_avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
     return 0;
 }
 
+int ff_avfilter_graph_adjust(AVFilterGraph *graph, AVClass *log_ctx)
+{
+    AVFilterContext *filtctx;
+    int i, ret, vflipfix_idx = 0;
+
+    for (i = 0; i < graph->filter_count; i++) {
+        filtctx = graph->filters[i];
+
+        if (!filtctx->filter->capabilities & AVFILTER_CAP_SUPPORT_NEG_LINESIZES) {
+            int i;
+
+            for (i = 0; i < filtctx->output_count; i++) {
+                AVFilterContext *vflipfix_ctx = NULL;
+                AVFilter *vflipfix;
+                char inst_name[128];
+                AVFilterLink *outlink = filtctx->outputs[i];
+
+                if (outlink->type != AVMEDIA_TYPE_VIDEO)
+                    continue;
+
+                vflipfix = avfilter_get_by_name("vflipfix");
+                if (!vflipfix) {
+                    av_log(log_ctx, AV_LOG_ERROR,
+                           "No vflipfix filter registered\n");
+                    return AVERROR(EINVAL);
+                }
+
+                snprintf(inst_name, sizeof(inst_name), "Auto-inserted vflipfix filter %d", vflipfix_idx++);
+                ret = avfilter_open(&vflipfix_ctx, vflipfix, inst_name);
+                if (!vflipfix_ctx) {
+                    av_log(log_ctx, AV_LOG_ERROR, "Error creating filter vflipfix\n");
+                    return ret;
+                }
+                if ((ret = avfilter_graph_add_filter(graph, vflipfix_ctx)) < 0) {
+                    avfilter_free(vflipfix_ctx);
+                    return ret;
+                }
+
+                if ((ret = avfilter_insert_filter(outlink, vflipfix_ctx, 0, 0)) < 0) {
+                    avfilter_free(vflipfix_ctx);
+                    return ret;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
 int ff_avfilter_graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
 {
     AVFilterContext *filt;
@@ -212,6 +261,8 @@ int avfilter_graph_config(AVFilterGraph *graphctx, AVClass *log_ctx)
 {
     int ret;
 
+    if ((ret = ff_avfilter_graph_adjust(graphctx, log_ctx)))
+        return ret;
     if ((ret = ff_avfilter_graph_check_validity(graphctx, log_ctx)))
         return ret;
     if ((ret = ff_avfilter_graph_config_formats(graphctx, log_ctx)))
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index 8f352ef..dd5c351 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -36,6 +36,14 @@ void ff_dprintf_link(void *ctx, AVFilterLink *link, int end);
 #define FF_DPRINTF_START(ctx, func) dprintf(NULL, "%-16s: ", #func)
 
 /**
+ * Adjust the filtergraph. This is required for example for adding the
+ * required auto-inserteed filters which may be required.
+ *
+ * @return 0 in case of success, a negative value otherwise
+ */
+int ff_avfilter_graph_adjust(AVFilterGraph *graph, AVClass *log_ctx);
+
+/**
  * Check for the validity of graph.
  *
  * A graph is considered valid if all its input and output pads are
-- 
1.7.1


--lrZ03NoBR/3+SXJZ--



More information about the ffmpeg-devel mailing list