Avoid searching by instance name when it is not necessary
authorVitor Sessak <vitor1001@gmail.com>
Sat, 24 May 2008 20:38:25 +0000 (20:38 +0000)
committerVitor Sessak <vitor1001@gmail.com>
Sat, 24 May 2008 20:38:25 +0000 (20:38 +0000)
Commited in SoC by Vitor Sessak on 2008-04-06 18:00:58

Originally committed as revision 13289 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavfilter/graphparser.c

index d54f97d..be61c27 100644 (file)
@@ -41,8 +41,8 @@ static const AVClass filter_parser_class = {
 
 static const AVClass *log_ctx = &filter_parser_class;
 
-static int create_filter(AVFilterGraph *ctx, int index, char *name,
-                         char *args)
+static AVFilterContext *create_filter(AVFilterGraph *ctx, int index,
+                                      char *name, char *args)
 {
     AVFilterContext *filt;
 
@@ -54,46 +54,34 @@ static int create_filter(AVFilterGraph *ctx, int index, char *name,
     if(!(filterdef = avfilter_get_by_name(name))) {
         av_log(&log_ctx, AV_LOG_ERROR,
                "no such filter: '%s'\n", name);
-        return -1;
+        return NULL;
     }
 
     if(!(filt = avfilter_open(filterdef, tmp))) {
         av_log(&log_ctx, AV_LOG_ERROR,
                "error creating filter '%s'\n", name);
-        return -1;
+        return NULL;
     }
 
     if (avfilter_graph_add_filter(ctx, filt) < 0)
-        return -1;
+        return NULL;
 
     if(avfilter_init_filter(filt, args, NULL)) {
         av_log(&log_ctx, AV_LOG_ERROR,
                "error initializing filter '%s' with args '%s'\n", name, args);
-        return -1;
+        return NULL;
     }
 
-    return 0;
+    return filt;
 }
 
-static int link_filter(AVFilterGraph *ctx, int src, int srcpad,
-                       int dst, int dstpad)
+static int link_filter(AVFilterContext *src, int srcpad,
+                       AVFilterContext *dst, int dstpad)
 {
-    AVFilterContext *filt, *filtb;
-
-    char tmp[20];
-
-    snprintf(tmp, 20, "%d", src);
-    if(!(filt = avfilter_graph_get_filter(ctx, tmp))) {
-        av_log(&log_ctx, AV_LOG_ERROR, "link source does not exist in graph\n");
-        return -1;
-    }
-    snprintf(tmp, 20, "%d", dst);
-    if(!(filtb = avfilter_graph_get_filter(ctx, tmp))) {
-        av_log(&log_ctx, AV_LOG_ERROR, "link destination does not exist in graph\n");
-        return -1;
-    }
-    if(avfilter_link(filt, srcpad, filtb, dstpad)) {
-        av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
+    if(avfilter_link(src, srcpad, dst, dstpad)) {
+        av_log(&log_ctx, AV_LOG_ERROR,
+               "cannot create the link %s:%d -> %s:%d\n",
+               src->filter->name, srcpad, dst->filter->name, dstpad);
         return -1;
     }
 
@@ -201,7 +189,7 @@ static void parse_link_name(const char **buf, char **name)
  * @arg ars  a pointer (that need to be free'd after use) to the args of the
  *           filter
  */
-static int parse_filter(const char **buf, AVFilterGraph *graph, int index)
+static AVFilterContext *parse_filter(const char **buf, AVFilterGraph *graph, int index)
 {
     char *name, *opts;
     name = consume_string(buf);
@@ -227,7 +215,7 @@ enum LinkType {
 typedef struct AVFilterInOut {
     enum LinkType type;
     char *name;
-    int instance;
+    AVFilterContext *instance;
     int pad_idx;
 
     struct AVFilterInOut *next;
@@ -247,7 +235,7 @@ static void free_inout(AVFilterInOut *head)
  * Parse "(a1)(link2) ... (etc)"
  */
 static int parse_inouts(const char **buf, AVFilterInOut **inout, int firstpad,
-                        enum LinkType type, int instance)
+                        enum LinkType type, AVFilterContext *instance)
 {
     int pad = firstpad;
     while (**buf == '(') {
@@ -262,6 +250,16 @@ static int parse_inouts(const char **buf, AVFilterInOut **inout, int firstpad,
     return pad;
 }
 
+static const char *skip_inouts(const char *buf)
+{
+    while (*buf == '(') {
+        buf += strcspn(buf, ")");
+        buf++;
+    }
+    return buf;
+}
+
+
 /**
  * Parse a string describing a filter graph.
  */
@@ -275,70 +273,61 @@ int avfilter_graph_parse_chain(AVFilterGraph *graph, const char *filters, AVFilt
     int pad = 0;
     int has_out = 0;
 
-    char tmp[20];
-    AVFilterContext *filt;
+    AVFilterContext *last_filt = NULL;
 
     consume_whitespace(&filters);
 
     do {
+        AVFilterContext *filter;
         int oldpad = pad;
+        const char *inouts = filters;
 
-        pad = parse_inouts(&filters, &inout, chr == ',', LinkTypeIn, index);
+        // We need to parse the inputs of the filter after we create it, so
+        // skip it by now
+        filters = skip_inouts(filters);
 
-        if (parse_filter(&filters, graph, index) < 0)
+        if (!(filter = parse_filter(&filters, graph, index)))
             goto fail;
 
+        pad = parse_inouts(&inouts, &inout, chr == ',', LinkTypeIn, filter);
+
         // If the first filter has an input and none was given, it is
         // implicitly the input of the whole graph.
         if (pad == 0 && graph->filters[graph->filter_count-1]->input_count == 1) {
-            snprintf(tmp, 20, "%d", index);
-            if(!(filt = avfilter_graph_get_filter(graph, tmp))) {
-                av_log(&log_ctx, AV_LOG_ERROR, "filter owning exported pad does not exist\n");
-                goto fail;
-            }
-            if(avfilter_link(in, inpad, filt, 0)) {
+            if(avfilter_link(in, inpad, filter, 0)) {
                 av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
                 goto fail;
             }
         }
 
         if(chr == ',') {
-            if (link_filter(graph, index-1, oldpad, index, 0) < 0)
+            if (link_filter(last_filt, oldpad, filter, 0) < 0)
                 goto fail;
 
         }
-        pad = parse_inouts(&filters, &inout, 0, LinkTypeOut, index);
+        pad = parse_inouts(&filters, &inout, 0, LinkTypeOut, filter);
         chr = *filters++;
         index++;
+        last_filt = filter;
     } while (chr == ',' || chr == ';');
 
     head = inout;
     for (; inout != NULL; inout = inout->next) {
-        if (inout->instance == -1)
+        if (inout->instance == NULL)
             continue; // Already processed
 
         if (!strcmp(inout->name, "in")) {
-            snprintf(tmp, 20, "%d", inout->instance);
-            if(!(filt = avfilter_graph_get_filter(graph, tmp))) {
-                av_log(&log_ctx, AV_LOG_ERROR, "filter owning exported pad does not exist\n");
-                goto fail;
-            }
-            if(avfilter_link(in, inpad, filt, inout->pad_idx)) {
+            if(avfilter_link(in, inpad, inout->instance, inout->pad_idx)) {
                 av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
                 goto fail;
             }
         } else if (!strcmp(inout->name, "out")) {
             has_out = 1;
-            snprintf(tmp, 20, "%d", inout->instance);
-            if(!(filt = avfilter_graph_get_filter(graph, tmp))) {
-                av_log(&log_ctx, AV_LOG_ERROR, "filter owning exported pad does not exist\n");
-                goto fail;
-            }
 
-            if(avfilter_link(filt, inout->pad_idx, out, outpad)) {
+            if(avfilter_link(inout->instance, inout->pad_idx, out, outpad)) {
                 av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
                 goto fail;
-        }
+            }
 
         } else {
             AVFilterInOut *p, *src, *dst;
@@ -363,24 +352,18 @@ int avfilter_graph_parse_chain(AVFilterGraph *graph, const char *filters, AVFilt
                 goto fail;
             }
 
-            if (link_filter(graph, src->instance, src->pad_idx, dst->instance, dst->pad_idx) < 0)
+            if (link_filter(src->instance, src->pad_idx, dst->instance, dst->pad_idx) < 0)
                 goto fail;
 
-            src->instance = -1;
-            dst->instance = -1;
+            src->instance = NULL;
+            dst->instance = NULL;
         }
     }
 
     free_inout(head);
 
     if (!has_out) {
-        snprintf(tmp, 20, "%d", index-1);
-        if(!(filt = avfilter_graph_get_filter(graph, tmp))) {
-            av_log(&log_ctx, AV_LOG_ERROR, "filter owning exported pad does not exist\n");
-            goto fail;
-        }
-
-        if(avfilter_link(filt, pad, out, outpad)) {
+        if(avfilter_link(last_filt, pad, out, outpad)) {
             av_log(&log_ctx, AV_LOG_ERROR, "cannot create link between source and destination filters\n");
             goto fail;
         }