Allow code to pass data to filters it creates.
[ffmpeg.git] / libavfilter / avfiltergraph.c
index 5211c76..ac2fb00 100644 (file)
@@ -22,6 +22,7 @@
 #include <string.h>
 #include <stddef.h>
 
+#include "avstring.h"
 #include "avfilter.h"
 #include "avfiltergraph.h"
 
@@ -37,10 +38,8 @@ AVFilterGraph *avfilter_create_graph(void)
 
 static void destroy_graph_filters(AVFilterGraph *graph)
 {
-    unsigned i;
-
-    for(i = 0; i < graph->filter_count; i ++)
-        avfilter_destroy(graph->filters[i]);
+    for(; graph->filter_count > 0; graph->filter_count --)
+        avfilter_destroy(graph->filters[graph->filter_count - 1]);
     av_freep(&graph->filters);
 }
 
@@ -57,16 +56,17 @@ void avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
     graph->filters[graph->filter_count - 1] = filter;
 }
 
-static AVFilterContext *create_filter_with_args(char *filter)
+static AVFilterContext *create_filter_with_args(const char *filt, void *opaque)
 {
     AVFilterContext *ret;
+    char *filter = av_strdup(filt); /* copy - don't mangle the input string */
     char *name, *args;
 
     name = filter;
     if((args = strchr(filter, '='))) {
         /* ensure we at least have a name */
         if(args == filter)
-            return NULL;
+            goto fail;
 
         *args ++ = 0;
     }
@@ -75,25 +75,34 @@ static AVFilterContext *create_filter_with_args(char *filter)
            name, args ? args : "(none)");
 
     if((ret = avfilter_create_by_name(name, NULL))) {
-        if(avfilter_init_filter(ret, args)) {
+        if(avfilter_init_filter(ret, args, opaque)) {
             av_log(NULL, AV_LOG_ERROR, "error initializing filter!\n");
             avfilter_destroy(ret);
-            ret = NULL;
+            goto fail;
         }
     } else av_log(NULL, AV_LOG_ERROR, "error creating filter!\n");
 
     return ret;
+
+fail:
+    av_free(filter);
+    return NULL;
 }
 
 int avfilter_graph_load_chain(AVFilterGraph *graph,
-                              unsigned count, char **filter_list,
+                              unsigned count, char **filter_list, void **opaque,
                               AVFilterContext **first, AVFilterContext **last)
 {
     unsigned i;
     AVFilterContext *filters[2] = {NULL,NULL};
 
     for(i = 0; i < count; i ++) {
-        if(!(filters[1] = create_filter_with_args(filter_list[i])))
+        void *op;
+
+        if(opaque) op = opaque[i];
+        else       op = NULL;
+
+        if(!(filters[1] = create_filter_with_args(filter_list[i], op)))
             goto fail;
         if(i == 0) {
             if(first) *first = filters[1];
@@ -112,7 +121,8 @@ int avfilter_graph_load_chain(AVFilterGraph *graph,
 
 fail:
     destroy_graph_filters(graph);
-    *first = *last = NULL;
+    if(first) *first = NULL;
+    if(last)  *last  = NULL;
     return -1;
 }