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,
92  } else if (link->type == AVMEDIA_TYPE_AUDIO) {
93  char buf[255];
94  av_channel_layout_describe(&link->ch_layout, buf, sizeof(buf));
95  fprintf(outfile,
96  "fmt:%s sr:%d cl:%s tb:%d/%d",
98  link->sample_rate, buf,
100  }
101  fprintf(outfile, "\" ];\n");
102  }
103  }
104  }
105  fprintf(outfile, "}\n");
106 }
107 
108 int main(int argc, char **argv)
109 {
110  const char *outfilename = NULL;
111  const char *infilename = NULL;
112  FILE *outfile = NULL;
113  FILE *infile = NULL;
114  char *graph_string = NULL;
115  AVFilterGraph *graph = NULL;
116  char c;
117 
119 
120  while ((c = getopt(argc, argv, "hi:o:")) != -1) {
121  switch (c) {
122  case 'h':
123  usage();
124  return 0;
125  case 'i':
126  infilename = optarg;
127  break;
128  case 'o':
129  outfilename = optarg;
130  break;
131  case '?':
132  return 1;
133  }
134  }
135 
136  if (!infilename || !strcmp(infilename, "-"))
137  infilename = "/dev/stdin";
138  infile = fopen(infilename, "r");
139  if (!infile) {
140  fprintf(stderr, "Failed to open input file '%s': %s\n",
141  infilename, strerror(errno));
142  return 1;
143  }
144 
145  if (!outfilename || !strcmp(outfilename, "-"))
146  outfilename = "/dev/stdout";
147  outfile = fopen(outfilename, "w");
148  if (!outfile) {
149  fprintf(stderr, "Failed to open output file '%s': %s\n",
150  outfilename, strerror(errno));
151  return 1;
152  }
153 
154  /* read from infile and put it in a buffer */
155  {
156  int64_t count = 0;
157  struct line *line, *last_line, *first_line;
158  char *p;
159  last_line = first_line = av_malloc(sizeof(struct line));
160  if (!last_line) {
161  fprintf(stderr, "Memory allocation failure\n");
162  return 1;
163  }
164 
165  while (fgets(last_line->data, sizeof(last_line->data), infile)) {
166  struct line *new_line = av_malloc(sizeof(struct line));
167  if (!new_line) {
168  fprintf(stderr, "Memory allocation failure\n");
169  return 1;
170  }
171  count += strlen(last_line->data);
172  last_line->next = new_line;
173  last_line = new_line;
174  }
175  last_line->next = NULL;
176 
177  graph_string = av_malloc(count + 1);
178  if (!graph_string) {
179  fprintf(stderr, "Memory allocation failure\n");
180  return 1;
181  }
182  p = graph_string;
183  for (line = first_line; line->next; line = line->next) {
184  size_t l = strlen(line->data);
185  memcpy(p, line->data, l);
186  p += l;
187  }
188  *p = '\0';
189  }
190 
191  graph = avfilter_graph_alloc();
192  if (!graph) {
193  fprintf(stderr, "Memory allocation failure\n");
194  return 1;
195  }
196 
197  if (avfilter_graph_parse(graph, graph_string, NULL, NULL, NULL) < 0) {
198  fprintf(stderr, "Failed to parse the graph description\n");
199  return 1;
200  }
201 
202  if (avfilter_graph_config(graph, NULL) < 0)
203  return 1;
204 
205  print_digraph(outfile, graph);
206  fflush(outfile);
207 
208  return 0;
209 }
avfilter_pad_get_name
const char * avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx)
Get the name of an AVFilterPad.
Definition: avfilter.c:923
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2888
pixdesc.h
outfile
FILE * outfile
Definition: audiogen.c:96
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:165
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
line::data
char data[256]
Definition: graph2dot.c:49
avfilter_graph_alloc
AVFilterGraph * avfilter_graph_alloc(void)
Allocate a filter graph.
Definition: avfiltergraph.c:82
filter_ctx
static FilteringContext * filter_ctx
Definition: transcode.c:51
AVFrame::ch_layout
AVChannelLayout ch_layout
Channel layout of the audio data.
Definition: frame.h:723
AVRational::num
int num
Numerator.
Definition: rational.h:59
getopt
static int getopt(int argc, char *argv[], char *opts)
Definition: getopt.c:41
av_channel_layout_describe
int av_channel_layout_describe(const AVChannelLayout *channel_layout, char *buf, size_t buf_size)
Get a human-readable string describing the channel layout properties.
Definition: channel_layout.c:778
line::next
struct line * next
Definition: graph2dot.c:50
main
int main(int argc, char **argv)
Definition: graph2dot.c:108
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
av_get_sample_fmt_name
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:51
link
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
Definition: filter_design.txt:23
avfilter_graph_config
int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
Check validity and configure all the links and formats in the graph.
Definition: avfiltergraph.c:1167
NULL
#define NULL
Definition: coverity.c:32
AVFilterGraph::filters
AVFilterContext ** filters
Definition: avfilter.h:857
AVFilterContext::name
char * name
name of this filter instance
Definition: avfilter.h:397
AVFilterGraph
Definition: avfilter.h:855
c
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
AVFrame::sample_rate
int sample_rate
Sample rate of the audio data.
Definition: frame.h:516
AVFrame::time_base
AVRational time_base
Time base for the timestamps in this frame.
Definition: frame.h:452
usage
static void usage(void)
Definition: graph2dot.c:37
printf
printf("static const uint8_t my_array[100] = {\n")
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:417
line
Definition: graph2dot.c:48
av_log_set_level
void av_log_set_level(int level)
Set the log level.
Definition: log.c:442
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
getopt.c
channel_layout.h
AVRational::den
int den
Denominator.
Definition: rational.h:60
avfilter.h
AVFilterContext
An instance of a filter.
Definition: avfilter.h:392
avfilter_graph_parse
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:163
desc
const char * desc
Definition: libsvtav1.c:83
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
optarg
static char * optarg
Definition: getopt.c:39
mem.h
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
AVFilterGraph::nb_filters
unsigned nb_filters
Definition: avfilter.h:858
AVFilterContext::filter
const AVFilter * filter
the AVFilter of which this is an instance
Definition: avfilter.h:395
print_digraph
static void print_digraph(FILE *outfile, AVFilterGraph *graph)
Definition: graph2dot.c:53
snprintf
#define snprintf
Definition: snprintf.h:34
line
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:40