3d702c6af5f490a9c5a576a272d2ab556d0acb51
2 * Filter graphs to bad ASCII-art
3 * Copyright (c) 2012 Nicolas George
5 * This file is part of FFmpeg.
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.
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.
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
24 #include "libavutil/channel_layout.h"
25 #include "libavutil/bprint.h"
26 #include "libavutil/pixdesc.h"
28 #include "avfiltergraph.h"
30 static int print_link_prop(AVBPrint
*buf
, AVFilterLink
*link
)
34 AVBPrint dummy_buffer
= { 0 };
39 case AVMEDIA_TYPE_VIDEO
:
40 format
= av_x_if_null(av_get_pix_fmt_name(link
->format
), "?");
41 av_bprintf(buf
, "[%dx%d %d:%d %s]", link
->w
, link
->h
,
42 link
->sample_aspect_ratio
.num
,
43 link
->sample_aspect_ratio
.den
,
47 case AVMEDIA_TYPE_AUDIO
:
48 av_get_channel_layout_string(layout
, sizeof(layout
),
49 link
->channels
, link
->channel_layout
);
50 format
= av_x_if_null(av_get_sample_fmt_name(link
->format
), "?");
51 av_bprintf(buf
, "[%dHz %s:%s]",
52 (int)link
->sample_rate
, format
, layout
);
62 static void avfilter_graph_dump_to_buf(AVBPrint
*buf
, AVFilterGraph
*graph
)
66 for (i
= 0; i
< graph
->nb_filters
; i
++) {
67 AVFilterContext
*filter
= graph
->filters
[i
];
68 unsigned max_src_name
= 0, max_dst_name
= 0;
69 unsigned max_in_name
= 0, max_out_name
= 0;
70 unsigned max_in_fmt
= 0, max_out_fmt
= 0;
71 unsigned width
, height
, in_indent
;
72 unsigned lname
= strlen(filter
->name
);
73 unsigned ltype
= strlen(filter
->filter
->name
);
75 for (j
= 0; j
< filter
->nb_inputs
; j
++) {
76 AVFilterLink
*l
= filter
->inputs
[j
];
77 unsigned ln
= strlen(l
->src
->name
) + 1 + strlen(l
->srcpad
->name
);
78 max_src_name
= FFMAX(max_src_name
, ln
);
79 max_in_name
= FFMAX(max_in_name
, strlen(l
->dstpad
->name
));
80 max_in_fmt
= FFMAX(max_in_fmt
, print_link_prop(NULL
, l
));
82 for (j
= 0; j
< filter
->nb_outputs
; j
++) {
83 AVFilterLink
*l
= filter
->outputs
[j
];
84 unsigned ln
= strlen(l
->dst
->name
) + 1 + strlen(l
->dstpad
->name
);
85 max_dst_name
= FFMAX(max_dst_name
, ln
);
86 max_out_name
= FFMAX(max_out_name
, strlen(l
->srcpad
->name
));
87 max_out_fmt
= FFMAX(max_out_fmt
, print_link_prop(NULL
, l
));
89 in_indent
= max_src_name
+ max_in_name
+ max_in_fmt
;
90 in_indent
+= in_indent
? 4 : 0;
91 width
= FFMAX(lname
+ 2, ltype
+ 4);
92 height
= FFMAX3(2, filter
->nb_inputs
, filter
->nb_outputs
);
93 av_bprint_chars(buf
, ' ', in_indent
);
95 av_bprint_chars(buf
, '-', width
);
96 av_bprintf(buf
, "+\n");
97 for (j
= 0; j
< height
; j
++) {
98 unsigned in_no
= j
- (height
- filter
->nb_inputs
) / 2;
99 unsigned out_no
= j
- (height
- filter
->nb_outputs
) / 2;
102 if (in_no
< filter
->nb_inputs
) {
103 AVFilterLink
*l
= filter
->inputs
[in_no
];
104 e
= buf
->len
+ max_src_name
+ 2;
105 av_bprintf(buf
, "%s:%s", l
->src
->name
, l
->srcpad
->name
);
106 av_bprint_chars(buf
, '-', e
- buf
->len
);
107 e
= buf
->len
+ max_in_fmt
+ 2 +
108 max_in_name
- strlen(l
->dstpad
->name
);
109 print_link_prop(buf
, l
);
110 av_bprint_chars(buf
, '-', e
- buf
->len
);
111 av_bprintf(buf
, "%s", l
->dstpad
->name
);
113 av_bprint_chars(buf
, ' ', in_indent
);
117 av_bprintf(buf
, "|");
118 if (j
== (height
- 2) / 2) {
119 x
= (width
- lname
) / 2;
120 av_bprintf(buf
, "%*s%-*s", x
, "", width
- x
, filter
->name
);
121 } else if (j
== (height
- 2) / 2 + 1) {
122 x
= (width
- ltype
- 2) / 2;
123 av_bprintf(buf
, "%*s(%s)%*s", x
, "", filter
->filter
->name
,
124 width
- ltype
- 2 - x
, "");
126 av_bprint_chars(buf
, ' ', width
);
128 av_bprintf(buf
, "|");
131 if (out_no
< filter
->nb_outputs
) {
132 AVFilterLink
*l
= filter
->outputs
[out_no
];
133 unsigned ln
= strlen(l
->dst
->name
) + 1 +
134 strlen(l
->dstpad
->name
);
135 e
= buf
->len
+ max_out_name
+ 2;
136 av_bprintf(buf
, "%s", l
->srcpad
->name
);
137 av_bprint_chars(buf
, '-', e
- buf
->len
);
138 e
= buf
->len
+ max_out_fmt
+ 2 +
140 print_link_prop(buf
, l
);
141 av_bprint_chars(buf
, '-', e
- buf
->len
);
142 av_bprintf(buf
, "%s:%s", l
->dst
->name
, l
->dstpad
->name
);
144 av_bprintf(buf
, "\n");
146 av_bprint_chars(buf
, ' ', in_indent
);
147 av_bprintf(buf
, "+");
148 av_bprint_chars(buf
, '-', width
);
149 av_bprintf(buf
, "+\n");
150 av_bprintf(buf
, "\n");
154 char *avfilter_graph_dump(AVFilterGraph
*graph
, const char *options
)
159 av_bprint_init(&buf
, 0, 0);
160 avfilter_graph_dump_to_buf(&buf
, graph
);
161 av_bprint_init(&buf
, buf
.len
+ 1, buf
.len
+ 1);
162 avfilter_graph_dump_to_buf(&buf
, graph
);
163 av_bprint_finalize(&buf
, &dump
);