FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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/pixdesc.h"
37 #include "libavutil/dict.h"
38 #include "libavutil/common.h"
39 #include "libavfilter/avfilter.h"
40 #include "libavutil/buffer.h"
41 #include "libavutil/hwcontext.h"
45 
46 typedef enum {
75 } SectionID;
76 
77 static struct AVTextFormatSection sections[] = {
79 
82 
84  [SECTION_ID_GRAPH_INPUT] = { SECTION_ID_GRAPH_INPUT, "graph_input", 0, { -1 }, .id_key = "filter_id" },
85 
87  [SECTION_ID_GRAPH_OUTPUT] = { SECTION_ID_GRAPH_OUTPUT, "graph_output", 0, { -1 }, .id_key = "filter_id" },
88 
91 
93  [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" },
94 
96  [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" },
97 
98  [SECTION_ID_HWFRAMESCONTEXT] = { SECTION_ID_HWFRAMESCONTEXT, "hw_frames_context", 0, { -1 }, },
99 
102 
105 
108 
111 
113  [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" },
114 
116  [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" },
117 
119  [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" },
120 };
121 
122 typedef struct GraphPrintContext {
126 
131  AVBPrint pbuf;
132 
134 
135 /* Text Format API Shortcuts */
136 #define print_id(k, v) print_sanizied_id(gpc, k, v, 0)
137 #define print_id_noprefix(k, v) print_sanizied_id(gpc, k, v, 1)
138 #define print_int(k, v) avtext_print_integer(tfc, k, v, 0)
139 #define print_int_opt(k, v) avtext_print_integer(tfc, k, v, gpc->opt_flags)
140 #define print_q(k, v, s) avtext_print_rational(tfc, k, v, s)
141 #define print_str(k, v) avtext_print_string(tfc, k, v, 0)
142 #define print_str_opt(k, v) avtext_print_string(tfc, k, v, gpc->opt_flags)
143 #define print_val(k, v, u) avtext_print_unit_int(tfc, k, v, u)
144 
145 #define print_fmt(k, f, ...) do { \
146  av_bprint_clear(&gpc->pbuf); \
147  av_bprintf(&gpc->pbuf, f, __VA_ARGS__); \
148  avtext_print_string(tfc, k, gpc->pbuf.str, 0); \
149 } while (0)
150 
151 #define print_fmt_opt(k, f, ...) do { \
152  av_bprint_clear(&gpc->pbuf); \
153  av_bprintf(&gpc->pbuf, f, __VA_ARGS__); \
154  avtext_print_string(tfc, k, gpc->pbuf.str, gpc->opt_flags); \
155 } while (0)
156 
157 
159 
160 static inline char *upcase_string(char *dst, size_t dst_size, const char *src)
161 {
162  unsigned i;
163  for (i = 0; src[i] && i < dst_size - 1; i++)
164  dst[i] = (char)av_toupper(src[i]);
165  dst[i] = 0;
166  return dst;
167 }
168 
169 static char *get_extension(const char *url)
170 {
171  const char *dot = NULL;
172  const char *sep = NULL;
173  const char *end;
174 
175  if (!url)
176  return NULL;
177 
178  /* Stop at the first query ('?') or fragment ('#') delimiter so they
179  * are not considered part of the path. */
180  end = strpbrk(url, "?#");
181  if (!end)
182  end = url + strlen(url);
183 
184  /* Scan the path component only. */
185  for (const char *p = url; p < end; p++) {
186  if (*p == '.')
187  dot = p;
188  else if (*p == '/' || *p == '\\')
189  sep = p;
190  }
191 
192  /* Validate that we have a proper extension. */
193  if (dot && dot != url && (!sep || dot > sep + 1) && (dot + 1) < end) {
194  /* Use FFmpeg helper to duplicate the substring. */
195  return av_strndup(dot + 1, end - (dot + 1));
196  }
197 
198  return NULL;
199 }
200 
201 static void print_hwdevicecontext(const GraphPrintContext *gpc, const AVHWDeviceContext *hw_device_context)
202 {
203  AVTextFormatContext *tfc = gpc->tfc;
204 
205  if (!hw_device_context)
206  return;
207 
208  print_int_opt("has_hw_device_context", 1);
209  print_str_opt("hw_device_type", av_hwdevice_get_type_name(hw_device_context->type));
210 }
211 
212 static void print_hwframescontext(const GraphPrintContext *gpc, const AVHWFramesContext *hw_frames_context)
213 {
214  AVTextFormatContext *tfc = gpc->tfc;
215  const AVPixFmtDescriptor *pix_desc_hw;
216  const AVPixFmtDescriptor *pix_desc_sw;
217 
218  if (!hw_frames_context || !hw_frames_context->device_ctx)
219  return;
220 
222 
223  print_int_opt("has_hw_frames_context", 1);
224  print_str("hw_device_type", av_hwdevice_get_type_name(hw_frames_context->device_ctx->type));
225 
226  pix_desc_hw = av_pix_fmt_desc_get(hw_frames_context->format);
227  if (pix_desc_hw) {
228  print_str("hw_pixel_format", pix_desc_hw->name);
229  if (pix_desc_hw->alias)
230  print_str_opt("hw_pixel_format_alias", pix_desc_hw->alias);
231  }
232 
233  pix_desc_sw = av_pix_fmt_desc_get(hw_frames_context->sw_format);
234  if (pix_desc_sw) {
235  print_str("sw_pixel_format", pix_desc_sw->name);
236  if (pix_desc_sw->alias)
237  print_str_opt("sw_pixel_format_alias", pix_desc_sw->alias);
238  }
239 
240  print_int_opt("width", hw_frames_context->width);
241  print_int_opt("height", hw_frames_context->height);
242  print_int_opt("initial_pool_size", hw_frames_context->initial_pool_size);
243 
244  avtext_print_section_footer(tfc); // SECTION_ID_HWFRAMESCONTEXT
245 }
246 
248 {
249  AVTextFormatContext *tfc = gpc->tfc;
250  AVBufferRef *hw_frames_ctx;
251  char layout_string[64];
252 
253  if (!link)
254  return;
255 
256  hw_frames_ctx = avfilter_link_get_hw_frames_ctx(link);
257 
258  print_str_opt("media_type", av_get_media_type_string(link->type));
259 
260  switch (link->type) {
261  case AVMEDIA_TYPE_VIDEO:
262 
263  if (hw_frames_ctx && hw_frames_ctx->data) {
264  AVHWFramesContext * hwfctx = (AVHWFramesContext *)hw_frames_ctx->data;
265  const AVPixFmtDescriptor *pix_desc_hw = av_pix_fmt_desc_get(hwfctx->format);
266  const AVPixFmtDescriptor *pix_desc_sw = av_pix_fmt_desc_get(hwfctx->sw_format);
267  if (pix_desc_hw && pix_desc_sw)
268  print_fmt("format", "%s | %s", pix_desc_hw->name, pix_desc_sw->name);
269  } else {
271  }
272 
273  if (link->w && link->h) {
274  if (tfc->show_value_unit) {
275  print_fmt("size", "%dx%d", link->w, link->h);
276  } else {
277  print_int("width", link->w);
278  print_int("height", link->h);
279  }
280  }
281 
282  print_q("sar", link->sample_aspect_ratio, ':');
283 
286 
288  print_str("color_space", av_color_space_name(link->colorspace));
289  break;
290 
292  ////print_str("format", av_x_if_null(av_get_subtitle_fmt_name(link->format), "?"));
293 
294  if (link->w && link->h) {
295  if (tfc->show_value_unit) {
296  print_fmt("size", "%dx%d", link->w, link->h);
297  } else {
298  print_int("width", link->w);
299  print_int("height", link->h);
300  }
301  }
302 
303  break;
304 
305  case AVMEDIA_TYPE_AUDIO:
306  av_channel_layout_describe(&link->ch_layout, layout_string, sizeof(layout_string));
307  print_str("channel_layout", layout_string);
308  print_val("channels", link->ch_layout.nb_channels, "ch");
309  if (tfc->show_value_unit)
310  print_fmt("sample_rate", "%d.1 kHz", link->sample_rate / 1000);
311  else
312  print_val("sample_rate", link->sample_rate, "Hz");
313 
314  break;
315  }
316 
317  print_fmt_opt("sample_rate", "%d/%d", link->time_base.num, link->time_base.den);
318 
319  if (hw_frames_ctx && hw_frames_ctx->data)
320  print_hwframescontext(gpc, (AVHWFramesContext *)hw_frames_ctx->data);
321  av_buffer_unref(&hw_frames_ctx);
322 }
323 
324 static char sanitize_char(const char c)
325 {
326  if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
327  return c;
328  return '_';
329 }
330 
331 static void print_sanizied_id(const GraphPrintContext *gpc, const char *key, const char *id_str, int skip_prefix)
332 {
333  AVTextFormatContext *tfc = gpc->tfc;
334  AVBPrint buf;
335 
336  if (!key || !id_str)
337  return;
338 
340 
341  if (!skip_prefix)
342  av_bprintf(&buf, "G%d_", gpc->id_prefix_num);
343 
344  // sanizize section id
345  for (const char *p = id_str; *p; p++)
346  av_bprint_chars(&buf, sanitize_char(*p), 1);
347 
348  print_str(key, buf.str);
349 
350  av_bprint_finalize(&buf, NULL);
351 }
352 
353 static void print_section_header_id(const GraphPrintContext *gpc, int section_id, const char *id_str, int skip_prefix)
354 {
355  AVTextFormatContext *tfc = gpc->tfc;
356  AVTextFormatSectionContext sec_ctx = { 0 };
357  AVBPrint buf;
358 
359  if (!id_str)
360  return;
361 
363 
364  if (!skip_prefix)
365  av_bprintf(&buf, "G%d_", gpc->id_prefix_num);
366 
367  // sanizize section id
368  for (const char *p = id_str; *p; p++)
369  av_bprint_chars(&buf, sanitize_char(*p), 1);
370 
371  sec_ctx.context_id = buf.str;
372 
373  avtext_print_section_header(tfc, &sec_ctx, section_id);
374 
375  av_bprint_finalize(&buf, NULL);
376 }
377 
378 static const char *get_filterpad_name(const AVFilterPad *pad)
379 {
380  return pad ? avfilter_pad_get_name(pad, 0) : "pad";
381 }
382 
383 static void print_filter(GraphPrintContext *gpc, const AVFilterContext *filter, AVDictionary *input_map, AVDictionary *output_map)
384 {
385  AVTextFormatContext *tfc = gpc->tfc;
386  AVTextFormatSectionContext sec_ctx = { 0 };
387 
389 
390  ////print_id("filter_id", filter->name);
391 
392  if (filter->filter) {
393  print_str("filter_name", filter->filter->name);
394  print_str_opt("description", filter->filter->description);
395  print_int_opt("nb_inputs", filter->nb_inputs);
396  print_int_opt("nb_outputs", filter->nb_outputs);
397  }
398 
399  if (filter->hw_device_ctx) {
400  AVHWDeviceContext *device_context = (AVHWDeviceContext *)filter->hw_device_ctx->data;
401  print_hwdevicecontext(gpc, device_context);
402  if (filter->extra_hw_frames > 0)
403  print_int("extra_hw_frames", filter->extra_hw_frames);
404  }
405 
407 
408  for (unsigned i = 0; i < filter->nb_inputs; i++) {
409  AVDictionaryEntry *dic_entry;
410  AVFilterLink *link = filter->inputs[i];
411 
412  sec_ctx.context_type = av_get_media_type_string(link->type);
414  sec_ctx.context_type = NULL;
415 
416  print_int_opt("input_index", i);
417  print_str_opt("pad_name", get_filterpad_name(link->dstpad));;
418 
419  dic_entry = av_dict_get(input_map, link->src->name, NULL, 0);
420  if (dic_entry) {
421  char buf[256];
422  (void)snprintf(buf, sizeof(buf), "in_%s", dic_entry->value);
423  print_id_noprefix("source_filter_id", buf);
424  } else {
425  print_id("source_filter_id", link->src->name);
426  }
427 
428  print_str_opt("source_pad_name", get_filterpad_name(link->srcpad));
429  print_id("filter_id", filter->name);
430 
431  print_link(gpc, link);
432 
433  avtext_print_section_footer(tfc); // SECTION_ID_FILTER_INPUT
434  }
435 
436  avtext_print_section_footer(tfc); // SECTION_ID_FILTER_INPUTS
437 
439 
440  for (unsigned i = 0; i < filter->nb_outputs; i++) {
441  AVDictionaryEntry *dic_entry;
442  AVFilterLink *link = filter->outputs[i];
443  char buf[256];
444 
445  sec_ctx.context_type = av_get_media_type_string(link->type);
447  sec_ctx.context_type = NULL;
448 
449  dic_entry = av_dict_get(output_map, link->dst->name, NULL, 0);
450  if (dic_entry) {
451  (void)snprintf(buf, sizeof(buf), "out_%s", dic_entry->value);
452  print_id_noprefix("dest_filter_id", buf);
453  } else {
454  print_id("dest_filter_id", link->dst->name);
455  }
456 
457  print_int_opt("output_index", i);
458  print_str_opt("pad_name", get_filterpad_name(link->srcpad));
459  ////print_id("dest_filter_id", link->dst->name);
460  print_str_opt("dest_pad_name", get_filterpad_name(link->dstpad));
461  print_id("filter_id", filter->name);
462 
463  print_link(gpc, link);
464 
465  avtext_print_section_footer(tfc); // SECTION_ID_FILTER_OUTPUT
466  }
467 
468  avtext_print_section_footer(tfc); // SECTION_ID_FILTER_OUTPUTS
469 
470  avtext_print_section_footer(tfc); // SECTION_ID_FILTER
471 }
472 
473 static void init_sections(void)
474 {
475  for (unsigned i = 0; i < FF_ARRAY_ELEMS(sections); i++)
476  sections[i].show_all_entries = 1;
477 }
478 
480 {
481  AVTextFormatContext *tfc = gpc->tfc;
482  AVDictionary *input_map = NULL;
483  AVDictionary *output_map = NULL;
484 
485  print_int("graph_index", fg->index);
486  print_fmt("name", "Graph %d.%d", gpc->id_prefix_num, fg->index);
487  print_fmt("id", "Graph_%d_%d", gpc->id_prefix_num, fg->index);
488  print_str("description", fg->graph_desc);
489 
490  print_section_header_id(gpc, SECTION_ID_GRAPH_INPUTS, "Input_File", 0);
491 
492  for (int i = 0; i < fg->nb_inputs; i++) {
493  InputFilter *ifilter = fg->inputs[i];
494  enum AVMediaType media_type = ifilter->type;
495 
497 
498  print_int("input_index", ifilter->index);
499 
500  if (ifilter->linklabel)
501  print_str("link_label", (const char*)ifilter->linklabel);
502 
503  if (ifilter->filter) {
504  print_id("filter_id", ifilter->filter->name);
505  print_str("filter_name", ifilter->filter->filter->name);
506  }
507 
508  if (ifilter->linklabel && ifilter->filter)
509  av_dict_set(&input_map, ifilter->filter->name, (const char *)ifilter->linklabel, 0);
510  else if (ifilter->input_name && ifilter->filter)
511  av_dict_set(&input_map, ifilter->filter->name, (const char *)ifilter->input_name, 0);
512 
513  print_str("media_type", av_get_media_type_string(media_type));
514 
515  avtext_print_section_footer(tfc); // SECTION_ID_GRAPH_INPUT
516  }
517 
518  avtext_print_section_footer(tfc); // SECTION_ID_GRAPH_INPUTS
519 
520  print_section_header_id(gpc, SECTION_ID_GRAPH_OUTPUTS, "Output_File", 0);
521 
522  for (int i = 0; i < fg->nb_outputs; i++) {
523  OutputFilter *ofilter = fg->outputs[i];
524 
526 
527  print_int("output_index", ofilter->index);
528 
529  print_str("name", ofilter->output_name);
530 
531  if (fg->outputs[i]->linklabel)
532  print_str("link_label", (const char*)fg->outputs[i]->linklabel);
533 
534  if (ofilter->filter) {
535  print_id("filter_id", ofilter->filter->name);
536  print_str("filter_name", ofilter->filter->filter->name);
537  }
538 
539  if (ofilter->output_name && ofilter->filter)
540  av_dict_set(&output_map, ofilter->filter->name, ofilter->output_name, 0);
541 
542 
543  print_str("media_type", av_get_media_type_string(ofilter->type));
544 
545  avtext_print_section_footer(tfc); // SECTION_ID_GRAPH_OUTPUT
546  }
547 
548  avtext_print_section_footer(tfc); // SECTION_ID_GRAPH_OUTPUTS
549 
550  if (graph) {
551  AVTextFormatSectionContext sec_ctx = { 0 };
552 
553  sec_ctx.context_id = av_asprintf("Graph_%d_%d", gpc->id_prefix_num, fg->index);
554 
556 
557  if (gpc->is_diagram) {
558  print_fmt("name", "Graph %d.%d", gpc->id_prefix_num, fg->index);
559  print_str("description", fg->graph_desc);
560  print_str("id", sec_ctx.context_id);
561  }
562 
563  av_freep(&sec_ctx.context_id);
564 
565  for (unsigned i = 0; i < graph->nb_filters; i++) {
566  AVFilterContext *filter = graph->filters[i];
567 
568  if (gpc->skip_buffer_filters) {
569  if (av_dict_get(input_map, filter->name, NULL, 0))
570  continue;
571  if (av_dict_get(output_map, filter->name, NULL, 0))
572  continue;
573  }
574 
575  sec_ctx.context_id = filter->name;
576 
577  print_filter(gpc, filter, input_map, output_map);
578  }
579 
580  avtext_print_section_footer(tfc); // SECTION_ID_FILTERS
581  }
582 
583  // Clean up dictionaries
584  av_dict_free(&input_map);
585  av_dict_free(&output_map);
586 }
587 
588 static int print_streams(GraphPrintContext *gpc, InputFile **ifiles, int nb_ifiles, OutputFile **ofiles, int nb_ofiles)
589 {
590  AVTextFormatContext *tfc = gpc->tfc;
591  AVBPrint buf;
592  AVTextFormatSectionContext sec_ctx = { 0 };
593 
595 
597 
598  for (int n = nb_ifiles - 1; n >= 0; n--) {
599  InputFile *ifi = ifiles[n];
600  AVFormatContext *fc = ifi->ctx;
601 
602  sec_ctx.context_id = av_asprintf("Input_%d", n);
604  av_freep(&sec_ctx.context_id);
605 
606  print_fmt("index", "%d", ifi->index);
607 
608  if (fc) {
609  print_str("demuxer_name", fc->iformat->name);
610  if (fc->url) {
611  char *extension = get_extension(fc->url);
612  if (extension) {
613  print_str("file_extension", extension);
614  av_freep(&extension);
615  }
616  print_str("url", fc->url);
617  }
618  }
619 
620  sec_ctx.context_id = av_asprintf("InputStreams_%d", n);
621 
623 
624  av_freep(&sec_ctx.context_id);
625 
626  for (int i = 0; i < ifi->nb_streams; i++) {
627  InputStream *ist = ifi->streams[i];
628  const AVCodecDescriptor *codec_desc;
629 
630  if (!ist || !ist->par)
631  continue;
632 
633  codec_desc = avcodec_descriptor_get(ist->par->codec_id);
634 
635  sec_ctx.context_id = av_asprintf("r_in_%d_%d", n, i);
636 
638 
640  av_freep(&sec_ctx.context_id);
641  sec_ctx.context_type = NULL;
642 
643  av_bprint_clear(&buf);
644 
645  print_fmt("id", "r_in_%d_%d", n, i);
646 
647  if (codec_desc && codec_desc->name) {
648  ////av_bprintf(&buf, "%s", upcase_string(char_buf, sizeof(char_buf), codec_desc->long_name));
649  av_bprintf(&buf, "%s", codec_desc->long_name);
650  } else if (ist->dec) {
651  char char_buf[256];
652  av_bprintf(&buf, "%s", upcase_string(char_buf, sizeof(char_buf), ist->dec->name));
653  } else if (ist->par->codec_type == AVMEDIA_TYPE_ATTACHMENT) {
654  av_bprintf(&buf, "%s", "Attachment");
655  } else if (ist->par->codec_type == AVMEDIA_TYPE_DATA) {
656  av_bprintf(&buf, "%s", "Data");
657  }
658 
659  print_fmt("name", "%s", buf.str);
660  print_fmt("index", "%d", ist->index);
661 
662  if (ist->dec)
664 
665  avtext_print_section_footer(tfc); // SECTION_ID_INPUTSTREAM
666  }
667 
668  avtext_print_section_footer(tfc); // SECTION_ID_INPUTSTREAMS
669  avtext_print_section_footer(tfc); // SECTION_ID_INPUTFILE
670  }
671 
672  avtext_print_section_footer(tfc); // SECTION_ID_INPUTFILES
673 
674 
675  print_section_header_id(gpc, SECTION_ID_DECODERS, "Decoders", 0);
676 
677  for (int n = 0; n < nb_ifiles; n++) {
678  InputFile *ifi = ifiles[n];
679 
680  for (int i = 0; i < ifi->nb_streams; i++) {
681  InputStream *ist = ifi->streams[i];
682 
683  if (!ist->decoder)
684  continue;
685 
686  sec_ctx.context_id = av_asprintf("in_%d_%d", n, i);
688  sec_ctx.context_flags = 2;
689 
691  av_freep(&sec_ctx.context_id);
692  sec_ctx.context_type = NULL;
693  sec_ctx.context_flags = 0;
694 
695  av_bprint_clear(&buf);
696 
697  print_fmt("source_id", "r_in_%d_%d", n, i);
698  print_fmt("id", "in_%d_%d", n, i);
699 
700  ////av_bprintf(&buf, "%s", upcase_string(char_buf, sizeof(char_buf), ist->dec->name));
701  print_fmt("name", "%s", ist->dec->name);
702 
704 
705  avtext_print_section_footer(tfc); // SECTION_ID_DECODER
706  }
707  }
708 
709  avtext_print_section_footer(tfc); // SECTION_ID_DECODERS
710 
711 
712  print_section_header_id(gpc, SECTION_ID_ENCODERS, "Encoders", 0);
713 
714  for (int n = 0; n < nb_ofiles; n++) {
715  OutputFile *of = ofiles[n];
716 
717  for (int i = 0; i < of->nb_streams; i++) {
718  OutputStream *ost = of->streams[i];
719  ////const AVCodecDescriptor *codec_desc;
720 
721  if (!ost || !ost->st || !ost->st->codecpar || !ost->enc)
722  continue;
723 
724  ////codec_desc = avcodec_descriptor_get(ost->st->codecpar->codec_id);
725 
726  sec_ctx.context_id = av_asprintf("out__%d_%d", n, i);
727  sec_ctx.context_type = av_get_media_type_string(ost->type);
728  sec_ctx.context_flags = 2;
729 
731  av_freep(&sec_ctx.context_id);
732  sec_ctx.context_type = NULL;
733  sec_ctx.context_flags = 0;
734 
735  av_bprint_clear(&buf);
736 
737  print_fmt("id", "out__%d_%d", n, i);
738  print_fmt("dest_id", "r_out__%d_%d", n, i);
739 
740  print_fmt("name", "%s", ost->enc->enc_ctx->av_class->item_name(ost->enc->enc_ctx));
741 
742  print_str_opt("media_type", av_get_media_type_string(ost->type));
743 
744  avtext_print_section_footer(tfc); // SECTION_ID_ENCODER
745  }
746  }
747 
748  avtext_print_section_footer(tfc); // SECTION_ID_ENCODERS
749 
750 
752 
753  for (int n = nb_ofiles - 1; n >= 0; n--) {
754  OutputFile *of = ofiles[n];
755  Muxer *muxer = (Muxer *)of;
756 
757  if (!muxer->fc)
758  continue;
759 
760  sec_ctx.context_id = av_asprintf("Output_%d", n);
761 
763 
764  av_freep(&sec_ctx.context_id);
765 
766  ////print_str_opt("index", av_get_media_type_string(of->index));
767  print_fmt("index", "%d", of->index);
768  ////print_str("url", of->url);
769  print_str("muxer_name", muxer->fc->oformat->name);
770  if (of->url) {
771  char *extension = get_extension(of->url);
772  if (extension) {
773  print_str("file_extension", extension);
774  av_freep(&extension);
775  }
776  print_str("url", of->url);
777  }
778 
779  sec_ctx.context_id = av_asprintf("OutputStreams_%d", n);
780 
782 
783  av_freep(&sec_ctx.context_id);
784 
785  for (int i = 0; i < of->nb_streams; i++) {
786  OutputStream *ost = of->streams[i];
787  const AVCodecDescriptor *codec_desc = avcodec_descriptor_get(ost->st->codecpar->codec_id);
788 
789  sec_ctx.context_id = av_asprintf("r_out__%d_%d", n, i);
790  sec_ctx.context_type = av_get_media_type_string(ost->type);
792  av_freep(&sec_ctx.context_id);
793  sec_ctx.context_type = NULL;
794 
795  av_bprint_clear(&buf);
796 
797  print_fmt("id", "r_out__%d_%d", n, i);
798 
799  if (codec_desc && codec_desc->name) {
800  av_bprintf(&buf, "%s", codec_desc->long_name);
801  } else {
802  av_bprintf(&buf, "%s", "unknown");
803  }
804 
805  print_fmt("name", "%s", buf.str);
806  print_fmt("index", "%d", ost->index);
807 
808  print_str_opt("media_type", av_get_media_type_string(ost->type));
809 
810  avtext_print_section_footer(tfc); // SECTION_ID_OUTPUTSTREAM
811  }
812 
813  avtext_print_section_footer(tfc); // SECTION_ID_OUTPUTSTREAMS
814  avtext_print_section_footer(tfc); // SECTION_ID_OUTPUTFILE
815  }
816 
817  avtext_print_section_footer(tfc); // SECTION_ID_OUTPUTFILES
818 
819 
821 
822  for (int n = 0; n < nb_ofiles; n++) {
823  OutputFile *of = ofiles[n];
824 
825  for (int i = 0; i < of->nb_streams; i++) {
826  OutputStream *ost = of->streams[i];
827 
828  if (ost->ist && !ost->filter) {
829  sec_ctx.context_type = av_get_media_type_string(ost->type);
831  sec_ctx.context_type = NULL;
832 
833  if (ost->enc) {
834  print_fmt("dest_stream_id", "out__%d_%d", n, i);
835  print_fmt("source_stream_id", "in_%d_%d", ost->ist->file->index, ost->ist->index);
836  print_str("operation", "Transcode");
837  } else {
838  print_fmt("dest_stream_id", "r_out__%d_%d", n, i);
839  print_fmt("source_stream_id", "r_in_%d_%d", ost->ist->file->index, ost->ist->index);
840  print_str("operation", "Stream Copy");
841  }
842 
843  print_str_opt("media_type", av_get_media_type_string(ost->type));
844 
845  avtext_print_section_footer(tfc); // SECTION_ID_STREAMLINK
846  }
847  }
848  }
849 
850  avtext_print_section_footer(tfc); // SECTION_ID_STREAMLINKS
851 
852  av_bprint_finalize(&buf, NULL);
853  return 0;
854 }
855 
856 
858 {
859  if (gpc->tfc)
860  avtext_context_close(&gpc->tfc);
861 
862  if (gpc->wctx)
864 
865  // Finalize the print buffer if it was initialized
866  av_bprint_finalize(&gpc->pbuf, NULL);
867 
868  av_freep(&gpc);
869 }
870 
871 static int init_graphprint(GraphPrintContext **pgpc, AVBPrint *target_buf)
872 {
873  const AVTextFormatter *text_formatter;
874  AVTextFormatContext *tfc = NULL;
875  AVTextWriterContext *wctx = NULL;
876  GraphPrintContext *gpc = NULL;
877  int ret;
878 
879  init_sections();
880  *pgpc = NULL;
881 
883 
884  const char *w_name = print_graphs_format ? print_graphs_format : "json";
885 
886  text_formatter = avtext_get_formatter_by_name(w_name);
887  if (!text_formatter) {
888  av_log(NULL, AV_LOG_ERROR, "Unknown filter graph output format with name '%s'\n", w_name);
889  ret = AVERROR(EINVAL);
890  goto fail;
891  }
892 
893  ret = avtextwriter_create_buffer(&wctx, target_buf);
894  if (ret < 0) {
895  av_log(NULL, AV_LOG_ERROR, "avtextwriter_create_buffer failed. Error code %d\n", ret);
896  ret = AVERROR(EINVAL);
897  goto fail;
898  }
899 
900  AVTextFormatOptions tf_options = { .show_optional_fields = -1 };
901  const char *w_args = print_graphs_format ? strchr(print_graphs_format, '=') : NULL;
902  if (w_args)
903  ++w_args; // consume '='
904  ret = avtext_context_open(&tfc, text_formatter, wctx, w_args, sections, FF_ARRAY_ELEMS(sections), tf_options, NULL);
905  if (ret < 0) {
906  goto fail;
907  }
908 
909  gpc = av_mallocz(sizeof(GraphPrintContext));
910  if (!gpc) {
911  ret = AVERROR(ENOMEM);
912  goto fail;
913  }
914 
915  gpc->wctx = wctx;
916  gpc->tfc = tfc;
918 
921  if (gpc->is_diagram) {
922  tfc->show_value_unit = 1;
923  tfc->show_optional_fields = -1;
925  gpc->skip_buffer_filters = 1;
926  ////} else {
927  //// gpc->opt_flags = AV_TEXTFORMAT_PRINT_STRING_OPTIONAL;
928  }
929 
930  if (!strcmp(text_formatter->name, "mermaid") || !strcmp(text_formatter->name, "mermaidhtml")) {
932 
933  if (!strcmp(text_formatter->name, "mermaidhtml"))
935 
936  av_diagram_init(tfc, &gpc->diagram_config);
937  }
938 
939  *pgpc = gpc;
940 
941  return 0;
942 
943 fail:
944  if (tfc)
945  avtext_context_close(&tfc);
946  if (wctx && !tfc) // Only free wctx if tfc didn't take ownership of it
948  av_freep(&gpc);
949 
950  return ret;
951 }
952 
953 
955 {
956  GraphPrintContext *gpc = NULL;
957  AVTextFormatContext *tfc;
958  AVBPrint *target_buf = &fg->graph_print_buf;
959  int ret;
960 
961  if (!fg) {
962  av_log(NULL, AV_LOG_ERROR, "Invalid filter graph provided\n");
963  return AVERROR(EINVAL);
964  }
965 
966  if (target_buf->len)
967  av_bprint_finalize(target_buf, NULL);
968 
969  ret = init_graphprint(&gpc, target_buf);
970  if (ret)
971  return ret;
972 
973  if (!gpc) {
974  av_log(NULL, AV_LOG_ERROR, "Failed to initialize graph print context\n");
975  return AVERROR(ENOMEM);
976  }
977 
978  tfc = gpc->tfc;
979 
980  // Due to the threading model each graph needs to print itself into a buffer
981  // from its own thread. The actual printing happens short before cleanup in ffmpeg.c
982  // where all graphs are assembled together. To make this work, we need to put the
983  // formatting context into the same state like it would be when printing all at once,
984  // so here we print the section headers and clear the buffer to get into the right state.
988 
989  av_bprint_clear(target_buf);
990 
991  print_filtergraph_single(gpc, fg, graph);
992 
993  if (gpc->is_diagram) {
994  avtext_print_section_footer(tfc); // SECTION_ID_FILTERGRAPH
995  avtext_print_section_footer(tfc); // SECTION_ID_FILTERGRAPHS
996  }
997 
998  uninit_graphprint(gpc);
999 
1000  return 0;
1001 }
1002 
1003 static int print_filtergraphs_priv(FilterGraph **graphs, int nb_graphs, InputFile **ifiles, int nb_ifiles, OutputFile **ofiles, int nb_ofiles)
1004 {
1005  GraphPrintContext *gpc = NULL;
1006  AVTextFormatContext *tfc;
1007  AVBPrint target_buf;
1008  int ret;
1009 
1010  ret = init_graphprint(&gpc, &target_buf);
1011  if (ret)
1012  goto cleanup;
1013 
1014  if (!gpc) {
1015  ret = AVERROR(ENOMEM);
1016  goto cleanup;
1017  }
1018 
1019  tfc = gpc->tfc;
1020 
1023 
1024  for (int i = 0; i < nb_graphs; i++) {
1025  AVBPrint *graph_buf = &graphs[i]->graph_print_buf;
1026 
1027  if (graph_buf->len > 0) {
1029  av_bprint_append_data(&target_buf, graph_buf->str, graph_buf->len);
1030  av_bprint_finalize(graph_buf, NULL);
1031  avtext_print_section_footer(tfc); // SECTION_ID_FILTERGRAPH
1032  }
1033  }
1034 
1035  for (int n = 0; n < nb_ofiles; n++) {
1036  OutputFile *of = ofiles[n];
1037 
1038  for (int i = 0; i < of->nb_streams; i++) {
1039  OutputStream *ost = of->streams[i];
1040 
1041  if (ost->fg_simple) {
1042  AVBPrint *graph_buf = &ost->fg_simple->graph_print_buf;
1043 
1044  if (graph_buf->len > 0) {
1046  av_bprint_append_data(&target_buf, graph_buf->str, graph_buf->len);
1047  av_bprint_finalize(graph_buf, NULL);
1048  avtext_print_section_footer(tfc); // SECTION_ID_FILTERGRAPH
1049  }
1050  }
1051  }
1052  }
1053 
1054  avtext_print_section_footer(tfc); // SECTION_ID_FILTERGRAPHS
1055 
1056  print_streams(gpc, ifiles, nb_ifiles, ofiles, nb_ofiles);
1057 
1058  avtext_print_section_footer(tfc); // SECTION_ID_ROOT
1059 
1060  if (print_graphs_file) {
1061  AVIOContext *avio = NULL;
1062 
1063  if (!strcmp(print_graphs_file, "-")) {
1064  printf("%s", target_buf.str);
1065  } else {
1067  if (ret < 0) {
1068  av_log(NULL, AV_LOG_ERROR, "Failed to open graph output file, \"%s\": %s\n", print_graphs_file, av_err2str(ret));
1069  goto cleanup;
1070  }
1071 
1072  avio_write(avio, (const unsigned char *)target_buf.str, FFMIN(target_buf.len, target_buf.size - 1));
1073 
1074  if ((ret = avio_closep(&avio)) < 0)
1075  av_log(NULL, AV_LOG_ERROR, "Error closing graph output file, loss of information possible: %s\n", av_err2str(ret));
1076  }
1077  }
1078 
1079  if (print_graphs)
1080  av_log(NULL, AV_LOG_INFO, "%s %c", target_buf.str, '\n');
1081 
1082 cleanup:
1083  // Properly clean up resources
1084  if (gpc)
1085  uninit_graphprint(gpc);
1086 
1087  // Ensure the target buffer is properly finalized
1088  av_bprint_finalize(&target_buf, NULL);
1089 
1090  return ret;
1091 }
1092 
1093 int print_filtergraphs(FilterGraph **graphs, int nb_graphs, InputFile **ifiles, int nb_ifiles, OutputFile **ofiles, int nb_ofiles)
1094 {
1095  int ret = print_filtergraphs_priv(graphs, nb_graphs, ifiles, nb_ifiles, ofiles, nb_ofiles);
1096  ff_resman_uninit();
1097  return ret;
1098 }
SECTION_ID_HWFRAMESCONTEXT
@ SECTION_ID_HWFRAMESCONTEXT
Definition: graphprint.c:60
upcase_string
static char * upcase_string(char *dst, size_t dst_size, const char *src)
Definition: graphprint.c:160
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:661
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
SECTION_ID_GRAPH_INPUTS
@ SECTION_ID_GRAPH_INPUTS
Definition: graphprint.c:50
print_filter
static void print_filter(GraphPrintContext *gpc, const AVFilterContext *filter, AVDictionary *input_map, AVDictionary *output_map)
Definition: graphprint.c:383
AV_TEXTFORMAT_PRINT_STRING_OPTIONAL
#define AV_TEXTFORMAT_PRINT_STRING_OPTIONAL
Definition: avtextformat.h:155
Muxer::fc
AVFormatContext * fc
Definition: ffmpeg_mux.h:101
SECTION_ID_DECODER
@ SECTION_ID_DECODER
Definition: graphprint.c:72
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:73
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:51
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:982
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:403
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:3341
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
FilterGraph::inputs
InputFilter ** inputs
Definition: ffmpeg.h:398
SECTION_ID_OUTPUTSTREAM
@ SECTION_ID_OUTPUTSTREAM
Definition: graphprint.c:68
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:198
SECTION_ID_FILTER
@ SECTION_ID_FILTER
Definition: graphprint.c:55
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:53
AVFrame::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:672
InputFile::index
int index
Definition: ffmpeg.h:495
pixdesc.h
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
print_int
#define print_int(k, v)
Definition: graphprint.c:138
AVPixFmtDescriptor::name
const char * name
Definition: pixdesc.h:70
OutputFilter::index
int index
Definition: ffmpeg.h:375
FilterGraph::index
int index
Definition: ffmpeg.h:396
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:353
AVTextFormatContext::show_value_unit
int show_value_unit
Definition: avtextformat.h:135
InputFilter::index
int index
Definition: ffmpeg.h:356
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:112
atomic_int
intptr_t atomic_int
Definition: stdatomic.h:55
SECTION_ID_ENCODERS
@ SECTION_ID_ENCODERS
Definition: graphprint.c:73
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:399
AVDictionary
Definition: dict.c:32
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:215
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:218
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:142
OutputFile::nb_streams
int nb_streams
Definition: ffmpeg.h:670
Muxer
Definition: ffmpeg_mux.h:95
InputStream
Definition: ffmpeg.h:458
AVDiagramConfig
Definition: tf_mermaid.h:29
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3717
SECTION_ID_INPUTSTREAMS
@ SECTION_ID_INPUTSTREAMS
Definition: graphprint.c:63
fail
#define fail()
Definition: checkasm.h:196
InputFilter::type
enum AVMediaType type
Definition: ffmpeg.h:359
print_filtergraph
int print_filtergraph(FilterGraph *fg, AVFilterGraph *graph)
Definition: graphprint.c:954
SECTION_ID_GRAPH_INPUT
@ SECTION_ID_GRAPH_INPUT
Definition: graphprint.c:51
AVFrame::ch_layout
AVChannelLayout ch_layout
Channel layout of the audio data.
Definition: frame.h:753
SECTION_ID_OUTPUTFILES
@ SECTION_ID_OUTPUTFILES
Definition: graphprint.c:65
AVRational::num
int num
Numerator.
Definition: rational.h:59
AVTextFormatSectionContext
Definition: avtextformat.h:34
InputFile
Definition: ffmpeg.h:492
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:38
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:61
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:212
AVHWFramesContext::height
int height
Definition: hwcontext.h:218
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:653
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:67
print_filtergraph_single
static void print_filtergraph_single(GraphPrintContext *gpc, FilterGraph *fg, AVFilterGraph *graph)
Definition: graphprint.c:479
AVTextFormatter
Definition: avtextformat.h:94
FilterGraph::outputs
OutputFilter ** outputs
Definition: ffmpeg.h:400
GraphPrintContext::is_diagram
int is_diagram
Definition: graphprint.c:128
print_filtergraphs
int print_filtergraphs(FilterGraph **graphs, int nb_graphs, InputFile **ifiles, int nb_ifiles, OutputFile **ofiles, int nb_ofiles)
Definition: graphprint.c:1093
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
avtextwriter_context_close
int avtextwriter_context_close(AVTextWriterContext **pwctx)
Definition: avtextformat.c:620
AVTextFormatSection
Definition: avtextformat.h:41
OutputFilter::linklabel
uint8_t * linklabel
Definition: ffmpeg.h:384
InputFilter
Definition: ffmpeg.h:353
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:493
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:129
print_graphs_file
char * print_graphs_file
Definition: ffmpeg_opt.c:80
GraphPrintContext
Definition: graphprint.c:122
InputFilter::linklabel
uint8_t * linklabel
Definition: ffmpeg.h:367
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:116
key
const char * key
Definition: hwcontext_opencl.c:189
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
init_sections
static void init_sections(void)
Definition: graphprint.c:473
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:145
SECTION_ID_FILTER_OUTPUT
@ SECTION_ID_FILTER_OUTPUT
Definition: graphprint.c:59
av_color_range_name
const char * av_color_range_name(enum AVColorRange range)
Definition: pixdesc.c:3657
AVFormatContext
Format I/O context.
Definition: avformat.h:1264
SECTION_ID_FILTERGRAPH
@ SECTION_ID_FILTERGRAPH
Definition: graphprint.c:49
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:378
NULL
#define NULL
Definition: coverity.c:32
print_val
#define print_val(k, v, u)
Definition: graphprint.c:143
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:211
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:74
AVFilterGraph::filters
AVFilterContext ** filters
Definition: avfilter.h:584
SECTION_ID_INPUTFILE
@ SECTION_ID_INPUTFILE
Definition: graphprint.c:62
AVFilterContext::name
char * name
name of this filter instance
Definition: avfilter.h:274
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:992
AVTextFormatContext::formatter
const AVTextFormatter * formatter
the AVTextFormatter of which this is an instance
Definition: avtextformat.h:114
AVFilterGraph
Definition: avfilter.h:582
OutputFile::index
int index
Definition: ffmpeg.h:665
sanitize_char
static char sanitize_char(const char c)
Definition: graphprint.c:324
avtext_get_formatter_by_name
const AVTextFormatter * avtext_get_formatter_by_name(const char *name)
Definition: avtextformat.c:698
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:716
FilterGraph::nb_outputs
int nb_outputs
Definition: ffmpeg.h:401
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:474
print_graphs_format
char * print_graphs_format
Definition: ffmpeg_opt.c:81
OutputFile::streams
OutputStream ** streams
Definition: ffmpeg.h:669
init_graphprint
static int init_graphprint(GraphPrintContext **pgpc, AVBPrint *target_buf)
Definition: graphprint.c:871
FilterGraph
Definition: ffmpeg.h:394
InputFilter::filter
AVFilterContext * filter
Definition: ffmpeg.h:361
SECTION_ID_FILTERGRAPHS
@ SECTION_ID_FILTERGRAPHS
Definition: graphprint.c:48
OutputFilter::output_name
char * output_name
Definition: ffmpeg.h:379
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
AVMediaType
AVMediaType
Definition: avutil.h:198
GraphPrintContext::pbuf
AVBPrint pbuf
Definition: graphprint.c:131
print_streams
static int print_streams(GraphPrintContext *gpc, InputFile **ifiles, int nb_ifiles, OutputFile **ofiles, int nb_ofiles)
Definition: graphprint.c:588
GraphPrintContext::diagram_config
AVDiagramConfig diagram_config
Definition: graphprint.c:125
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:240
get_extension
static char * get_extension(const char *url)
Definition: graphprint.c:169
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:124
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:97
AVFrame::sample_rate
int sample_rate
Sample rate of the audio data.
Definition: frame.h:573
avtext_print_section_footer
void avtext_print_section_footer(AVTextFormatContext *tctx)
Definition: avtextformat.c:273
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:527
OutputFile::url
const char * url
Definition: ffmpeg.h:667
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:497
buffer.h
FilterGraph::graph_print_buf
struct AVBPrint graph_print_buf
Definition: ffmpeg.h:404
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:201
OutputFilter::filter
AVFilterContext * filter
Definition: ffmpeg.h:377
print_sanizied_id
static void print_sanizied_id(const GraphPrintContext *gpc, const char *key, const char *id_str, int skip_prefix)
Definition: graphprint.c:331
AVTextFormatContext::show_optional_fields
int show_optional_fields
Definition: avtextformat.h:134
AVTextFormatter::flags
int flags
a combination or AV_TEXTFORMAT__FLAG_*
Definition: avtextformat.h:106
SectionID
SectionID
Definition: graphprint.c:46
sections
static struct AVTextFormatSection sections[]
Definition: graphprint.c:77
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:71
print_id
#define print_id(k, v)
Definition: graphprint.c:136
OutputFilter::type
enum AVMediaType type
Definition: ffmpeg.h:388
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
AVTextFormatSectionContext::context_id
char * context_id
Definition: avtextformat.h:35
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
SECTION_ID_STREAMLINKS
@ SECTION_ID_STREAMLINKS
Definition: graphprint.c:69
print_q
#define print_q(k, v, s)
Definition: graphprint.c:140
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:61
SECTION_ID_GRAPH_OUTPUTS
@ SECTION_ID_GRAPH_OUTPUTS
Definition: graphprint.c:52
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:79
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:497
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
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:256
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:676
SECTION_ID_FILTERS
@ SECTION_ID_FILTERS
Definition: graphprint.c:54
SECTION_ID_INPUTSTREAM
@ SECTION_ID_INPUTSTREAM
Definition: graphprint.c:64
print_int_opt
#define print_int_opt(k, v)
Definition: graphprint.c:139
print_link
static void print_link(GraphPrintContext *gpc, AVFilterLink *link)
Definition: graphprint.c:247
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:116
InputStream::decoder
Decoder * decoder
Definition: ffmpeg.h:475
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:73
AVFormatContext::oformat
const struct AVOutputFormat * oformat
The output container format.
Definition: avformat.h:1283
AVHWFramesContext::device_ctx
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:135
SECTION_ID_FILTER_OUTPUTS
@ SECTION_ID_FILTER_OUTPUTS
Definition: graphprint.c:58
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:511
print_str
#define print_str(k, v)
Definition: graphprint.c:141
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:99
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:507
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:129
AVDiagramConfig::html_template
const char * html_template
Definition: tf_mermaid.h:32
GraphPrintContext::tfc
AVTextFormatContext * tfc
Definition: graphprint.c:123
prefix_num
static atomic_int prefix_num
Definition: graphprint.c:158
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:148
AVTextFormatOptions
Definition: avtextformat.h:147
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:201
avfilter.h
av_bprint_clear
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
Definition: bprint.c:232
print_id_noprefix
#define print_id_noprefix(k, v)
Definition: graphprint.c:137
uninit_graphprint
static void uninit_graphprint(GraphPrintContext *gpc)
Definition: graphprint.c:857
AVFilterContext
An instance of a filter.
Definition: avfilter.h:269
OutputFilter
Definition: ffmpeg.h:370
SECTION_ID_ROOT
@ SECTION_ID_ROOT
Definition: graphprint.c:47
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:188
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
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:492
ffmpeg_mux.h
SECTION_ID_STREAMLINK
@ SECTION_ID_STREAMLINK
Definition: graphprint.c:70
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:464
SECTION_ID_FILTER_INPUT
@ SECTION_ID_FILTER_INPUT
Definition: graphprint.c:57
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:55
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:650
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:172
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:151
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:145
avcodec_descriptor_get
const AVCodecDescriptor * avcodec_descriptor_get(enum AVCodecID id)
Definition: codec_desc.c:3794
AVDictionaryEntry::value
char * value
Definition: dict.h:92
AVFilterGraph::nb_filters
unsigned nb_filters
Definition: avfilter.h:585
SECTION_ID_OUTPUTFILE
@ SECTION_ID_OUTPUTFILE
Definition: graphprint.c:66
avstring.h
AVFilterContext::filter
const AVFilter * filter
the AVFilter of which this is an instance
Definition: avfilter.h:272
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:1003
InputFile::nb_streams
int nb_streams
Definition: ffmpeg.h:512
GraphPrintContext::id_prefix_num
int id_prefix_num
Definition: graphprint.c:127
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:101
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:163
InputStream::dec
const AVCodec * dec
Definition: ffmpeg.h:476
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:56
GraphPrintContext::skip_buffer_filters
int skip_buffer_filters
Definition: graphprint.c:130
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:3261
OutputFile
Definition: ffmpeg.h:662
tf_mermaid.h
avtext_print_section_header
void avtext_print_section_header(AVTextFormatContext *tctx, const void *data, int section_id)
Definition: avtextformat.c:255
InputFilter::input_name
char * input_name
Definition: ffmpeg.h:363