]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blobdiff - libavfilter/avfiltergraph.c
frsh: Export information about the last RTP contract and VRES
[frescor/ffmpeg.git] / libavfilter / avfiltergraph.c
index ef2a78cb443c64ec076ca74ce40028d3df405e7e..4b24508f5fc5f70e9cc4e6964bd0a58315ca51ee 100644 (file)
 #include "avfilter.h"
 #include "avfiltergraph.h"
 
-void avfilter_destroy_graph(AVFilterGraph *graph)
+void avfilter_graph_destroy(AVFilterGraph *graph)
 {
     for(; graph->filter_count > 0; graph->filter_count --)
         avfilter_destroy(graph->filters[graph->filter_count - 1]);
+    av_freep(&graph->scale_sws_opts);
     av_freep(&graph->filters);
 }
 
-void avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
+int avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
 {
     graph->filters = av_realloc(graph->filters,
                                 sizeof(AVFilterContext*) * ++graph->filter_count);
+
+    if (!graph->filters)
+        return -1;
+
     graph->filters[graph->filter_count - 1] = filter;
+
+    return 0;
+}
+
+int avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
+{
+    AVFilterContext *filt;
+    int i, j;
+
+    for (i=0; i < graph->filter_count; i++) {
+        filt = graph->filters[i];
+
+        for (j = 0; j < filt->input_count; j++) {
+            if (!filt->inputs[j] || !filt->inputs[j]->src) {
+                av_log(log_ctx, AV_LOG_ERROR,
+                       "Input pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any source\n",
+                       filt->input_pads[j].name, filt->name, filt->filter->name);
+                return -1;
+            }
+        }
+
+        for (j = 0; j < filt->output_count; j++) {
+            if (!filt->outputs[j] || !filt->outputs[j]->dst) {
+                av_log(log_ctx, AV_LOG_ERROR,
+                       "Output pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any destination\n",
+                       filt->output_pads[j].name, filt->name, filt->filter->name);
+                return -1;
+            }
+        }
+    }
+
+    return 0;
 }
 
 AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name)
 {
     int i;
 
-    if(!name)
-        return NULL;
-
     for(i = 0; i < graph->filter_count; i ++)
         if(graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
             return graph->filters[i];
@@ -57,6 +91,8 @@ AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name)
 static int query_formats(AVFilterGraph *graph)
 {
     int i, j;
+    int scaler_count = 0;
+    char inst_name[30];
 
     /* ask all the sub-filters for their supported colorspaces */
     for(i = 0; i < graph->filter_count; i ++) {
@@ -71,25 +107,28 @@ static int query_formats(AVFilterGraph *graph)
         AVFilterContext *filter = graph->filters[i];
 
         for(j = 0; j < filter->input_count; j ++) {
-            AVFilterLink *link;
-            if(!(link = filter->inputs[j]))
-                continue;
-            if(link->in_formats != link->out_formats) {
+            AVFilterLink *link = filter->inputs[j];
+            if(link && link->in_formats != link->out_formats) {
                 if(!avfilter_merge_formats(link->in_formats,
                                            link->out_formats)) {
-                    /* couldn't merge format lists. auto-insert scale filter */
                     AVFilterContext *scale;
-
-                    if(!(scale =
-                         avfilter_open(avfilter_get_by_name("scale"), NULL)))
-                        return -1;
-                    if(scale->filter->init(scale, NULL, NULL) ||
-                       avfilter_insert_filter(link, scale, 0, 0)) {
+                    char scale_args[256];
+                    /* couldn't merge format lists. auto-insert scale filter */
+                    snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
+                             scaler_count);
+                    scale =
+                        avfilter_open(avfilter_get_by_name("scale"),inst_name);
+
+                    snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts);
+                    if(!scale || scale->filter->init(scale, scale_args, NULL) ||
+                                 avfilter_insert_filter(link, scale, 0, 0)) {
                         avfilter_destroy(scale);
                         return -1;
                     }
 
-                    avfilter_graph_add_filter(graph, scale);
+                    if (avfilter_graph_add_filter(graph, scale) < 0)
+                        return -1;
+
                     scale->filter->query_formats(scale);
                     if(!avfilter_merge_formats(scale-> inputs[0]->in_formats,
                                                scale-> inputs[0]->out_formats)||