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 
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,
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;
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 
201  fflush(outfile);
202 
203  return 0;
204 }
filter_ctx
static FilteringContext * filter_ctx
Definition: transcoding.c:48
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:1048
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
graph
fg outputs[0] graph
Definition: ffmpeg_filter.c:176
av_get_channel_layout_string
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.
Definition: channel_layout.c:217
pixdesc.h
outfile
FILE * outfile
Definition: audiogen.c:96
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:149
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
line::data
char data[256]
Definition: graph2dot.c:49
getopt
static int getopt(int argc, char *argv[], char *opts)
Definition: getopt.c:41
line::next
struct line * next
Definition: graph2dot.c:50
main
int main(int argc, char **argv)
Definition: graph2dot.c:109
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:215
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:49
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:1218
NULL
#define NULL
Definition: coverity.c:32
AVFilterContext::name
char * name
name of this filter instance
Definition: avfilter.h:346
AVFilterGraph
Definition: avfilter.h:850
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:496
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:397
AVFrame::channel_layout
uint64_t channel_layout
Channel layout of the audio data.
Definition: frame.h:501
line
Definition: graph2dot.c:48
av_log_set_level
void av_log_set_level(int level)
Set the log level.
Definition: log.c:440
i
int i
Definition: input.c:407
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:237
getopt.c
channel_layout.h
avfilter.h
AVFilterContext
An instance of a filter.
Definition: avfilter.h:341
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:486
desc
const char * desc
Definition: libsvtav1.c:79
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:81
AVFilterContext::filter
const AVFilter * filter
the AVFilter of which this is an instance
Definition: avfilter.h:344
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