FFmpeg
graph2dot.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008-2010 Stefano Sabatini
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "config.h"
22 #if HAVE_UNISTD_H
23 #include <unistd.h> /* getopt */
24 #endif
25 #include <stdio.h>
26 #include <string.h>
27 
29 #include "libavutil/mem.h"
30 #include "libavutil/pixdesc.h"
31 #include "libavfilter/avfilter.h"
32 
33 #if !HAVE_GETOPT
34 #include "compat/getopt.c"
35 #endif
36 
37 static void usage(void)
38 {
39  printf("Convert a libavfilter graph to a dot file.\n");
40  printf("Usage: graph2dot [OPTIONS]\n");
41  printf("\n"
42  "Options:\n"
43  "-i INFILE set INFILE as input file, stdin if omitted\n"
44  "-o OUTFILE set OUTFILE as output file, stdout if omitted\n"
45  "-h print this help\n");
46 }
47 
48 struct line {
49  char data[256];
50  struct line *next;
51 };
52 
53 static void print_digraph(FILE *outfile, AVFilterGraph *graph)
54 {
55  int i, j;
56 
57  fprintf(outfile, "digraph G {\n");
58  fprintf(outfile, "node [shape=box]\n");
59  fprintf(outfile, "rankdir=LR\n");
60 
61  for (i = 0; i < graph->nb_filters; i++) {
62  char filter_ctx_label[128];
63  const AVFilterContext *filter_ctx = graph->filters[i];
64 
65  snprintf(filter_ctx_label, sizeof(filter_ctx_label), "%s\\n(%s)",
66  filter_ctx->name,
67  filter_ctx->filter->name);
68 
69  for (j = 0; j < filter_ctx->nb_outputs; j++) {
70  AVFilterLink *link = filter_ctx->outputs[j];
71  if (link) {
72  char dst_filter_ctx_label[128];
73  const AVFilterContext *dst_filter_ctx = link->dst;
74 
75  snprintf(dst_filter_ctx_label, sizeof(dst_filter_ctx_label),
76  "%s\\n(%s)",
77  dst_filter_ctx->name,
78  dst_filter_ctx->filter->name);
79 
80  fprintf(outfile, "\"%s\" -> \"%s\" [ label= \"inpad:%s -> outpad:%s\\n",
81  filter_ctx_label, dst_filter_ctx_label,
82  avfilter_pad_get_name(link->srcpad, 0),
83  avfilter_pad_get_name(link->dstpad, 0));
84 
85  if (link->type == AVMEDIA_TYPE_VIDEO) {
87  fprintf(outfile,
88  "fmt:%s w:%d h:%d tb:%d/%d",
89  desc->name,
90  link->w, link->h,
91  link->time_base.num, link->time_base.den);
92  } else if (link->type == AVMEDIA_TYPE_AUDIO) {
93  char buf[255];
94  av_get_channel_layout_string(buf, sizeof(buf), -1,
95  link->channel_layout);
96  fprintf(outfile,
97  "fmt:%s sr:%d cl:%s tb:%d/%d",
99  link->sample_rate, buf,
100  link->time_base.num, link->time_base.den);
101  }
102  fprintf(outfile, "\" ];\n");
103  }
104  }
105  }
106  fprintf(outfile, "}\n");
107 }
108 
109 int main(int argc, char **argv)
110 {
111  const char *outfilename = NULL;
112  const char *infilename = NULL;
113  FILE *outfile = NULL;
114  FILE *infile = NULL;
115  char *graph_string = NULL;
116  AVFilterGraph *graph = av_mallocz(sizeof(AVFilterGraph));
117  char c;
118 
120 
121  while ((c = getopt(argc, argv, "hi:o:")) != -1) {
122  switch (c) {
123  case 'h':
124  usage();
125  return 0;
126  case 'i':
127  infilename = optarg;
128  break;
129  case 'o':
130  outfilename = optarg;
131  break;
132  case '?':
133  return 1;
134  }
135  }
136 
137  if (!infilename || !strcmp(infilename, "-"))
138  infilename = "/dev/stdin";
139  infile = fopen(infilename, "r");
140  if (!infile) {
141  fprintf(stderr, "Failed to open input file '%s': %s\n",
142  infilename, strerror(errno));
143  return 1;
144  }
145 
146  if (!outfilename || !strcmp(outfilename, "-"))
147  outfilename = "/dev/stdout";
148  outfile = fopen(outfilename, "w");
149  if (!outfile) {
150  fprintf(stderr, "Failed to open output file '%s': %s\n",
151  outfilename, strerror(errno));
152  return 1;
153  }
154 
155  /* read from infile and put it in a buffer */
156  {
157  int64_t count = 0;
158  struct line *line, *last_line, *first_line;
159  char *p;
160  last_line = first_line = av_malloc(sizeof(struct line));
161  if (!last_line) {
162  fprintf(stderr, "Memory allocation failure\n");
163  return 1;
164  }
165 
166  while (fgets(last_line->data, sizeof(last_line->data), infile)) {
167  struct line *new_line = av_malloc(sizeof(struct line));
168  if (!new_line) {
169  fprintf(stderr, "Memory allocation failure\n");
170  return 1;
171  }
172  count += strlen(last_line->data);
173  last_line->next = new_line;
174  last_line = new_line;
175  }
176  last_line->next = NULL;
177 
178  graph_string = av_malloc(count + 1);
179  if (!graph_string) {
180  fprintf(stderr, "Memory allocation failure\n");
181  return 1;
182  }
183  p = graph_string;
184  for (line = first_line; line->next; line = line->next) {
185  size_t l = strlen(line->data);
186  memcpy(p, line->data, l);
187  p += l;
188  }
189  *p = '\0';
190  }
191 
192  if (avfilter_graph_parse(graph, graph_string, NULL, NULL, NULL) < 0) {
193  fprintf(stderr, "Failed to parse the graph description\n");
194  return 1;
195  }
196 
197  if (avfilter_graph_config(graph, NULL) < 0)
198  return 1;
199 
200  print_digraph(outfile, graph);
201  fflush(outfile);
202 
203  return 0;
204 }
AVFilterContext ** filters
Definition: avfilter.h:842
#define NULL
Definition: coverity.c:32
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
Main libavfilter public API header.
Memory handling functions.
const char * desc
Definition: nvenc.c:68
void av_log_set_level(int level)
Set the log level.
Definition: log.c:385
int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
Check validity and configure all the links and formats in the graph.
int num
Numerator.
Definition: rational.h:59
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
struct line * next
Definition: graph2dot.c:50
char data[256]
Definition: graph2dot.c:49
char * name
name of this filter instance
Definition: avfilter.h:343
#define av_malloc(s)
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
static void print_digraph(FILE *outfile, AVFilterGraph *graph)
Definition: graph2dot.c:53
int main(int argc, char **argv)
Definition: graph2dot.c:109
const char * name
Definition: pixdesc.h:82
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
unsigned nb_outputs
number of output pads
Definition: avfilter.h:351
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
Definition: graph2dot.c:48
static FilteringContext * filter_ctx
Definition: transcoding.c:45
const char * av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
Return the name of sample_fmt, or NULL if sample_fmt is not recognized.
Definition: samplefmt.c:49
GLsizei count
Definition: opengl_enc.c:108
static void usage(void)
Definition: graph2dot.c:37
audio channel layout utility functions
void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout)
Return a description of a channel layout.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
static int getopt(int argc, char *argv[], char *opts)
Definition: getopt.c:41
void * buf
Definition: avisynth_c.h:766
int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, AVFilterInOut *inputs, AVFilterInOut *outputs, void *log_ctx)
Add a graph described by a string to a graph.
Definition: graphparser.c:475
const char * name
Filter name.
Definition: avfilter.h:148
unsigned nb_filters
Definition: avfilter.h:843
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a link
#define snprintf
Definition: snprintf.h:34
const char * avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx)
Get the name of an AVFilterPad.
Definition: avfilter.c:1034
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
The official guide to swscale for confused that consecutive non overlapping rectangles of slice_bottom special converter These generally are unscaled converters of common like for each output line the vertical scaler pulls lines from a ring buffer When the ring buffer does not contain the wanted line
Definition: swscale.txt:33
int den
Denominator.
Definition: rational.h:60
static char * optarg
Definition: getopt.c:39
printf("static const uint8_t my_array[100] = {\n")
An instance of a filter.
Definition: avfilter.h:338
const AVFilter * filter
the AVFilter of which this is an instance
Definition: avfilter.h:341
FILE * outfile
Definition: audiogen.c:96