Libav
|
00001 /* 00002 * Copyright (c) 2008-2010 Stefano Sabatini 00003 * 00004 * This file is part of FFmpeg. 00005 * 00006 * FFmpeg is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * FFmpeg is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with FFmpeg; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 #include <unistd.h> /* getopt */ 00022 00023 #undef HAVE_AV_CONFIG_H 00024 #include "libavutil/pixdesc.h" 00025 #include "libavfilter/graphparser.h" 00026 00027 static void usage(void) 00028 { 00029 printf("Convert a libavfilter graph to a dot file\n"); 00030 printf("Usage: graph2dot [OPTIONS]\n"); 00031 printf("\n" 00032 "Options:\n" 00033 "-i INFILE set INFILE as input file, stdin if omitted\n" 00034 "-o OUTFILE set OUTFILE as output file, stdout if omitted\n" 00035 "-h print this help\n"); 00036 } 00037 00038 struct line { 00039 char data[256]; 00040 struct line *next; 00041 }; 00042 00043 static void print_digraph(FILE *outfile, AVFilterGraph *graph) 00044 { 00045 int i, j; 00046 00047 fprintf(outfile, "digraph G {\n"); 00048 fprintf(outfile, "node [shape=box]\n"); 00049 fprintf(outfile, "rankdir=LR\n"); 00050 00051 for (i = 0; i < graph->filter_count; i++) { 00052 char filter_ctx_label[128]; 00053 const AVFilterContext *filter_ctx = graph->filters[i]; 00054 00055 snprintf(filter_ctx_label, sizeof(filter_ctx_label), "%s (%s)", 00056 filter_ctx->name, 00057 filter_ctx->filter->name); 00058 00059 for (j = 0; j < filter_ctx->output_count; j++) { 00060 AVFilterLink *link = filter_ctx->outputs[j]; 00061 if (link) { 00062 char dst_filter_ctx_label[128]; 00063 const AVFilterContext *dst_filter_ctx = link->dst; 00064 00065 snprintf(dst_filter_ctx_label, sizeof(dst_filter_ctx_label), "%s (%s)", 00066 dst_filter_ctx->name, 00067 dst_filter_ctx->filter->name); 00068 00069 fprintf(outfile, "\"%s\" -> \"%s\"", filter_ctx_label, dst_filter_ctx_label); 00070 fprintf(outfile, " [ label= \"fmt:%s w:%d h:%d\"];\n", 00071 av_pix_fmt_descriptors[link->format].name, link->w, link->h); 00072 } 00073 } 00074 } 00075 fprintf(outfile, "}\n"); 00076 } 00077 00078 int main(int argc, char **argv) 00079 { 00080 const char *outfilename = NULL; 00081 const char *infilename = NULL; 00082 FILE *outfile = NULL; 00083 FILE *infile = NULL; 00084 char *graph_string = NULL; 00085 AVFilterGraph *graph = av_mallocz(sizeof(AVFilterGraph)); 00086 char c; 00087 00088 av_log_set_level(AV_LOG_DEBUG); 00089 00090 while ((c = getopt(argc, argv, "hi:o:")) != -1) { 00091 switch(c) { 00092 case 'h': 00093 usage(); 00094 return 0; 00095 case 'i': 00096 infilename = optarg; 00097 break; 00098 case 'o': 00099 outfilename = optarg; 00100 break; 00101 case '?': 00102 return 1; 00103 } 00104 } 00105 00106 if (!infilename || !strcmp(infilename, "-")) 00107 infilename = "/dev/stdin"; 00108 infile = fopen(infilename, "r"); 00109 if (!infile) { 00110 fprintf(stderr, "Impossible to open input file '%s': %s\n", infilename, strerror(errno)); 00111 return 1; 00112 } 00113 00114 if (!outfilename || !strcmp(outfilename, "-")) 00115 outfilename = "/dev/stdout"; 00116 outfile = fopen(outfilename, "w"); 00117 if (!outfile) { 00118 fprintf(stderr, "Impossible to open output file '%s': %s\n", outfilename, strerror(errno)); 00119 return 1; 00120 } 00121 00122 /* read from infile and put it in a buffer */ 00123 { 00124 unsigned int count = 0; 00125 struct line *line, *last_line, *first_line; 00126 char *p; 00127 last_line = first_line = av_malloc(sizeof(struct line)); 00128 00129 while (fgets(last_line->data, sizeof(last_line->data), infile)) { 00130 struct line *new_line = av_malloc(sizeof(struct line)); 00131 count += strlen(last_line->data); 00132 last_line->next = new_line; 00133 last_line = new_line; 00134 } 00135 last_line->next = NULL; 00136 00137 graph_string = av_malloc(count + 1); 00138 p = graph_string; 00139 for (line = first_line; line->next; line = line->next) { 00140 unsigned int l = strlen(line->data); 00141 memcpy(p, line->data, l); 00142 p += l; 00143 } 00144 *p = '\0'; 00145 } 00146 00147 avfilter_register_all(); 00148 00149 if (avfilter_graph_parse(graph, graph_string, NULL, NULL, NULL) < 0) { 00150 fprintf(stderr, "Impossible to parse the graph description\n"); 00151 return 1; 00152 } 00153 00154 if (avfilter_graph_check_validity(graph, NULL) || 00155 avfilter_graph_config_formats(graph, NULL) || 00156 avfilter_graph_config_links (graph, NULL)) 00157 return 1; 00158 00159 print_digraph(outfile, graph); 00160 fflush(outfile); 00161 00162 return 0; 00163 }