FFmpeg
graphprint.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2025 - softworkz
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 /**
22  * @file
23  * output writers for filtergraph details
24  */
25 
26 #include <string.h>
27 #include <stdatomic.h>
28 
29 #include "graphprint.h"
30 
31 #include "fftools/ffmpeg.h"
32 #include "fftools/ffmpeg_mux.h"
33 
34 #include "libavutil/avassert.h"
35 #include "libavutil/avstring.h"
36 #include "libavutil/mem.h"
37 #include "libavutil/pixdesc.h"
38 #include "libavutil/dict.h"
39 #include "libavutil/common.h"
40 #include "libavfilter/avfilter.h"
41 #include "libavutil/buffer.h"
42 #include "libavutil/hwcontext.h"
46 
47 typedef enum {
76 } SectionID;
77 
78 static const AVTextFormatSection sections[] = {
80 
83 
85  [SECTION_ID_GRAPH_INPUT] = { SECTION_ID_GRAPH_INPUT, "graph_input", 0, { -1 }, .id_key = "filter_id" },
86 
88  [SECTION_ID_GRAPH_OUTPUT] = { SECTION_ID_GRAPH_OUTPUT, "graph_output", 0, { -1 }, .id_key = "filter_id" },
89 
92 
94  [SECTION_ID_FILTER_INPUT] = { SECTION_ID_FILTER_INPUT, "filter_input", AV_TEXTFORMAT_SECTION_FLAG_HAS_LINKS, { SECTION_ID_HWFRAMESCONTEXT, -1 }, .id_key = "filter_id", .src_id_key = "source_filter_id", .dest_id_key = "filter_id" },
95 
97  [SECTION_ID_FILTER_OUTPUT] = { SECTION_ID_FILTER_OUTPUT, "filter_output", AV_TEXTFORMAT_SECTION_FLAG_HAS_LINKS, { SECTION_ID_HWFRAMESCONTEXT, -1 }, .id_key = "filter_id", .src_id_key = "filter_id", .dest_id_key = "dest_filter_id" },
98 
99  [SECTION_ID_HWFRAMESCONTEXT] = { SECTION_ID_HWFRAMESCONTEXT, "hw_frames_context", 0, { -1 }, },
100 
103 
106 
109 
112 
114  [SECTION_ID_STREAMLINK] = { SECTION_ID_STREAMLINK, "streamlink", AV_TEXTFORMAT_SECTION_FLAG_HAS_LINKS, { -1 }, .src_id_key = "source_stream_id", .dest_id_key = "dest_stream_id" },
115 
117  [SECTION_ID_DECODER] = { SECTION_ID_DECODER, "decoder", AV_TEXTFORMAT_SECTION_FLAG_IS_SHAPE | AV_TEXTFORMAT_SECTION_PRINT_TAGS | AV_TEXTFORMAT_SECTION_FLAG_HAS_LINKS, { -1 }, .id_key = "id", .src_id_key = "source_id", .dest_id_key = "id" },
118 
120  [SECTION_ID_ENCODER] = { SECTION_ID_ENCODER, "encoder", AV_TEXTFORMAT_SECTION_FLAG_IS_SHAPE | AV_TEXTFORMAT_SECTION_PRINT_TAGS | AV_TEXTFORMAT_SECTION_FLAG_HAS_LINKS, { -1 }, .id_key = "id", .src_id_key = "id", .dest_id_key = "dest_id" },
121 };
122 
123 typedef struct GraphPrintContext {
127 
132  AVBPrint pbuf;
133 
135 
136 /* Text Format API Shortcuts */
137 #define print_id(k, v) print_sanizied_id(gpc, k, v, 0)
138 #define print_id_noprefix(k, v) print_sanizied_id(gpc, k, v, 1)
139 #define print_int(k, v) avtext_print_integer(tfc, k, v, 0)
140 #define print_int_opt(k, v) avtext_print_integer(tfc, k, v, gpc->opt_flags)
141 #define print_q(k, v, s) avtext_print_rational(tfc, k, v, s)
142 #define print_str(k, v) avtext_print_string(tfc, k, v, 0)
143 #define print_str_opt(k, v) avtext_print_string(tfc, k, v, gpc->opt_flags)
144 #define print_val(k, v, u) avtext_print_unit_integer(tfc, k, v, u)
145 
146 #define print_fmt(k, f, ...) do { \
147  av_bprint_clear(&gpc->pbuf); \
148  av_bprintf(&gpc->pbuf, f, __VA_ARGS__); \
149  avtext_print_string(tfc, k, gpc->pbuf.str, 0); \
150 } while (0)
151 
152 #define print_fmt_opt(k, f, ...) do { \
153  av_bprint_clear(&gpc->pbuf); \
154  av_bprintf(&gpc->pbuf, f, __VA_ARGS__); \
155  avtext_print_string(tfc, k, gpc->pbuf.str, gpc->opt_flags); \
156 } while (0)
157 
158 
160 
161 static inline char *upcase_string(char *dst, size_t dst_size, const char *src)
162 {
163  unsigned i;
164  for (i = 0; src[i] && i < dst_size - 1; i++)
165  dst[i] = (char)av_toupper(src[i]);
166  dst[i] = 0;
167  return dst;
168 }
169 
170 static char *get_extension(const char *url)
171 {
172  const char *dot = NULL;
173  const char *sep = NULL;
174  const char *end;
175 
176  if (!url)
177  return NULL;
178 
179  /* Stop at the first query ('?') or fragment ('#') delimiter so they
180  * are not considered part of the path. */
181  end = strpbrk(url, "?#");
182  if (!end)
183  end = url + strlen(url);
184 
185  /* Scan the path component only. */
186  for (const char *p = url; p < end; p++) {
187  if (*p == '.')
188  dot = p;
189  else if (*p == '/' || *p == '\\')
190  sep = p;
191  }
192 
193  /* Validate that we have a proper extension. */
194  if (dot && dot != url && (!sep || dot > sep + 1) && (dot + 1) < end) {
195  /* Use FFmpeg helper to duplicate the substring. */
196  return av_strndup(dot + 1, end - (dot + 1));
197  }
198 
199  return NULL;
200 }
201 
202 static void print_hwdevicecontext(const GraphPrintContext *gpc, const AVHWDeviceContext *hw_device_context)
203 {
204  AVTextFormatContext *tfc = gpc->tfc;
205 
206  if (!hw_device_context)
207  return;
208 
209  print_int_opt("has_hw_device_context", 1);
210  print_str_opt("hw_device_type", av_hwdevice_get_type_name(hw_device_context->type));
211 }
212 
213 static void print_hwframescontext(const GraphPrintContext *gpc, const AVHWFramesContext *hw_frames_context)
214 {
215  AVTextFormatContext *tfc = gpc->tfc;
216  const AVPixFmtDescriptor *pix_desc_hw;
217  const AVPixFmtDescriptor *pix_desc_sw;
218 
219  if (!hw_frames_context || !hw_frames_context->device_ctx)
220  return;
221 
223 
224  print_int_opt("has_hw_frames_context", 1);
225  print_str("hw_device_type", av_hwdevice_get_type_name(hw_frames_context->device_ctx->type));
226 
227  pix_desc_hw = av_pix_fmt_desc_get(hw_frames_context->format);
228  if (pix_desc_hw) {
229  print_str("hw_pixel_format", pix_desc_hw->name);
230  if (pix_desc_hw->alias)
231  print_str_opt("hw_pixel_format_alias", pix_desc_hw->alias);
232  }
233 
234  pix_desc_sw = av_pix_fmt_desc_get(hw_frames_context->sw_format);
235  if (pix_desc_sw) {
236  print_str("sw_pixel_format", pix_desc_sw->name);
237  if (pix_desc_sw->alias)
238  print_str_opt("sw_pixel_format_alias", pix_desc_sw->alias);
239  }
240 
241  print_int_opt("width", hw_frames_context->width);
242  print_int_opt("height", hw_frames_context->height);
243  print_int_opt("initial_pool_size", hw_frames_context->initial_pool_size);
244 
245  avtext_print_section_footer(tfc); // SECTION_ID_HWFRAMESCONTEXT
246 }
247 
249 {
250  AVTextFormatContext *tfc = gpc->tfc;
251  AVBufferRef *hw_frames_ctx;
252  char layout_string[64];
253 
254  if (!link)
255  return;
256 
257  hw_frames_ctx = avfilter_link_get_hw_frames_ctx(link);
258 
259  print_str_opt("media_type", av_get_media_type_string(link->type));
260 
261  switch (link->type) {
262  case AVMEDIA_TYPE_VIDEO:
263 
264  if (hw_frames_ctx && hw_frames_ctx->data) {
265  AVHWFramesContext * hwfctx = (AVHWFramesContext *)hw_frames_ctx->data;
266  const AVPixFmtDescriptor *pix_desc_hw = av_pix_fmt_desc_get(hwfctx->format);
267  const AVPixFmtDescriptor *pix_desc_sw = av_pix_fmt_desc_get(hwfctx->sw_format);
268  if (pix_desc_hw && pix_desc_sw)
269  print_fmt("format", "%s | %s", pix_desc_hw->name, pix_desc_sw->name);
270  } else {
272  }
273 
274  if (link->w && link->h) {
275  if (tfc->opts.show_value_unit) {
276  print_fmt("size", "%dx%d", link->w, link->h);
277  } else {
278  print_int("width", link->w);
279  print_int("height", link->h);
280  }
281  }
282 
283  print_q("sar", link->sample_aspect_ratio, ':');
284 
287 
289  print_str("color_space", av_color_space_name(link->colorspace));
290  break;
291 
293  ////print_str("format", av_x_if_null(av_get_subtitle_fmt_name(link->format), "?"));
294 
295  if (link->w && link->h) {
296  if (tfc->opts.show_value_unit) {
297  print_fmt("size", "%dx%d", link->w, link->h);
298  } else {
299  print_int("width", link->w);
300  print_int("height", link->h);
301  }
302  }
303 
304  break;
305 
306  case AVMEDIA_TYPE_AUDIO:
307  av_channel_layout_describe(&link->ch_layout, layout_string, sizeof(layout_string));
308  print_str("channel_layout", layout_string);
309  print_val("channels", link->ch_layout.nb_channels, "ch");
310  if (tfc->opts.show_value_unit)
311  print_fmt("sample_rate", "%d.1 kHz", link->sample_rate / 1000);
312  else
313  print_val("sample_rate", link->sample_rate, "Hz");
314 
315  break;
316  }
317 
318  print_fmt_opt("sample_rate", "%d/%d", link->time_base.num, link->time_base.den);
319 
320  if (hw_frames_ctx && hw_frames_ctx->data)
321  print_hwframescontext(gpc, (AVHWFramesContext *)hw_frames_ctx->data);
322  av_buffer_unref(&hw_frames_ctx);
323 }
324 
325 static char sanitize_char(const char c)
326 {
327  if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
328  return c;
329  return '_';
330 }
331 
332 static void print_sanizied_id(const GraphPrintContext *gpc, const char *key, const char *id_str, int skip_prefix)
333 {
334  AVTextFormatContext *tfc = gpc->tfc;
335  AVBPrint buf;
336 
337  if (!key || !id_str)
338  return;
339 
341 
342  if (!skip_prefix)
343  av_bprintf(&buf, "G%d_", gpc->id_prefix_num);
344 
345  // sanizize section id
346  for (const char *p = id_str; *p; p++)
347  av_bprint_chars(&buf, sanitize_char(*p), 1);
348 
349  print_str(key, buf.str);
350 
351  av_bprint_finalize(&buf, NULL);
352 }
353 
354 static void print_section_header_id(const GraphPrintContext *gpc, int section_id, const char *id_str, int skip_prefix)
355 {
356  AVTextFormatContext *tfc = gpc->tfc;
357  AVTextFormatSectionContext sec_ctx = { 0 };
358  AVBPrint buf;
359 
360  if (!id_str)
361  return;
362 
364 
365  if (!skip_prefix)
366  av_bprintf(&buf, "G%d_", gpc->id_prefix_num);
367 
368  // sanizize section id
369  for (const char *p = id_str; *p; p++)
370  av_bprint_chars(&buf, sanitize_char(*p), 1);
371 
372  sec_ctx.context_id = buf.str;
373 
374  avtext_print_section_header(tfc, &sec_ctx, section_id);
375 
376  av_bprint_finalize(&buf, NULL);
377 }
378 
379 static const char *get_filterpad_name(const AVFilterPad *pad)
380 {
381  return pad ? avfilter_pad_get_name(pad, 0) : "pad";
382 }
383 
384 static void print_filter(GraphPrintContext *gpc, const AVFilterContext *filter, AVDictionary *input_map, AVDictionary *output_map)
385 {
386  AVTextFormatContext *tfc = gpc->tfc;
387  AVTextFormatSectionContext sec_ctx = { 0 };
388 
390 
391  ////print_id("filter_id", filter->name);
392 
393  if (filter->filter) {
394  print_str("filter_name", filter->filter->name);
395  print_str_opt("description", filter->filter->description);
396  print_int_opt("nb_inputs", filter->nb_inputs);
397  print_int_opt("nb_outputs", filter->nb_outputs);
398  }
399 
400  if (filter->hw_device_ctx) {
401  AVHWDeviceContext *device_context = (AVHWDeviceContext *)filter->hw_device_ctx->data;
402  print_hwdevicecontext(gpc, device_context);
403  if (filter->extra_hw_frames > 0)
404  print_int("extra_hw_frames", filter->extra_hw_frames);
405  }
406 
408 
409  for (unsigned i = 0; i < filter->nb_inputs; i++) {
410  AVDictionaryEntry *dic_entry;
411  AVFilterLink *link = filter->inputs[i];
412 
413  sec_ctx.context_type = av_get_media_type_string(link->type);
415  sec_ctx.context_type = NULL;
416 
417  print_int_opt("input_index", i);
418  print_str_opt("pad_name", get_filterpad_name(link->dstpad));;
419 
420  dic_entry = av_dict_get(input_map, link->src->name, NULL, 0);
421  if (dic_entry) {
422  char buf[256];
423  (void)snprintf(buf, sizeof(buf), "in_%s", dic_entry->value);
424  print_id_noprefix("source_filter_id", buf);
425  } else {
426  print_id("source_filter_id", link->src->name);
427  }
428 
429  print_str_opt("source_pad_name", get_filterpad_name(link->srcpad));
430  print_id("filter_id", filter->name);
431 
432  print_link(gpc, link);
433 
434  avtext_print_section_footer(tfc); // SECTION_ID_FILTER_INPUT
435  }
436 
437  avtext_print_section_footer(tfc); // SECTION_ID_FILTER_INPUTS
438 
440 
441  for (unsigned i = 0; i < filter->nb_outputs; i++) {
442  AVDictionaryEntry *dic_entry;
443  AVFilterLink *link = filter->outputs[i];
444  char buf[256];
445 
446  sec_ctx.context_type = av_get_media_type_string(link->type);
448  sec_ctx.context_type = NULL;
449 
450  dic_entry = av_dict_get(output_map, link->dst->name, NULL, 0);
451  if (dic_entry) {
452  (void)snprintf(buf, sizeof(buf), "out_%s", dic_entry->value);
453  print_id_noprefix("dest_filter_id", buf);
454  } else {
455  print_id("dest_filter_id", link->dst->name);
456  }
457 
458  print_int_opt("output_index", i);
459  print_str_opt("pad_name", get_filterpad_name(link->srcpad));
460  ////print_id("dest_filter_id", link->dst->name);
461  print_str_opt("dest_pad_name", get_filterpad_name(link->dstpad));
462  print_id("filter_id", filter->name);
463 
464  print_link(gpc, link);
465 
466  avtext_print_section_footer(tfc); // SECTION_ID_FILTER_OUTPUT
467  }
468 
469  avtext_print_section_footer(tfc); // SECTION_ID_FILTER_OUTPUTS
470 
471  avtext_print_section_footer(tfc); // SECTION_ID_FILTER
472 }
473 
475 {
476  AVTextFormatContext *tfc = gpc->tfc;
477  AVDictionary *input_map = NULL;
478  AVDictionary *output_map = NULL;
479 
480  print_int("graph_index", fg->index);
481  print_fmt("name", "Graph %d.%d", gpc->id_prefix_num, fg->index);
482  print_fmt("id", "Graph_%d_%d", gpc->id_prefix_num, fg->index);
483  print_str("description", fg->graph_desc);
484 
485  print_section_header_id(gpc, SECTION_ID_GRAPH_INPUTS, "Input_File", 0);
486 
487  for (int i = 0; i < fg->nb_inputs; i++) {
488  InputFilter *ifilter = fg->inputs[i];
489  enum AVMediaType media_type = ifilter->type;
490 
492 
493  print_int("input_index", ifilter->index);
494 
495  if (ifilter->linklabel)
496  print_str("link_label", (const char*)ifilter->linklabel);
497 
498  if (ifilter->filter) {
499  print_id("filter_id", ifilter->filter->name);
500  print_str("filter_name", ifilter->filter->filter->name);
501  }
502 
503  if (ifilter->linklabel && ifilter->filter)
504  av_dict_set(&input_map, ifilter->filter->name, (const char *)ifilter->linklabel, 0);
505  else if (ifilter->input_name && ifilter->filter)
506  av_dict_set(&input_map, ifilter->filter->name, (const char *)ifilter->input_name, 0);
507 
508  print_str("media_type", av_get_media_type_string(media_type));
509 
510  avtext_print_section_footer(tfc); // SECTION_ID_GRAPH_INPUT
511  }
512 
513  avtext_print_section_footer(tfc); // SECTION_ID_GRAPH_INPUTS
514 
515  print_section_header_id(gpc, SECTION_ID_GRAPH_OUTPUTS, "Output_File", 0);
516 
517  for (int i = 0; i < fg->nb_outputs; i++) {
518  OutputFilter *ofilter = fg->outputs[i];
519 
521 
522  print_int("output_index", ofilter->index);
523 
524  print_str("name", ofilter->output_name);
525 
526  if (fg->outputs[i]->linklabel)
527  print_str("link_label", (const char*)fg->outputs[i]->linklabel);
528 
529  if (ofilter->filter) {
530  print_id("filter_id", ofilter->filter->name);
531  print_str("filter_name", ofilter->filter->filter->name);
532  }
533 
534  if (ofilter->output_name && ofilter->filter)
535  av_dict_set(&output_map, ofilter->filter->name, ofilter->output_name, 0);
536 
537 
538  print_str("media_type", av_get_media_type_string(ofilter->type));
539 
540  avtext_print_section_footer(tfc); // SECTION_ID_GRAPH_OUTPUT
541  }
542 
543  avtext_print_section_footer(tfc); // SECTION_ID_GRAPH_OUTPUTS
544 
545  if (graph) {
546  AVTextFormatSectionContext sec_ctx = { 0 };
547 
548  sec_ctx.context_id = av_asprintf("Graph_%d_%d", gpc->id_prefix_num, fg->index);
549 
551 
552  if (gpc->is_diagram) {
553  print_fmt("name", "Graph %d.%d", gpc->id_prefix_num, fg->index);
554  print_str("description", fg->graph_desc);
555  print_str("id", sec_ctx.context_id);
556  }
557 
558  av_freep(&sec_ctx.context_id);
559 
560  for (unsigned i = 0; i < graph->nb_filters; i++) {
561  AVFilterContext *filter = graph->filters[i];
562 
563  if (gpc->skip_buffer_filters) {
564  if (av_dict_get(input_map, filter->name, NULL, 0))
565  continue;
566  if (av_dict_get(output_map, filter->name, NULL, 0))
567  continue;
568  }
569 
570  sec_ctx.context_id = filter->name;
571 
572  print_filter(gpc, filter, input_map, output_map);
573  }
574 
575  avtext_print_section_footer(tfc); // SECTION_ID_FILTERS
576  }
577 
578  // Clean up dictionaries
579  av_dict_free(&input_map);
580  av_dict_free(&output_map);
581 }
582 
583 static int print_streams(GraphPrintContext *gpc, InputFile **ifiles, int nb_ifiles, OutputFile **ofiles, int nb_ofiles)
584 {
585  AVTextFormatContext *tfc = gpc->tfc;
586  AVBPrint buf;
587  AVTextFormatSectionContext sec_ctx = { 0 };
588 
590 
592 
593  for (int n = nb_ifiles - 1; n >= 0; n--) {
594  InputFile *ifi = ifiles[n];
595  AVFormatContext *fc = ifi->ctx;
596 
597  sec_ctx.context_id = av_asprintf("Input_%d", n);
599  av_freep(&sec_ctx.context_id);
600 
601  print_fmt("index", "%d", ifi->index);
602 
603  if (fc) {
604  print_str("demuxer_name", fc->iformat->name);
605  if (fc->url) {
606  char *extension = get_extension(fc->url);
607  if (extension) {
608  print_str("file_extension", extension);
609  av_freep(&extension);
610  }
611  print_str("url", fc->url);
612  }
613  }
614 
615  sec_ctx.context_id = av_asprintf("InputStreams_%d", n);
616 
618 
619  av_freep(&sec_ctx.context_id);
620 
621  for (int i = 0; i < ifi->nb_streams; i++) {
622  InputStream *ist = ifi->streams[i];
623  const AVCodecDescriptor *codec_desc;
624 
625  if (!ist || !ist->par)
626  continue;
627 
628  codec_desc = avcodec_descriptor_get(ist->par->codec_id);
629 
630  sec_ctx.context_id = av_asprintf("r_in_%d_%d", n, i);
631 
633 
635  av_freep(&sec_ctx.context_id);
636  sec_ctx.context_type = NULL;
637 
638  av_bprint_clear(&buf);
639 
640  print_fmt("id", "r_in_%d_%d", n, i);
641 
642  if (codec_desc && codec_desc->name) {
643  ////av_bprintf(&buf, "%s", upcase_string(char_buf, sizeof(char_buf), codec_desc->long_name));
644  av_bprintf(&buf, "%s", codec_desc->long_name);
645  } else if (ist->dec) {
646  char char_buf[256];
647  av_bprintf(&buf, "%s", upcase_string(char_buf, sizeof(char_buf), ist->dec->name));
648  } else if (ist->par->codec_type == AVMEDIA_TYPE_ATTACHMENT) {
649  av_bprintf(&buf, "%s", "Attachment");
650  } else if (ist->par->codec_type == AVMEDIA_TYPE_DATA) {
651  av_bprintf(&buf, "%s", "Data");
652  }
653 
654  print_fmt("name", "%s", buf.str);
655  print_fmt("index", "%d", ist->index);
656 
657  if (ist->dec)
659 
660  avtext_print_section_footer(tfc); // SECTION_ID_INPUTSTREAM
661  }
662 
663  avtext_print_section_footer(tfc); // SECTION_ID_INPUTSTREAMS
664  avtext_print_section_footer(tfc); // SECTION_ID_INPUTFILE
665  }
666 
667  avtext_print_section_footer(tfc); // SECTION_ID_INPUTFILES
668 
669 
670  print_section_header_id(gpc, SECTION_ID_DECODERS, "Decoders", 0);
671 
672  for (int n = 0; n < nb_ifiles; n++) {
673  InputFile *ifi = ifiles[n];
674 
675  for (int i = 0; i < ifi->nb_streams; i++) {
676  InputStream *ist = ifi->streams[i];
677 
678  if (!ist->decoder)
679  continue;
680 
681  sec_ctx.context_id = av_asprintf("in_%d_%d", n, i);
683  sec_ctx.context_flags = 2;
684 
686  av_freep(&sec_ctx.context_id);
687  sec_ctx.context_type = NULL;
688  sec_ctx.context_flags = 0;
689 
690  av_bprint_clear(&buf);
691 
692  print_fmt("source_id", "r_in_%d_%d", n, i);
693  print_fmt("id", "in_%d_%d", n, i);
694 
695  ////av_bprintf(&buf, "%s", upcase_string(char_buf, sizeof(char_buf), ist->dec->name));
696  print_fmt("name", "%s", ist->dec->name);
697 
699 
700  avtext_print_section_footer(tfc); // SECTION_ID_DECODER
701  }
702  }
703 
704  avtext_print_section_footer(tfc); // SECTION_ID_DECODERS
705 
706 
707  print_section_header_id(gpc, SECTION_ID_ENCODERS, "Encoders", 0);
708 
709  for (int n = 0; n < nb_ofiles; n++) {
710  OutputFile *of = ofiles[n];
711 
712  for (int i = 0; i < of->nb_streams; i++) {
713  OutputStream *ost = of->streams[i];
714  ////const AVCodecDescriptor *codec_desc;
715 
716  if (!ost || !ost->st || !ost->st->codecpar || !ost->enc)
717  continue;
718 
719  ////codec_desc = avcodec_descriptor_get(ost->st->codecpar->codec_id);
720 
721  sec_ctx.context_id = av_asprintf("out__%d_%d", n, i);
722  sec_ctx.context_type = av_get_media_type_string(ost->type);
723  sec_ctx.context_flags = 2;
724 
726  av_freep(&sec_ctx.context_id);
727  sec_ctx.context_type = NULL;
728  sec_ctx.context_flags = 0;
729 
730  av_bprint_clear(&buf);
731 
732  print_fmt("id", "out__%d_%d", n, i);
733  print_fmt("dest_id", "r_out__%d_%d", n, i);
734 
735  print_fmt("name", "%s", ost->enc->enc_ctx->av_class->item_name(ost->enc->enc_ctx));
736 
737  print_str_opt("media_type", av_get_media_type_string(ost->type));
738 
739  avtext_print_section_footer(tfc); // SECTION_ID_ENCODER
740  }
741  }
742 
743  avtext_print_section_footer(tfc); // SECTION_ID_ENCODERS
744 
745 
747 
748  for (int n = nb_ofiles - 1; n >= 0; n--) {
749  OutputFile *of = ofiles[n];
750  Muxer *muxer = (Muxer *)of;
751 
752  if (!muxer->fc)
753  continue;
754 
755  sec_ctx.context_id = av_asprintf("Output_%d", n);
756 
758 
759  av_freep(&sec_ctx.context_id);
760 
761  ////print_str_opt("index", av_get_media_type_string(of->index));
762  print_fmt("index", "%d", of->index);
763  ////print_str("url", of->url);
764  print_str("muxer_name", muxer->fc->oformat->name);
765  if (of->url) {
766  char *extension = get_extension(of->url);
767  if (extension) {
768  print_str("file_extension", extension);
769  av_freep(&extension);
770  }
771  print_str("url", of->url);
772  }
773 
774  sec_ctx.context_id = av_asprintf("OutputStreams_%d", n);
775 
777 
778  av_freep(&sec_ctx.context_id);
779 
780  for (int i = 0; i < of->nb_streams; i++) {
781  OutputStream *ost = of->streams[i];
782  const AVCodecDescriptor *codec_desc = avcodec_descriptor_get(ost->st->codecpar->codec_id);
783 
784  sec_ctx.context_id = av_asprintf("r_out__%d_%d", n, i);
785  sec_ctx.context_type = av_get_media_type_string(ost->type);
787  av_freep(&sec_ctx.context_id);
788  sec_ctx.context_type = NULL;
789 
790  av_bprint_clear(&buf);
791 
792  print_fmt("id", "r_out__%d_%d", n, i);
793 
794  if (codec_desc && codec_desc->name) {
795  av_bprintf(&buf, "%s", codec_desc->long_name);
796  } else {
797  av_bprintf(&buf, "%s", "unknown");
798  }
799 
800  print_fmt("name", "%s", buf.str);
801  print_fmt("index", "%d", ost->index);
802 
803  print_str_opt("media_type", av_get_media_type_string(ost->type));
804 
805  avtext_print_section_footer(tfc); // SECTION_ID_OUTPUTSTREAM
806  }
807 
808  avtext_print_section_footer(tfc); // SECTION_ID_OUTPUTSTREAMS
809  avtext_print_section_footer(tfc); // SECTION_ID_OUTPUTFILE
810  }
811 
812  avtext_print_section_footer(tfc); // SECTION_ID_OUTPUTFILES
813 
814 
816 
817  for (int n = 0; n < nb_ofiles; n++) {
818  OutputFile *of = ofiles[n];
819 
820  for (int i = 0; i < of->nb_streams; i++) {
821  OutputStream *ost = of->streams[i];
822 
823  if (ost->ist && !ost->filter) {
824  sec_ctx.context_type = av_get_media_type_string(ost->type);
826  sec_ctx.context_type = NULL;
827 
828  if (ost->enc) {
829  print_fmt("dest_stream_id", "out__%d_%d", n, i);
830  print_fmt("source_stream_id", "in_%d_%d", ost->ist->file->index, ost->ist->index);
831  print_str("operation", "Transcode");
832  } else {
833  print_fmt("dest_stream_id", "r_out__%d_%d", n, i);
834  print_fmt("source_stream_id", "r_in_%d_%d", ost->ist->file->index, ost->ist->index);
835  print_str("operation", "Stream Copy");
836  }
837 
838  print_str_opt("media_type", av_get_media_type_string(ost->type));
839 
840  avtext_print_section_footer(tfc); // SECTION_ID_STREAMLINK
841  }
842  }
843  }
844 
845  avtext_print_section_footer(tfc); // SECTION_ID_STREAMLINKS
846 
847  av_bprint_finalize(&buf, NULL);
848  return 0;
849 }
850 
851 
853 {
854  if (gpc->tfc)
855  avtext_context_close(&gpc->tfc);
856 
857  if (gpc->wctx)
859 
860  // Finalize the print buffer if it was initialized
861  av_bprint_finalize(&gpc->pbuf, NULL);
862 
863  av_freep(&gpc);
864 }
865 
866 static int init_graphprint(GraphPrintContext **pgpc, AVBPrint *target_buf)
867 {
868  const AVTextFormatter *text_formatter;
869  AVTextFormatContext *tfc = NULL;
870  AVTextWriterContext *wctx = NULL;
871  GraphPrintContext *gpc = NULL;
872  int ret;
873 
874  *pgpc = NULL;
875 
877 
878  const char *w_name = print_graphs_format ? print_graphs_format : "json";
879 
880  text_formatter = avtext_get_formatter_by_name(w_name);
881  if (!text_formatter) {
882  av_log(NULL, AV_LOG_ERROR, "Unknown filter graph output format with name '%s'\n", w_name);
883  ret = AVERROR(EINVAL);
884  goto fail;
885  }
886 
887  ret = avtextwriter_create_buffer(&wctx, target_buf);
888  if (ret < 0) {
889  av_log(NULL, AV_LOG_ERROR, "avtextwriter_create_buffer failed. Error code %d\n", ret);
890  ret = AVERROR(EINVAL);
891  goto fail;
892  }
893 
894  AVTextFormatOptions tf_options = { .show_optional_fields = -1 };
895  const char *w_args = print_graphs_format ? strchr(print_graphs_format, '=') : NULL;
896  if (w_args)
897  ++w_args; // consume '='
898  ret = avtext_context_open(&tfc, text_formatter, wctx, w_args, sections, FF_ARRAY_ELEMS(sections), tf_options, NULL);
899  if (ret < 0) {
900  goto fail;
901  }
902 
903  gpc = av_mallocz(sizeof(GraphPrintContext));
904  if (!gpc) {
905  ret = AVERROR(ENOMEM);
906  goto fail;
907  }
908 
909  gpc->wctx = wctx;
910  gpc->tfc = tfc;
912 
915  if (gpc->is_diagram) {
916  tfc->opts.show_value_unit = 1;
917  tfc->opts.show_optional_fields = -1;
919  gpc->skip_buffer_filters = 1;
920  ////} else {
921  //// gpc->opt_flags = AV_TEXTFORMAT_PRINT_STRING_OPTIONAL;
922  }
923 
924  if (!strcmp(text_formatter->name, "mermaid") || !strcmp(text_formatter->name, "mermaidhtml")) {
926 
927  if (!strcmp(text_formatter->name, "mermaidhtml"))
929 
930  av_diagram_init(tfc, &gpc->diagram_config);
931  }
932 
933  *pgpc = gpc;
934 
935  return 0;
936 
937 fail:
938  if (tfc)
939  avtext_context_close(&tfc);
940  if (wctx && !tfc) // Only free wctx if tfc didn't take ownership of it
942  av_freep(&gpc);
943 
944  return ret;
945 }
946 
947 
949 {
950  av_assert2(fg);
951 
952  GraphPrintContext *gpc = NULL;
953  AVTextFormatContext *tfc;
954  AVBPrint *target_buf = &fg->graph_print_buf;
955  int ret;
956 
957  if (target_buf->len)
958  av_bprint_finalize(target_buf, NULL);
959 
960  ret = init_graphprint(&gpc, target_buf);
961  if (ret)
962  return ret;
963 
964  tfc = gpc->tfc;
965 
966  // Due to the threading model each graph needs to print itself into a buffer
967  // from its own thread. The actual printing happens short before cleanup in ffmpeg.c
968  // where all graphs are assembled together. To make this work, we need to put the
969  // formatting context into the same state like it would be when printing all at once,
970  // so here we print the section headers and clear the buffer to get into the right state.
974 
975  av_bprint_clear(target_buf);
976 
977  print_filtergraph_single(gpc, fg, graph);
978 
979  if (gpc->is_diagram) {
980  avtext_print_section_footer(tfc); // SECTION_ID_FILTERGRAPH
981  avtext_print_section_footer(tfc); // SECTION_ID_FILTERGRAPHS
982  }
983 
984  uninit_graphprint(gpc);
985 
986  return 0;
987 }
988 
989 static int print_filtergraphs_priv(FilterGraph **graphs, int nb_graphs, InputFile **ifiles, int nb_ifiles, OutputFile **ofiles, int nb_ofiles)
990 {
991  GraphPrintContext *gpc = NULL;
992  AVTextFormatContext *tfc;
993  AVBPrint target_buf;
994  int ret;
995 
996  ret = init_graphprint(&gpc, &target_buf);
997  if (ret)
998  goto cleanup;
999 
1000  tfc = gpc->tfc;
1001 
1004 
1005  for (int i = 0; i < nb_graphs; i++) {
1006  AVBPrint *graph_buf = &graphs[i]->graph_print_buf;
1007 
1008  if (graph_buf->len > 0) {
1010  av_bprint_append_data(&target_buf, graph_buf->str, graph_buf->len);
1011  av_bprint_finalize(graph_buf, NULL);
1012  avtext_print_section_footer(tfc); // SECTION_ID_FILTERGRAPH
1013  }
1014  }
1015 
1016  for (int n = 0; n < nb_ofiles; n++) {
1017  OutputFile *of = ofiles[n];
1018 
1019  for (int i = 0; i < of->nb_streams; i++) {
1020  OutputStream *ost = of->streams[i];
1021 
1022  if (ost->fg_simple) {
1023  AVBPrint *graph_buf = &ost->fg_simple->graph_print_buf;
1024 
1025  if (graph_buf->len > 0) {
1027  av_bprint_append_data(&target_buf, graph_buf->str, graph_buf->len);
1028  av_bprint_finalize(graph_buf, NULL);
1029  avtext_print_section_footer(tfc); // SECTION_ID_FILTERGRAPH
1030  }
1031  }
1032  }
1033  }
1034 
1035  avtext_print_section_footer(tfc); // SECTION_ID_FILTERGRAPHS
1036 
1037  print_streams(gpc, ifiles, nb_ifiles, ofiles, nb_ofiles);
1038 
1039  avtext_print_section_footer(tfc); // SECTION_ID_ROOT
1040 
1041  if (print_graphs_file) {
1042  AVIOContext *avio = NULL;
1043 
1044  if (!strcmp(print_graphs_file, "-")) {
1045  printf("%s", target_buf.str);
1046  } else {
1048  if (ret < 0) {
1049  av_log(NULL, AV_LOG_ERROR, "Failed to open graph output file, \"%s\": %s\n", print_graphs_file, av_err2str(ret));
1050  goto cleanup;
1051  }
1052 
1053  avio_write(avio, (const unsigned char *)target_buf.str, FFMIN(target_buf.len, target_buf.size - 1));
1054 
1055  if ((ret = avio_closep(&avio)) < 0)
1056  av_log(NULL, AV_LOG_ERROR, "Error closing graph output file, loss of information possible: %s\n", av_err2str(ret));
1057  }
1058  }
1059 
1060  if (print_graphs)
1061  av_log(NULL, AV_LOG_INFO, "%s %c", target_buf.str, '\n');
1062 
1063 cleanup:
1064  // Properly clean up resources
1065  if (gpc)
1066  uninit_graphprint(gpc);
1067 
1068  // Ensure the target buffer is properly finalized
1069  av_bprint_finalize(&target_buf, NULL);
1070 
1071  return ret;
1072 }
1073 
1074 int print_filtergraphs(FilterGraph **graphs, int nb_graphs, InputFile **ifiles, int nb_ifiles, OutputFile **ofiles, int nb_ofiles)
1075 {
1076  int ret = print_filtergraphs_priv(graphs, nb_graphs, ifiles, nb_ifiles, ofiles, nb_ofiles);
1077  ff_resman_uninit();
1078  return ret;
1079 }
sections
static const AVTextFormatSection sections[]
Definition: graphprint.c:78
SECTION_ID_HWFRAMESCONTEXT
@ SECTION_ID_HWFRAMESCONTEXT
Definition: graphprint.c:61
upcase_string
static char * upcase_string(char *dst, size_t dst_size, const char *src)
Definition: graphprint.c:161
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AVFrame::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:686
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
SECTION_ID_GRAPH_INPUTS
@ SECTION_ID_GRAPH_INPUTS
Definition: graphprint.c:51
print_filter
static void print_filter(GraphPrintContext *gpc, const AVFilterContext *filter, AVDictionary *input_map, AVDictionary *output_map)
Definition: graphprint.c:384
AV_TEXTFORMAT_PRINT_STRING_OPTIONAL
#define AV_TEXTFORMAT_PRINT_STRING_OPTIONAL
Definition: avtextformat.h:164
Muxer::fc
AVFormatContext * fc
Definition: ffmpeg_mux.h:101
SECTION_ID_DECODER
@ SECTION_ID_DECODER
Definition: graphprint.c:73
AV_TEXTFORMAT_SECTION_PRINT_TAGS
#define AV_TEXTFORMAT_SECTION_PRINT_TAGS
...
Definition: avtextformat.h:53
AV_TEXTFORMAT_FLAG_IS_DIAGRAM_FORMATTER
#define AV_TEXTFORMAT_FLAG_IS_DIAGRAM_FORMATTER
Definition: avtextformat.h:71
AVOutputFormat::name
const char * name
Definition: avformat.h:506
AVERROR
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 all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
printf
__device__ int printf(const char *,...)
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:53
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:987
AVTextFormatContext::opts
AVTextFormatOptions opts
Definition: avtextformat.h:155
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
FilterGraph::graph_desc
const char * graph_desc
Definition: ffmpeg.h:428
atomic_fetch_add
#define atomic_fetch_add(object, operand)
Definition: stdatomic.h:137
FF_RESOURCE_GRAPH_CSS
@ FF_RESOURCE_GRAPH_CSS
Definition: resman.h:33
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3456
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
FilterGraph::inputs
InputFilter ** inputs
Definition: ffmpeg.h:418
SECTION_ID_OUTPUTSTREAM
@ SECTION_ID_OUTPUTSTREAM
Definition: graphprint.c:69
AVCodecDescriptor::long_name
const char * long_name
A more descriptive name for this codec.
Definition: codec_desc.h:50
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:200
SECTION_ID_FILTER
@ SECTION_ID_FILTER
Definition: graphprint.c:56
AVCodecDescriptor::name
const char * name
Name of the codec described by this descriptor.
Definition: codec_desc.h:46
av_asprintf
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:115
AVTextFormatSectionContext::context_type
const char * context_type
Definition: avtextformat.h:36
AVDiagramConfig::diagram_css
const char * diagram_css
Definition: tf_mermaid.h:31
SECTION_ID_GRAPH_OUTPUT
@ SECTION_ID_GRAPH_OUTPUT
Definition: graphprint.c:54
AVFrame::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:697
InputFile::index
int index
Definition: ffmpeg.h:532
pixdesc.h
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
print_int
#define print_int(k, v)
Definition: graphprint.c:139
AVPixFmtDescriptor::name
const char * name
Definition: pixdesc.h:70
OutputFilter::index
int index
Definition: ffmpeg.h:395
FilterGraph::index
int index
Definition: ffmpeg.h:416
print_section_header_id
static void print_section_header_id(const GraphPrintContext *gpc, int section_id, const char *id_str, int skip_prefix)
Definition: graphprint.c:354
InputFilter::index
int index
Definition: ffmpeg.h:376
AV_TEXTFORMAT_SECTION_FLAG_IS_SUBGRAPH
#define AV_TEXTFORMAT_SECTION_FLAG_IS_SUBGRAPH
...
Definition: avtextformat.h:54
AVTextWriterContext
Definition: avtextwriters.h:42
avtextformat.h
AVTextFormatContext
Definition: avtextformat.h:133
atomic_int
intptr_t atomic_int
Definition: stdatomic.h:55
SECTION_ID_ENCODERS
@ SECTION_ID_ENCODERS
Definition: graphprint.c:74
ff_resman_uninit
void ff_resman_uninit(void)
Definition: resman.c:120
ffmpeg.h
filter
void(* filter)(uint8_t *src, int stride, int qscale)
Definition: h263dsp.c:29
FilterGraph::nb_inputs
int nb_inputs
Definition: ffmpeg.h:419
AVDictionary
Definition: dict.c:32
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:220
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:220
resman.h
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
ost
static AVStream * ost
Definition: vaapi_transcode.c:42
print_str_opt
#define print_str_opt(k, v)
Definition: graphprint.c:143
OutputFile::nb_streams
int nb_streams
Definition: ffmpeg.h:713
Muxer
Definition: ffmpeg_mux.h:95
InputStream
Definition: ffmpeg.h:483
AVDiagramConfig
Definition: tf_mermaid.h:29
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3856
SECTION_ID_INPUTSTREAMS
@ SECTION_ID_INPUTSTREAMS
Definition: graphprint.c:64
fail
#define fail()
Definition: checkasm.h:224
InputFilter::type
enum AVMediaType type
Definition: ffmpeg.h:379
print_filtergraph
int print_filtergraph(FilterGraph *fg, AVFilterGraph *graph)
Definition: graphprint.c:948
SECTION_ID_GRAPH_INPUT
@ SECTION_ID_GRAPH_INPUT
Definition: graphprint.c:52
AVFrame::ch_layout
AVChannelLayout ch_layout
Channel layout of the audio data.
Definition: frame.h:778
SECTION_ID_OUTPUTFILES
@ SECTION_ID_OUTPUTFILES
Definition: graphprint.c:66
AVRational::num
int num
Numerator.
Definition: rational.h:59
AVTextFormatSectionContext
Definition: avtextformat.h:34
InputFile
Definition: ffmpeg.h:529
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:40
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:63
ff_resman_get_string
char * ff_resman_get_string(FFResourceId resource_id)
Definition: resman.c:130
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
avtextwriter_create_buffer
int avtextwriter_create_buffer(AVTextWriterContext **pwctx, AVBPrint *buffer)
Definition: tw_buffer.c:76
print_hwframescontext
static void print_hwframescontext(const GraphPrintContext *gpc, const AVHWFramesContext *hw_frames_context)
Definition: graphprint.c:213
AVHWFramesContext::height
int height
Definition: hwcontext.h:220
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:60
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:654
AVCodecDescriptor
This struct describes the properties of a single codec described by an AVCodecID.
Definition: codec_desc.h:38
SECTION_ID_OUTPUTSTREAMS
@ SECTION_ID_OUTPUTSTREAMS
Definition: graphprint.c:68
print_filtergraph_single
static void print_filtergraph_single(GraphPrintContext *gpc, FilterGraph *fg, AVFilterGraph *graph)
Definition: graphprint.c:474
AVTextFormatter
Definition: avtextformat.h:97
FilterGraph::outputs
OutputFilter ** outputs
Definition: ffmpeg.h:420
GraphPrintContext::is_diagram
int is_diagram
Definition: graphprint.c:129
print_filtergraphs
int print_filtergraphs(FilterGraph **graphs, int nb_graphs, InputFile **ifiles, int nb_ifiles, OutputFile **ofiles, int nb_ofiles)
Definition: graphprint.c:1074
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
avtextwriter_context_close
int avtextwriter_context_close(AVTextWriterContext **pwctx)
Definition: avtextformat.c:606
AVTextFormatSection
Definition: avtextformat.h:41
OutputFilter::linklabel
uint8_t * linklabel
Definition: ffmpeg.h:404
InputFilter
Definition: ffmpeg.h:373
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:494
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:618
avtext_context_open
int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *formatter, AVTextWriterContext *writer_context, const char *args, const AVTextFormatSection *sections, int nb_sections, AVTextFormatOptions options, char *show_data_hash)
Definition: avtextformat.c:127
print_graphs_file
char * print_graphs_file
Definition: ffmpeg_opt.c:81
GraphPrintContext
Definition: graphprint.c:123
InputFilter::linklabel
uint8_t * linklabel
Definition: ffmpeg.h:387
av_hwdevice_get_type_name
const char * av_hwdevice_get_type_name(enum AVHWDeviceType type)
Get the string name of an AVHWDeviceType.
Definition: hwcontext.c:120
key
const char * key
Definition: hwcontext_opencl.c:189
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
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
print_fmt
#define print_fmt(k, f,...)
Definition: graphprint.c:146
SECTION_ID_FILTER_OUTPUT
@ SECTION_ID_FILTER_OUTPUT
Definition: graphprint.c:60
av_color_range_name
const char * av_color_range_name(enum AVColorRange range)
Definition: pixdesc.c:3772
AVFormatContext
Format I/O context.
Definition: avformat.h:1263
SECTION_ID_FILTERGRAPH
@ SECTION_ID_FILTERGRAPH
Definition: graphprint.c:50
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:767
get_filterpad_name
static const char * get_filterpad_name(const AVFilterPad *pad)
Definition: graphprint.c:379
NULL
#define NULL
Definition: coverity.c:32
print_val
#define print_val(k, v, u)
Definition: graphprint.c:144
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:213
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
SECTION_ID_ENCODER
@ SECTION_ID_ENCODER
Definition: graphprint.c:75
AVFilterGraph::filters
AVFilterContext ** filters
Definition: avfilter.h:591
SECTION_ID_INPUTFILE
@ SECTION_ID_INPUTFILE
Definition: graphprint.c:63
AVFilterContext::name
char * name
name of this filter instance
Definition: avfilter.h:279
avfilter_link_get_hw_frames_ctx
AVBufferRef * avfilter_link_get_hw_frames_ctx(AVFilterLink *link)
Get the hardware frames context of a filter link.
Definition: avfilter.c:997
AVTextFormatContext::formatter
const AVTextFormatter * formatter
the AVTextFormatter of which this is an instance
Definition: avtextformat.h:135
AVFilterGraph
Definition: avfilter.h:589
OutputFile::index
int index
Definition: ffmpeg.h:708
sanitize_char
static char sanitize_char(const char c)
Definition: graphprint.c:325
avtext_get_formatter_by_name
const AVTextFormatter * avtext_get_formatter_by_name(const char *name)
Definition: avtextformat.c:684
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:743
FilterGraph::nb_outputs
int nb_outputs
Definition: ffmpeg.h:421
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
InputStream::par
AVCodecParameters * par
Codec parameters - to be used by the decoding/streamcopy code.
Definition: ffmpeg.h:499
print_graphs_format
char * print_graphs_format
Definition: ffmpeg_opt.c:82
OutputFile::streams
OutputStream ** streams
Definition: ffmpeg.h:712
init_graphprint
static int init_graphprint(GraphPrintContext **pgpc, AVBPrint *target_buf)
Definition: graphprint.c:866
FilterGraph
Definition: ffmpeg.h:414
InputFilter::filter
AVFilterContext * filter
Definition: ffmpeg.h:381
SECTION_ID_FILTERGRAPHS
@ SECTION_ID_FILTERGRAPHS
Definition: graphprint.c:49
OutputFilter::output_name
char * output_name
Definition: ffmpeg.h:399
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AVMediaType
AVMediaType
Definition: avutil.h:198
GraphPrintContext::pbuf
AVBPrint pbuf
Definition: graphprint.c:132
print_streams
static int print_streams(GraphPrintContext *gpc, InputFile **ifiles, int nb_ifiles, OutputFile **ofiles, int nb_ofiles)
Definition: graphprint.c:583
GraphPrintContext::diagram_config
AVDiagramConfig diagram_config
Definition: graphprint.c:126
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
get_extension
static char * get_extension(const char *url)
Definition: graphprint.c:170
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
GraphPrintContext::wctx
AVTextWriterContext * wctx
Definition: graphprint.c:125
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
AVTextFormatter::name
const char * name
Definition: avtextformat.h:100
AVFrame::sample_rate
int sample_rate
Sample rate of the audio data.
Definition: frame.h:598
avtext_print_section_footer
void avtext_print_section_footer(AVTextFormatContext *tctx)
Definition: avtextformat.c:266
AV_TEXTFORMAT_SECTION_FLAG_IS_SHAPE
#define AV_TEXTFORMAT_SECTION_FLAG_IS_SHAPE
...
Definition: avtextformat.h:51
AVFrame::time_base
AVRational time_base
Time base for the timestamps in this frame.
Definition: frame.h:552
OutputFile::url
const char * url
Definition: ffmpeg.h:710
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:522
buffer.h
FilterGraph::graph_print_buf
struct AVBPrint graph_print_buf
Definition: ffmpeg.h:429
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:206
OutputFilter::filter
AVFilterContext * filter
Definition: ffmpeg.h:397
print_sanizied_id
static void print_sanizied_id(const GraphPrintContext *gpc, const char *key, const char *id_str, int skip_prefix)
Definition: graphprint.c:332
AVTextFormatter::flags
int flags
a combination or AV_TEXTFORMAT__FLAG_*
Definition: avtextformat.h:109
SectionID
SectionID
Definition: graphprint.c:47
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:233
SECTION_ID_DECODERS
@ SECTION_ID_DECODERS
Definition: graphprint.c:72
print_id
#define print_id(k, v)
Definition: graphprint.c:137
OutputFilter::type
enum AVMediaType type
Definition: ffmpeg.h:408
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:68
AVTextFormatSectionContext::context_id
char * context_id
Definition: avtextformat.h:35
SECTION_ID_STREAMLINKS
@ SECTION_ID_STREAMLINKS
Definition: graphprint.c:70
print_q
#define print_q(k, v, s)
Definition: graphprint.c:141
AVPixFmtDescriptor::alias
const char * alias
Alternative comma-separated names.
Definition: pixdesc.h:110
AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS
#define AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS
the section may contain a variable number of fields with variable keys.
Definition: avtextformat.h:47
SECTION_ID_INPUTFILES
@ SECTION_ID_INPUTFILES
Definition: graphprint.c:62
SECTION_ID_GRAPH_OUTPUTS
@ SECTION_ID_GRAPH_OUTPUTS
Definition: graphprint.c:53
common.h
AVStream::av_class
const AVClass * av_class
A class for AVOptions.
Definition: avformat.h:748
print_graphs
int print_graphs
Definition: ffmpeg_opt.c:80
av_toupper
static av_const int av_toupper(int c)
Locale-independent conversion of ASCII characters to uppercase.
Definition: avstring.h:227
AVMEDIA_TYPE_ATTACHMENT
@ AVMEDIA_TYPE_ATTACHMENT
Opaque data information usually sparse.
Definition: avutil.h:204
InputFile::ctx
AVFormatContext * ctx
Definition: ffmpeg.h:534
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVTextFormatSectionContext::context_flags
int context_flags
Definition: avtextformat.h:37
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:179
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:703
SECTION_ID_FILTERS
@ SECTION_ID_FILTERS
Definition: graphprint.c:55
SECTION_ID_INPUTSTREAM
@ SECTION_ID_INPUTSTREAM
Definition: graphprint.c:65
print_int_opt
#define print_int_opt(k, v)
Definition: graphprint.c:140
print_link
static void print_link(GraphPrintContext *gpc, AVFilterLink *link)
Definition: graphprint.c:248
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:118
InputStream::decoder
Decoder * decoder
Definition: ffmpeg.h:500
ret
ret
Definition: filter_design.txt:187
AVHWDeviceContext::type
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition: hwcontext.h:75
AVFormatContext::oformat
const struct AVOutputFormat * oformat
The output container format.
Definition: avformat.h:1282
AVHWFramesContext::device_ctx
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:137
SECTION_ID_FILTER_OUTPUTS
@ SECTION_ID_FILTER_OUTPUTS
Definition: graphprint.c:59
AV_TEXTFORMAT_SECTION_FLAG_IS_WRAPPER
#define AV_TEXTFORMAT_SECTION_FLAG_IS_WRAPPER
the section only contains other sections, but has no data at its own level
Definition: avtextformat.h:45
InputFile::streams
InputStream ** streams
Definition: ffmpeg.h:548
print_str
#define print_str(k, v)
Definition: graphprint.c:142
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:122
dict.h
AVFrame::sample_aspect_ratio
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:532
AV_TEXTFORMAT_SECTION_FLAG_HAS_LINKS
#define AV_TEXTFORMAT_SECTION_FLAG_HAS_LINKS
...
Definition: avtextformat.h:52
GraphPrintContext::opt_flags
int opt_flags
Definition: graphprint.c:130
AVDiagramConfig::html_template
const char * html_template
Definition: tf_mermaid.h:32
GraphPrintContext::tfc
AVTextFormatContext * tfc
Definition: graphprint.c:124
prefix_num
static atomic_int prefix_num
Definition: graphprint.c:159
av_get_media_type_string
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition: utils.c:28
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:750
AVTextFormatOptions::show_optional_fields
int show_optional_fields
Definition: avtextformat.h:125
AVTextFormatOptions
Definition: avtextformat.h:115
AVRational::den
int den
Denominator.
Definition: rational.h:60
print_hwdevicecontext
static void print_hwdevicecontext(const GraphPrintContext *gpc, const AVHWDeviceContext *hw_device_context)
Definition: graphprint.c:202
avfilter.h
av_bprint_clear
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
Definition: bprint.c:227
print_id_noprefix
#define print_id_noprefix(k, v)
Definition: graphprint.c:138
uninit_graphprint
static void uninit_graphprint(GraphPrintContext *gpc)
Definition: graphprint.c:852
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
AVFilterContext
An instance of a filter.
Definition: avfilter.h:274
OutputFilter
Definition: ffmpeg.h:390
SECTION_ID_ROOT
@ SECTION_ID_ROOT
Definition: graphprint.c:48
FF_RESOURCE_GRAPH_HTML
@ FF_RESOURCE_GRAPH_HTML
Definition: resman.h:34
AVHWFramesContext::initial_pool_size
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:190
AVTextFormatOptions::show_value_unit
int show_value_unit
Definition: avtextformat.h:126
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
avio_open2
int avio_open2(AVIOContext **s, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
Create and initialize a AVIOContext for accessing the resource indicated by url.
Definition: avio.c:497
ffmpeg_mux.h
SECTION_ID_STREAMLINK
@ SECTION_ID_STREAMLINK
Definition: graphprint.c:71
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
InputStream::index
int index
Definition: ffmpeg.h:489
SECTION_ID_FILTER_INPUT
@ SECTION_ID_FILTER_INPUT
Definition: graphprint.c:58
AVDictionaryEntry
Definition: dict.h:90
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:57
avio_closep
int avio_closep(AVIOContext **s)
Close the resource accessed by the AVIOContext *s, free it and set the pointer pointing to it to NULL...
Definition: avio.c:655
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:86
OutputStream
Definition: mux.c:53
hwcontext.h
av_diagram_init
void av_diagram_init(AVTextFormatContext *tfc, AVDiagramConfig *diagram_config)
Definition: tf_mermaid.c:171
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
graphprint.h
print_fmt_opt
#define print_fmt_opt(k, f,...)
Definition: graphprint.c:152
av_bprint_chars
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:130
avcodec_descriptor_get
const AVCodecDescriptor * avcodec_descriptor_get(enum AVCodecID id)
Definition: codec_desc.c:3888
AVDictionaryEntry::value
char * value
Definition: dict.h:92
AVFilterGraph::nb_filters
unsigned nb_filters
Definition: avfilter.h:592
SECTION_ID_OUTPUTFILE
@ SECTION_ID_OUTPUTFILE
Definition: graphprint.c:67
avstring.h
AVFilterContext::filter
const AVFilter * filter
the AVFilter of which this is an instance
Definition: avfilter.h:277
AVClass::item_name
const char *(* item_name)(void *ctx)
A pointer to a function which returns the name of a context instance ctx associated with the class.
Definition: log.h:87
print_filtergraphs_priv
static int print_filtergraphs_priv(FilterGraph **graphs, int nb_graphs, InputFile **ifiles, int nb_ifiles, OutputFile **ofiles, int nb_ofiles)
Definition: graphprint.c:989
InputFile::nb_streams
int nb_streams
Definition: ffmpeg.h:549
GraphPrintContext::id_prefix_num
int id_prefix_num
Definition: graphprint.c:128
av_strndup
char * av_strndup(const char *s, size_t len)
Duplicate a substring of a string.
Definition: mem.c:284
avtext_context_close
int avtext_context_close(AVTextFormatContext **ptctx)
Definition: avtextformat.c:102
av_bprint_append_data
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
Append data to a print buffer.
Definition: bprint.c:148
InputStream::dec
const AVCodec * dec
Definition: ffmpeg.h:501
snprintf
#define snprintf
Definition: snprintf.h:34
AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY
#define AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY
the section contains an array of elements of the same type
Definition: avtextformat.h:46
src
#define src
Definition: vp8dsp.c:248
SECTION_ID_FILTER_INPUTS
@ SECTION_ID_FILTER_INPUTS
Definition: graphprint.c:57
GraphPrintContext::skip_buffer_filters
int skip_buffer_filters
Definition: graphprint.c:131
av_x_if_null
static void * av_x_if_null(const void *p, const void *x)
Return x default pointer in case p is NULL.
Definition: avutil.h:311
av_get_pix_fmt_name
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:3376
OutputFile
Definition: ffmpeg.h:705
tf_mermaid.h
avtext_print_section_header
void avtext_print_section_header(AVTextFormatContext *tctx, const void *data, int section_id)
Definition: avtextformat.c:248
InputFilter::input_name
char * input_name
Definition: ffmpeg.h:383