graphdump.c
Go to the documentation of this file.
1 /*
2  * Filter graphs to bad ASCII-art
3  * Copyright (c) 2012 Nicolas George
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <string.h>
23 
25 #include "libavutil/bprint.h"
26 #include "libavutil/pixdesc.h"
27 #include "avfilter.h"
28 #include "avfiltergraph.h"
29 
31 {
32  char *format;
33  char layout[64];
34 
35  if (!buf)
36  buf = &(AVBPrint){ 0 }; /* dummy buffer */
37  switch (link->type) {
38  case AVMEDIA_TYPE_VIDEO:
39  format = av_x_if_null(av_get_pix_fmt_name(link->format), "?");
40  av_bprintf(buf, "[%dx%d %d:%d %s]", link->w, link->h,
43  format);
44  break;
45 
46  case AVMEDIA_TYPE_AUDIO:
47  av_get_channel_layout_string(layout, sizeof(layout),
48  link->channels, link->channel_layout);
49  format = av_x_if_null(av_get_sample_fmt_name(link->format), "?");
50  av_bprintf(buf, "[%dHz %s:%s]",
51  (int)link->sample_rate, format, layout);
52  break;
53 
54  default:
55  av_bprintf(buf, "?");
56  break;
57  }
58  return buf->len;
59 }
60 
62 {
63  unsigned i, j, x, e;
64 
65  for (i = 0; i < graph->nb_filters; i++) {
66  AVFilterContext *filter = graph->filters[i];
67  unsigned max_src_name = 0, max_dst_name = 0;
68  unsigned max_in_name = 0, max_out_name = 0;
69  unsigned max_in_fmt = 0, max_out_fmt = 0;
70  unsigned width, height, in_indent;
71  unsigned lname = strlen(filter->name);
72  unsigned ltype = strlen(filter->filter->name);
73 
74  for (j = 0; j < filter->input_count; j++) {
75  AVFilterLink *l = filter->inputs[j];
76  unsigned ln = strlen(l->src->name) + 1 + strlen(l->srcpad->name);
77  max_src_name = FFMAX(max_src_name, ln);
78  max_in_name = FFMAX(max_in_name, strlen(l->dstpad->name));
79  max_in_fmt = FFMAX(max_in_fmt, print_link_prop(NULL, l));
80  }
81  for (j = 0; j < filter->output_count; j++) {
82  AVFilterLink *l = filter->outputs[j];
83  unsigned ln = strlen(l->dst->name) + 1 + strlen(l->dstpad->name);
84  max_dst_name = FFMAX(max_dst_name, ln);
85  max_out_name = FFMAX(max_out_name, strlen(l->srcpad->name));
86  max_out_fmt = FFMAX(max_out_fmt, print_link_prop(NULL, l));
87  }
88  in_indent = max_src_name + max_in_name + max_in_fmt;
89  in_indent += in_indent ? 4 : 0;
90  width = FFMAX(lname + 2, ltype + 4);
91  height = FFMAX3(2, filter->input_count, filter->output_count);
92  av_bprint_chars(buf, ' ', in_indent);
93  av_bprintf(buf, "+");
94  av_bprint_chars(buf, '-', width);
95  av_bprintf(buf, "+\n");
96  for (j = 0; j < height; j++) {
97  unsigned in_no = j - (height - filter->input_count ) / 2;
98  unsigned out_no = j - (height - filter->output_count) / 2;
99 
100  /* Input link */
101  if (in_no < filter->input_count) {
102  AVFilterLink *l = filter->inputs[in_no];
103  e = buf->len + max_src_name + 2;
104  av_bprintf(buf, "%s:%s", l->src->name, l->srcpad->name);
105  av_bprint_chars(buf, '-', e - buf->len);
106  e = buf->len + max_in_fmt + 2 +
107  max_in_name - strlen(l->dstpad->name);
108  print_link_prop(buf, l);
109  av_bprint_chars(buf, '-', e - buf->len);
110  av_bprintf(buf, "%s", l->dstpad->name);
111  } else {
112  av_bprint_chars(buf, ' ', in_indent);
113  }
114 
115  /* Filter */
116  av_bprintf(buf, "|");
117  if (j == (height - 2) / 2) {
118  x = (width - lname) / 2;
119  av_bprintf(buf, "%*s%-*s", x, "", width - x, filter->name);
120  } else if (j == (height - 2) / 2 + 1) {
121  x = (width - ltype - 2) / 2;
122  av_bprintf(buf, "%*s(%s)%*s", x, "", filter->filter->name,
123  width - ltype - 2 - x, "");
124  } else {
125  av_bprint_chars(buf, ' ', width);
126  }
127  av_bprintf(buf, "|");
128 
129  /* Output link */
130  if (out_no < filter->output_count) {
131  AVFilterLink *l = filter->outputs[out_no];
132  unsigned ln = strlen(l->dst->name) + 1 +
133  strlen(l->dstpad->name);
134  e = buf->len + max_out_name + 2;
135  av_bprintf(buf, "%s", l->srcpad->name);
136  av_bprint_chars(buf, '-', e - buf->len);
137  e = buf->len + max_out_fmt + 2 +
138  max_dst_name - ln;
139  print_link_prop(buf, l);
140  av_bprint_chars(buf, '-', e - buf->len);
141  av_bprintf(buf, "%s:%s", l->dst->name, l->dstpad->name);
142  }
143  av_bprintf(buf, "\n");
144  }
145  av_bprint_chars(buf, ' ', in_indent);
146  av_bprintf(buf, "+");
147  av_bprint_chars(buf, '-', width);
148  av_bprintf(buf, "+\n");
149  av_bprintf(buf, "\n");
150  }
151 }
152 
153 char *avfilter_graph_dump(AVFilterGraph *graph, const char *options)
154 {
155  AVBPrint buf;
156  char *dump;
157 
158  av_bprint_init(&buf, 0, 0);
159  avfilter_graph_dump_to_buf(&buf, graph);
160  av_bprint_init(&buf, buf.len + 1, buf.len + 1);
161  avfilter_graph_dump_to_buf(&buf, graph);
162  av_bprint_finalize(&buf, &dump);
163  return dump;
164 }
AVFilterContext ** filters
Definition: avfilter.h:997
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:93
external API header
int num
numerator
Definition: rational.h:44
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:193
const char * name
Pad name.
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:532
char * name
name of this filter instance
Definition: avfilter.h:529
static void avfilter_graph_dump_to_buf(AVBPrint *buf, AVFilterGraph *graph)
Definition: graphdump.c:61
the mask is usually to keep the same permissions Filters should remove permissions on reference they give to output whenever necessary It can be automatically done by setting the rej_perms field on the output pad Here are a few guidelines corresponding to common then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
const OptionDef options[]
Definition: ffserver.c:4697
static void * av_x_if_null(const void *p, const void *x)
Return x default pointer in case p is NULL.
Definition: avutil.h:250
Discrete Time axis x
static int print_link_prop(AVBPrint *buf, AVFilterLink *link)
Definition: graphdump.c:30
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Init a print buffer.
Definition: bprint.c:68
#define FFMAX(a, b)
Definition: common.h:56
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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
Buffer to print data progressively.
Definition: bprint.h:75
audio channel layout utility functions
struct AVBPrint AVBPrint
Buffer to print data progressively.
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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 format(the sample packing is implied by the sample format) and sample rate.The lists are not just lists
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:47
NULL
Definition: eval.c:55
static int width
Definition: tests/utils.c:158
void * buf
Definition: avisynth_c.h:594
BYTE int const BYTE int int int height
Definition: avisynth_c.h:713
synthesis window for stochastic i
const char * name
filter name
Definition: avfilter.h:437
unsigned nb_filters
Definition: avfilter.h:999
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:539
char * avfilter_graph_dump(AVFilterGraph *graph, const char *options)
Dump a graph into a human-readable string representation.
Definition: graphdump.c:153
int den
denominator
Definition: rational.h:45
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
An instance of a filter.
Definition: avfilter.h:524
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:1700
const AVFilter * filter
the AVFilter of which this is an instance
Definition: avfilter.h:527
#define FFMAX3(a, b, c)
Definition: common.h:57
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.
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:116