[FFmpeg-devel] [PATCH] graph2dot tool

Benoit Fouet benoit.fouet
Fri Dec 26 23:20:12 CET 2008


Hi,

Stefano Sabatini wrote :
> Hi all,
>
> this neat tool should help to debug/understand avfilter graphs, if you
> find it useful we could include this in the tools dir.
>
> Usage example:
> $ echo "scale=100:100, crop=100:20:30:30, vflip, hflip" | graph2dot
> digraph G {
> "Parsed filter 0 (scale)" -> "Parsed filter 1 (crop)";
> "Parsed filter 1 (crop)" -> "Parsed filter 2 (vflip)";
> "Parsed filter 2 (vflip)" -> "Parsed filter 3 (hflip)";
> }
>
> To directly display the graph:
> $ echo "scale=100:100, crop=100:20:30:30, vflip, hflip" | graph2dot | dot -Tpng -o graph.png; and display graph.png
>
> Regards.
>   
> ------------------------------------------------------------------------
>
> const char *program_name = NULL;
>
>   

static

> static void usage()
> {
>     printf("Convert a libavfilter graph to a dot file\n");
>     printf("Usage: %s [ outfile ]\n", program_name);
> }
>
> typedef struct Line {
>     char data[128];
>     struct Line *next;
> } Line;
>
> int main(int argc, char **argv)
> {
>     const char *outfilename = NULL;
>     FILE *outfile = NULL;
>
>     program_name = argv[0];
>
>     if (argc < 2 || !strcmp(argv[1], "-"))
>         outfilename = "/dev/stdout";
>   

else
    outfilename = argv[1]
?

>     outfile = fopen(outfilename, "w");
>     if (!outfile) {
>         fprintf(stderr, "Impossible to open output file '%s': %s\n", argv[0], strerror(errno));
>   

s/argv[0]/outfilename/

>         return 1;
>     }
>
>     /* read from stdin and put it in a buffer */
>     unsigned int count = 0;
>     Line *line, *last_line, *first_line;
>   

this should be with the other declarations...

>     last_line = first_line = malloc(sizeof(Line));
>
>     while (fgets(last_line->data, sizeof(last_line->data), stdin)) {
>         count += strlen(last_line->data);
>         Line *new_line = malloc(sizeof(Line));
>   

those two lines should be swapped

>         last_line->next = new_line;
>         last_line = new_line;
>     }
>     last_line->next = NULL;
>
>     char *p, *graph_string = malloc(count + 1);
>   

this should also be moved up (the declarations)

>     p = graph_string;
>     for (line = first_line; line->next; line = line->next) {
>         unsigned int l = strlen(line->data);
>         memcpy(p, line->data, l);
>         p += l;
>     }
>     *p = '\0';
>
>     /* create a corresponding graph from the input buffer */
>     AVFilterGraph *graph = malloc (sizeof(AVFilterGraph));
>     AVFilterInOut *open_inputs, *open_outputs;
>   

ditto

>     open_inputs = open_outputs = NULL;
>
>     avfilter_register_all();
>
>     if (avfilter_parse_graph(graph, graph_string, open_inputs, open_outputs, NULL) < 0) {
>         fprintf(stderr, "Impossible to parse the graph description\n");
>         return 1;
>     }
>
>     /* convert the graph to a dot graph */
>     fprintf(outfile, "digraph G {\n");
>
>     int i, j;
>   

ditto

>     for (i = 0; i < graph->filter_count; i++) {
>         const AVFilterContext *filt_ctx = graph->filters[i];
>         char filt_ctx_id[128];
>         snprintf(filt_ctx_id, sizeof(filt_ctx_id), "%s (%s)",
>                  filt_ctx->name,
>                  filt_ctx->filter->name);
>
>         for (j = 0; j < filt_ctx->output_count; j++) {
>             if (filt_ctx->outputs[j]) {
>                 const AVFilterContext *dst_filt_ctx = filt_ctx->outputs[j]->dst;
>                 char dst_filt_ctx_id[128];
>                 snprintf(dst_filt_ctx_id, sizeof(dst_filt_ctx_id), "%s (%s)",
>                          dst_filt_ctx->name,
>                          dst_filt_ctx->filter->name);
>
>                 fprintf(outfile, "\"%s\" -> \"%s\"%s", filt_ctx_id, dst_filt_ctx_id,
>                         j < (filt_ctx->output_count - 1) ? "," : ";\n");
>             }
>         }
>     }
>
>     fprintf(outfile, "}\n");
>     fflush(outfile);
>     return 0;
> }
>   

cheers,

Ben





More information about the ffmpeg-devel mailing list