00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <string.h>
00023
00024 #include "libavutil/audioconvert.h"
00025 #include "libavutil/bprint.h"
00026 #include "libavutil/pixdesc.h"
00027 #include "avfilter.h"
00028 #include "avfiltergraph.h"
00029
00030 static int print_link_prop(AVBPrint *buf, AVFilterLink *link)
00031 {
00032 char *format;
00033 char layout[64];
00034
00035 if (!buf)
00036 buf = &(AVBPrint){ 0 };
00037 switch (link->type) {
00038 case AVMEDIA_TYPE_VIDEO:
00039 format = av_x_if_null(av_get_pix_fmt_name(link->format), "?");
00040 av_bprintf(buf, "[%dx%d %d:%d %s]", link->w, link->h,
00041 link->sample_aspect_ratio.num,
00042 link->sample_aspect_ratio.den,
00043 format);
00044 break;
00045
00046 case AVMEDIA_TYPE_AUDIO:
00047 av_get_channel_layout_string(layout, sizeof(layout),
00048 -1, link->channel_layout);
00049 format = av_x_if_null(av_get_sample_fmt_name(link->format), "?");
00050 av_bprintf(buf, "[%dHz %s:%s]",
00051 (int)link->sample_rate, format, layout);
00052 break;
00053
00054 default:
00055 av_bprintf(buf, "?");
00056 break;
00057 }
00058 return buf->len;
00059 }
00060
00061 static void avfilter_graph_dump_to_buf(AVBPrint *buf, AVFilterGraph *graph)
00062 {
00063 unsigned i, j, x, e;
00064
00065 for (i = 0; i < graph->filter_count; i++) {
00066 AVFilterContext *filter = graph->filters[i];
00067 unsigned max_src_name = 0, max_dst_name = 0;
00068 unsigned max_in_name = 0, max_out_name = 0;
00069 unsigned max_in_fmt = 0, max_out_fmt = 0;
00070 unsigned width, height, in_indent;
00071 unsigned lname = strlen(filter->name);
00072 unsigned ltype = strlen(filter->filter->name);
00073
00074 for (j = 0; j < filter->input_count; j++) {
00075 AVFilterLink *l = filter->inputs[j];
00076 unsigned ln = strlen(l->src->name) + 1 + strlen(l->srcpad->name);
00077 max_src_name = FFMAX(max_src_name, ln);
00078 max_in_name = FFMAX(max_in_name, strlen(l->dstpad->name));
00079 max_in_fmt = FFMAX(max_in_fmt, print_link_prop(NULL, l));
00080 }
00081 for (j = 0; j < filter->output_count; j++) {
00082 AVFilterLink *l = filter->outputs[j];
00083 unsigned ln = strlen(l->dst->name) + 1 + strlen(l->dstpad->name);
00084 max_dst_name = FFMAX(max_dst_name, ln);
00085 max_out_name = FFMAX(max_out_name, strlen(l->srcpad->name));
00086 max_out_fmt = FFMAX(max_out_fmt, print_link_prop(NULL, l));
00087 }
00088 in_indent = max_src_name + max_in_name + max_in_fmt;
00089 in_indent += in_indent ? 4 : 0;
00090 width = FFMAX(lname + 2, ltype + 4);
00091 height = FFMAX3(2, filter->input_count, filter->output_count);
00092 av_bprint_chars(buf, ' ', in_indent);
00093 av_bprintf(buf, "+");
00094 av_bprint_chars(buf, '-', width);
00095 av_bprintf(buf, "+\n");
00096 for (j = 0; j < height; j++) {
00097 unsigned in_no = j - (height - filter->input_count ) / 2;
00098 unsigned out_no = j - (height - filter->output_count) / 2;
00099
00100
00101 if (in_no < filter->input_count) {
00102 AVFilterLink *l = filter->inputs[in_no];
00103 e = buf->len + max_src_name + 2;
00104 av_bprintf(buf, "%s:%s", l->src->name, l->srcpad->name);
00105 av_bprint_chars(buf, '-', e - buf->len);
00106 e = buf->len + max_in_fmt + 2 +
00107 max_in_name - strlen(l->dstpad->name);
00108 print_link_prop(buf, l);
00109 av_bprint_chars(buf, '-', e - buf->len);
00110 av_bprintf(buf, "%s", l->dstpad->name);
00111 } else {
00112 av_bprint_chars(buf, ' ', in_indent);
00113 }
00114
00115
00116 av_bprintf(buf, "|");
00117 if (j == (height - 2) / 2) {
00118 x = (width - lname) / 2;
00119 av_bprintf(buf, "%*s%-*s", x, "", width - x, filter->name);
00120 } else if (j == (height - 2) / 2 + 1) {
00121 x = (width - ltype - 2) / 2;
00122 av_bprintf(buf, "%*s(%s)%*s", x, "", filter->filter->name,
00123 width - ltype - 2 - x, "");
00124 } else {
00125 av_bprint_chars(buf, ' ', width);
00126 }
00127 av_bprintf(buf, "|");
00128
00129
00130 if (out_no < filter->output_count) {
00131 AVFilterLink *l = filter->outputs[out_no];
00132 unsigned ln = strlen(l->dst->name) + 1 +
00133 strlen(l->dstpad->name);
00134 e = buf->len + max_out_name + 2;
00135 av_bprintf(buf, "%s", l->srcpad->name);
00136 av_bprint_chars(buf, '-', e - buf->len);
00137 e = buf->len + max_out_fmt + 2 +
00138 max_dst_name - ln;
00139 print_link_prop(buf, l);
00140 av_bprint_chars(buf, '-', e - buf->len);
00141 av_bprintf(buf, "%s:%s", l->dst->name, l->dstpad->name);
00142 }
00143 av_bprintf(buf, "\n");
00144 }
00145 av_bprint_chars(buf, ' ', in_indent);
00146 av_bprintf(buf, "+");
00147 av_bprint_chars(buf, '-', width);
00148 av_bprintf(buf, "+\n");
00149 av_bprintf(buf, "\n");
00150 }
00151 }
00152
00153 char *avfilter_graph_dump(AVFilterGraph *graph, const char *options)
00154 {
00155 AVBPrint buf;
00156 char *dump;
00157
00158 av_bprint_init(&buf, 0, 0);
00159 avfilter_graph_dump_to_buf(&buf, graph);
00160 av_bprint_init(&buf, buf.len + 1, buf.len + 1);
00161 avfilter_graph_dump_to_buf(&buf, graph);
00162 av_bprint_finalize(&buf, &dump);
00163 return dump;
00164 }