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/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 const 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_integer(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 
474 {
475  AVTextFormatContext *tfc = gpc->tfc;
476  AVDictionary *input_map = NULL;
477  AVDictionary *output_map = NULL;
478 
479  print_int("graph_index", fg->index);
480  print_fmt("name", "Graph %d.%d", gpc->id_prefix_num, fg->index);
481  print_fmt("id", "Graph_%d_%d", gpc->id_prefix_num, fg->index);
482  print_str("description", fg->graph_desc);
483 
484  print_section_header_id(gpc, SECTION_ID_GRAPH_INPUTS, "Input_File", 0);
485 
486  for (int i = 0; i < fg->nb_inputs; i++) {
487  InputFilter *ifilter = fg->inputs[i];
488  enum AVMediaType media_type = ifilter->type;
489 
491 
492  print_int("input_index", ifilter->index);
493 
494  if (ifilter->linklabel)
495  print_str("link_label", (const char*)ifilter->linklabel);
496 
497  if (ifilter->filter) {
498  print_id("filter_id", ifilter->filter->name);
499  print_str("filter_name", ifilter->filter->filter->name);
500  }
501 
502  if (ifilter->linklabel && ifilter->filter)
503  av_dict_set(&input_map, ifilter->filter->name, (const char *)ifilter->linklabel, 0);
504  else if (ifilter->input_name && ifilter->filter)
505  av_dict_set(&input_map, ifilter->filter->name, (const char *)ifilter->input_name, 0);
506 
507  print_str("media_type", av_get_media_type_string(media_type));
508 
509  avtext_print_section_footer(tfc); // SECTION_ID_GRAPH_INPUT
510  }
511 
512  avtext_print_section_footer(tfc); // SECTION_ID_GRAPH_INPUTS
513 
514  print_section_header_id(gpc, SECTION_ID_GRAPH_OUTPUTS, "Output_File", 0);
515 
516  for (int i = 0; i < fg->nb_outputs; i++) {
517  OutputFilter *ofilter = fg->outputs[i];
518 
520 
521  print_int("output_index", ofilter->index);
522 
523  print_str("name", ofilter->output_name);
524 
525  if (fg->outputs[i]->linklabel)
526  print_str("link_label", (const char*)fg->outputs[i]->linklabel);
527 
528  if (ofilter->filter) {
529  print_id("filter_id", ofilter->filter->name);
530  print_str("filter_name", ofilter->filter->filter->name);
531  }
532 
533  if (ofilter->output_name && ofilter->filter)
534  av_dict_set(&output_map, ofilter->filter->name, ofilter->output_name, 0);
535 
536 
537  print_str("media_type", av_get_media_type_string(ofilter->type));
538 
539  avtext_print_section_footer(tfc); // SECTION_ID_GRAPH_OUTPUT
540  }
541 
542  avtext_print_section_footer(tfc); // SECTION_ID_GRAPH_OUTPUTS
543 
544  if (graph) {
545  AVTextFormatSectionContext sec_ctx = { 0 };
546 
547  sec_ctx.context_id = av_asprintf("Graph_%d_%d", gpc->id_prefix_num, fg->index);
548 
550 
551  if (gpc->is_diagram) {
552  print_fmt("name", "Graph %d.%d", gpc->id_prefix_num, fg->index);
553  print_str("description", fg->graph_desc);
554  print_str("id", sec_ctx.context_id);
555  }
556 
557  av_freep(&sec_ctx.context_id);
558 
559  for (unsigned i = 0; i < graph->nb_filters; i++) {
560  AVFilterContext *filter = graph->filters[i];
561 
562  if (gpc->skip_buffer_filters) {
563  if (av_dict_get(input_map, filter->name, NULL, 0))
564  continue;
565  if (av_dict_get(output_map, filter->name, NULL, 0))
566  continue;
567  }
568 
569  sec_ctx.context_id = filter->name;
570 
571  print_filter(gpc, filter, input_map, output_map);
572  }
573 
574  avtext_print_section_footer(tfc); // SECTION_ID_FILTERS
575  }
576 
577  // Clean up dictionaries
578  av_dict_free(&input_map);
579  av_dict_free(&output_map);
580 }
581 
582 static int print_streams(GraphPrintContext *gpc, InputFile **ifiles, int nb_ifiles, OutputFile **ofiles, int nb_ofiles)
583 {
584  AVTextFormatContext *tfc = gpc->tfc;
585  AVBPrint buf;
586  AVTextFormatSectionContext sec_ctx = { 0 };
587 
589 
591 
592  for (int n = nb_ifiles - 1; n >= 0; n--) {
593  InputFile *ifi = ifiles[n];
594  AVFormatContext *fc = ifi->ctx;
595 
596  sec_ctx.context_id = av_asprintf("Input_%d", n);
598  av_freep(&sec_ctx.context_id);
599 
600  print_fmt("index", "%d", ifi->index);
601 
602  if (fc) {
603  print_str("demuxer_name", fc->iformat->name);
604  if (fc->url) {
605  char *extension = get_extension(fc->url);
606  if (extension) {
607  print_str("file_extension", extension);
608  av_freep(&extension);
609  }
610  print_str("url", fc->url);
611  }
612  }
613 
614  sec_ctx.context_id = av_asprintf("InputStreams_%d", n);
615 
617 
618  av_freep(&sec_ctx.context_id);
619 
620  for (int i = 0; i < ifi->nb_streams; i++) {
621  InputStream *ist = ifi->streams[i];
622  const AVCodecDescriptor *codec_desc;
623 
624  if (!ist || !ist->par)
625  continue;
626 
627  codec_desc = avcodec_descriptor_get(ist->par->codec_id);
628 
629  sec_ctx.context_id = av_asprintf("r_in_%d_%d", n, i);
630 
632 
634  av_freep(&sec_ctx.context_id);
635  sec_ctx.context_type = NULL;
636 
637  av_bprint_clear(&buf);
638 
639  print_fmt("id", "r_in_%d_%d", n, i);
640 
641  if (codec_desc && codec_desc->name) {
642  ////av_bprintf(&buf, "%s", upcase_string(char_buf, sizeof(char_buf), codec_desc->long_name));
643  av_bprintf(&buf, "%s", codec_desc->long_name);
644  } else if (ist->dec) {
645  char char_buf[256];
646  av_bprintf(&buf, "%s", upcase_string(char_buf, sizeof(char_buf), ist->dec->name));
647  } else if (ist->par->codec_type == AVMEDIA_TYPE_ATTACHMENT) {
648  av_bprintf(&buf, "%s", "Attachment");
649  } else if (ist->par->codec_type == AVMEDIA_TYPE_DATA) {
650  av_bprintf(&buf, "%s", "Data");
651  }
652 
653  print_fmt("name", "%s", buf.str);
654  print_fmt("index", "%d", ist->index);
655 
656  if (ist->dec)
658 
659  avtext_print_section_footer(tfc); // SECTION_ID_INPUTSTREAM
660  }
661 
662  avtext_print_section_footer(tfc); // SECTION_ID_INPUTSTREAMS
663  avtext_print_section_footer(tfc); // SECTION_ID_INPUTFILE
664  }
665 
666  avtext_print_section_footer(tfc); // SECTION_ID_INPUTFILES
667 
668 
669  print_section_header_id(gpc, SECTION_ID_DECODERS, "Decoders", 0);
670 
671  for (int n = 0; n < nb_ifiles; n++) {
672  InputFile *ifi = ifiles[n];
673 
674  for (int i = 0; i < ifi->nb_streams; i++) {
675  InputStream *ist = ifi->streams[i];
676 
677  if (!ist->decoder)
678  continue;
679 
680  sec_ctx.context_id = av_asprintf("in_%d_%d", n, i);
682  sec_ctx.context_flags = 2;
683 
685  av_freep(&sec_ctx.context_id);
686  sec_ctx.context_type = NULL;
687  sec_ctx.context_flags = 0;
688 
689  av_bprint_clear(&buf);
690 
691  print_fmt("source_id", "r_in_%d_%d", n, i);
692  print_fmt("id", "in_%d_%d", n, i);
693 
694  ////av_bprintf(&buf, "%s", upcase_string(char_buf, sizeof(char_buf), ist->dec->name));
695  print_fmt("name", "%s", ist->dec->name);
696 
698 
699  avtext_print_section_footer(tfc); // SECTION_ID_DECODER
700  }
701  }
702 
703  avtext_print_section_footer(tfc); // SECTION_ID_DECODERS
704 
705 
706  print_section_header_id(gpc, SECTION_ID_ENCODERS, "Encoders", 0);
707 
708  for (int n = 0; n < nb_ofiles; n++) {
709  OutputFile *of = ofiles[n];
710 
711  for (int i = 0; i < of->nb_streams; i++) {
712  OutputStream *ost = of->streams[i];
713  ////const AVCodecDescriptor *codec_desc;
714 
715  if (!ost || !ost->st || !ost->st->codecpar || !ost->enc)
716  continue;
717 
718  ////codec_desc = avcodec_descriptor_get(ost->st->codecpar->codec_id);
719 
720  sec_ctx.context_id = av_asprintf("out__%d_%d", n, i);
721  sec_ctx.context_type = av_get_media_type_string(ost->type);
722  sec_ctx.context_flags = 2;
723 
725  av_freep(&sec_ctx.context_id);
726  sec_ctx.context_type = NULL;
727  sec_ctx.context_flags = 0;
728 
729  av_bprint_clear(&buf);
730 
731  print_fmt("id", "out__%d_%d", n, i);
732  print_fmt("dest_id", "r_out__%d_%d", n, i);
733 
734  print_fmt("name", "%s", ost->enc->enc_ctx->av_class->item_name(ost->enc->enc_ctx));
735 
736  print_str_opt("media_type", av_get_media_type_string(ost->type));
737 
738  avtext_print_section_footer(tfc); // SECTION_ID_ENCODER
739  }
740  }
741 
742  avtext_print_section_footer(tfc); // SECTION_ID_ENCODERS
743 
744 
746 
747  for (int n = nb_ofiles - 1; n >= 0; n--) {
748  OutputFile *of = ofiles[n];
749  Muxer *muxer = (Muxer *)of;
750 
751  if (!muxer->fc)
752  continue;
753 
754  sec_ctx.context_id = av_asprintf("Output_%d", n);
755 
757 
758  av_freep(&sec_ctx.context_id);
759 
760  ////print_str_opt("index", av_get_media_type_string(of->index));
761  print_fmt("index", "%d", of->index);
762  ////print_str("url", of->url);
763  print_str("muxer_name", muxer->fc->oformat->name);
764  if (of->url) {
765  char *extension = get_extension(of->url);
766  if (extension) {
767  print_str("file_extension", extension);
768  av_freep(&extension);
769  }
770  print_str("url", of->url);
771  }
772 
773  sec_ctx.context_id = av_asprintf("OutputStreams_%d", n);
774 
776 
777  av_freep(&sec_ctx.context_id);
778 
779  for (int i = 0; i < of->nb_streams; i++) {
780  OutputStream *ost = of->streams[i];
781  const AVCodecDescriptor *codec_desc = avcodec_descriptor_get(ost->st->codecpar->codec_id);
782 
783  sec_ctx.context_id = av_asprintf("r_out__%d_%d", n, i);
784  sec_ctx.context_type = av_get_media_type_string(ost->type);
786  av_freep(&sec_ctx.context_id);
787  sec_ctx.context_type = NULL;
788 
789  av_bprint_clear(&buf);
790 
791  print_fmt("id", "r_out__%d_%d", n, i);
792 
793  if (codec_desc && codec_desc->name) {
794  av_bprintf(&buf, "%s", codec_desc->long_name);
795  } else {
796  av_bprintf(&buf, "%s", "unknown");
797  }
798 
799  print_fmt("name", "%s", buf.str);
800  print_fmt("index", "%d", ost->index);
801 
802  print_str_opt("media_type", av_get_media_type_string(ost->type));
803 
804  avtext_print_section_footer(tfc); // SECTION_ID_OUTPUTSTREAM
805  }
806 
807  avtext_print_section_footer(tfc); // SECTION_ID_OUTPUTSTREAMS
808  avtext_print_section_footer(tfc); // SECTION_ID_OUTPUTFILE
809  }
810 
811  avtext_print_section_footer(tfc); // SECTION_ID_OUTPUTFILES
812 
813 
815 
816  for (int n = 0; n < nb_ofiles; n++) {
817  OutputFile *of = ofiles[n];
818 
819  for (int i = 0; i < of->nb_streams; i++) {
820  OutputStream *ost = of->streams[i];
821 
822  if (ost->ist && !ost->filter) {
823  sec_ctx.context_type = av_get_media_type_string(ost->type);
825  sec_ctx.context_type = NULL;
826 
827  if (ost->enc) {
828  print_fmt("dest_stream_id", "out__%d_%d", n, i);
829  print_fmt("source_stream_id", "in_%d_%d", ost->ist->file->index, ost->ist->index);
830  print_str("operation", "Transcode");
831  } else {
832  print_fmt("dest_stream_id", "r_out__%d_%d", n, i);
833  print_fmt("source_stream_id", "r_in_%d_%d", ost->ist->file->index, ost->ist->index);
834  print_str("operation", "Stream Copy");
835  }
836 
837  print_str_opt("media_type", av_get_media_type_string(ost->type));
838 
839  avtext_print_section_footer(tfc); // SECTION_ID_STREAMLINK
840  }
841  }
842  }
843 
844  avtext_print_section_footer(tfc); // SECTION_ID_STREAMLINKS
845 
846  av_bprint_finalize(&buf, NULL);
847  return 0;
848 }
849 
850 
852 {
853  if (gpc->tfc)
854  avtext_context_close(&gpc->tfc);
855 
856  if (gpc->wctx)
858 
859  // Finalize the print buffer if it was initialized
860  av_bprint_finalize(&gpc->pbuf, NULL);
861 
862  av_freep(&gpc);
863 }
864 
865 static int init_graphprint(GraphPrintContext **pgpc, AVBPrint *target_buf)
866 {
867  const AVTextFormatter *text_formatter;
868  AVTextFormatContext *tfc = NULL;
869  AVTextWriterContext *wctx = NULL;
870  GraphPrintContext *gpc = NULL;
871  int ret;
872 
873  *pgpc = NULL;
874 
876 
877  const char *w_name = print_graphs_format ? print_graphs_format : "json";
878 
879  text_formatter = avtext_get_formatter_by_name(w_name);
880  if (!text_formatter) {
881  av_log(NULL, AV_LOG_ERROR, "Unknown filter graph output format with name '%s'\n", w_name);
882  ret = AVERROR(EINVAL);
883  goto fail;
884  }
885 
886  ret = avtextwriter_create_buffer(&wctx, target_buf);
887  if (ret < 0) {
888  av_log(NULL, AV_LOG_ERROR, "avtextwriter_create_buffer failed. Error code %d\n", ret);
889  ret = AVERROR(EINVAL);
890  goto fail;
891  }
892 
893  AVTextFormatOptions tf_options = { .show_optional_fields = -1 };
894  const char *w_args = print_graphs_format ? strchr(print_graphs_format, '=') : NULL;
895  if (w_args)
896  ++w_args; // consume '='
897  ret = avtext_context_open(&tfc, text_formatter, wctx, w_args, sections, FF_ARRAY_ELEMS(sections), tf_options, NULL);
898  if (ret < 0) {
899  goto fail;
900  }
901 
902  gpc = av_mallocz(sizeof(GraphPrintContext));
903  if (!gpc) {
904  ret = AVERROR(ENOMEM);
905  goto fail;
906  }
907 
908  gpc->wctx = wctx;
909  gpc->tfc = tfc;
911 
914  if (gpc->is_diagram) {
915  tfc->show_value_unit = 1;
916  tfc->show_optional_fields = -1;
918  gpc->skip_buffer_filters = 1;
919  ////} else {
920  //// gpc->opt_flags = AV_TEXTFORMAT_PRINT_STRING_OPTIONAL;
921  }
922 
923  if (!strcmp(text_formatter->name, "mermaid") || !strcmp(text_formatter->name, "mermaidhtml")) {
925 
926  if (!strcmp(text_formatter->name, "mermaidhtml"))
928 
929  av_diagram_init(tfc, &gpc->diagram_config);
930  }
931 
932  *pgpc = gpc;
933 
934  return 0;
935 
936 fail:
937  if (tfc)
938  avtext_context_close(&tfc);
939  if (wctx && !tfc) // Only free wctx if tfc didn't take ownership of it
941  av_freep(&gpc);
942 
943  return ret;
944 }
945 
946 
948 {
949  av_assert2(fg);
950 
951  GraphPrintContext *gpc = NULL;
952  AVTextFormatContext *tfc;
953  AVBPrint *target_buf = &fg->graph_print_buf;
954  int ret;
955 
956  if (target_buf->len)
957  av_bprint_finalize(target_buf, NULL);
958 
959  ret = init_graphprint(&gpc, target_buf);
960  if (ret)
961  return ret;
962 
963  tfc = gpc->tfc;
964 
965  // Due to the threading model each graph needs to print itself into a buffer
966  // from its own thread. The actual printing happens short before cleanup in ffmpeg.c
967  // where all graphs are assembled together. To make this work, we need to put the
968  // formatting context into the same state like it would be when printing all at once,
969  // so here we print the section headers and clear the buffer to get into the right state.
973 
974  av_bprint_clear(target_buf);
975 
976  print_filtergraph_single(gpc, fg, graph);
977 
978  if (gpc->is_diagram) {
979  avtext_print_section_footer(tfc); // SECTION_ID_FILTERGRAPH
980  avtext_print_section_footer(tfc); // SECTION_ID_FILTERGRAPHS
981  }
982 
983  uninit_graphprint(gpc);
984 
985  return 0;
986 }
987 
988 static int print_filtergraphs_priv(FilterGraph **graphs, int nb_graphs, InputFile **ifiles, int nb_ifiles, OutputFile **ofiles, int nb_ofiles)
989 {
990  GraphPrintContext *gpc = NULL;
991  AVTextFormatContext *tfc;
992  AVBPrint target_buf;
993  int ret;
994 
995  ret = init_graphprint(&gpc, &target_buf);
996  if (ret)
997  goto cleanup;
998 
999  tfc = gpc->tfc;
1000 
1003 
1004  for (int i = 0; i < nb_graphs; i++) {
1005  AVBPrint *graph_buf = &graphs[i]->graph_print_buf;
1006 
1007  if (graph_buf->len > 0) {
1009  av_bprint_append_data(&target_buf, graph_buf->str, graph_buf->len);
1010  av_bprint_finalize(graph_buf, NULL);
1011  avtext_print_section_footer(tfc); // SECTION_ID_FILTERGRAPH
1012  }
1013  }
1014 
1015  for (int n = 0; n < nb_ofiles; n++) {
1016  OutputFile *of = ofiles[n];
1017 
1018  for (int i = 0; i < of->nb_streams; i++) {
1019  OutputStream *ost = of->streams[i];
1020 
1021  if (ost->fg_simple) {
1022  AVBPrint *graph_buf = &ost->fg_simple->graph_print_buf;
1023 
1024  if (graph_buf->len > 0) {
1026  av_bprint_append_data(&target_buf, graph_buf->str, graph_buf->len);
1027  av_bprint_finalize(graph_buf, NULL);
1028  avtext_print_section_footer(tfc); // SECTION_ID_FILTERGRAPH
1029  }
1030  }
1031  }
1032  }
1033 
1034  avtext_print_section_footer(tfc); // SECTION_ID_FILTERGRAPHS
1035 
1036  print_streams(gpc, ifiles, nb_ifiles, ofiles, nb_ofiles);
1037 
1038  avtext_print_section_footer(tfc); // SECTION_ID_ROOT
1039 
1040  if (print_graphs_file) {
1041  AVIOContext *avio = NULL;
1042 
1043  if (!strcmp(print_graphs_file, "-")) {
1044  printf("%s", target_buf.str);
1045  } else {
1047  if (ret < 0) {
1048  av_log(NULL, AV_LOG_ERROR, "Failed to open graph output file, \"%s\": %s\n", print_graphs_file, av_err2str(ret));
1049  goto cleanup;
1050  }
1051 
1052  avio_write(avio, (const unsigned char *)target_buf.str, FFMIN(target_buf.len, target_buf.size - 1));
1053 
1054  if ((ret = avio_closep(&avio)) < 0)
1055  av_log(NULL, AV_LOG_ERROR, "Error closing graph output file, loss of information possible: %s\n", av_err2str(ret));
1056  }
1057  }
1058 
1059  if (print_graphs)
1060  av_log(NULL, AV_LOG_INFO, "%s %c", target_buf.str, '\n');
1061 
1062 cleanup:
1063  // Properly clean up resources
1064  if (gpc)
1065  uninit_graphprint(gpc);
1066 
1067  // Ensure the target buffer is properly finalized
1068  av_bprint_finalize(&target_buf, NULL);
1069 
1070  return ret;
1071 }
1072 
1073 int print_filtergraphs(FilterGraph **graphs, int nb_graphs, InputFile **ifiles, int nb_ifiles, OutputFile **ofiles, int nb_ofiles)
1074 {
1075  int ret = print_filtergraphs_priv(graphs, nb_graphs, ifiles, nb_ifiles, ofiles, nb_ofiles);
1076  ff_resman_uninit();
1077  return ret;
1078 }
sections
static const AVTextFormatSection sections[]
Definition: graphprint.c:77
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:678
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:164
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: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: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:987
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:421
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:411
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:200
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:689
InputFile::index
int index
Definition: ffmpeg.h:525
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:388
FilterGraph::index
int index
Definition: ffmpeg.h:409
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:143
InputFilter::index
int index
Definition: ffmpeg.h:369
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:110
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:412
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:142
OutputFile::nb_streams
int nb_streams
Definition: ffmpeg.h:706
Muxer
Definition: ffmpeg_mux.h:95
InputStream
Definition: ffmpeg.h:476
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:63
fail
#define fail()
Definition: checkasm.h:216
InputFilter::type
enum AVMediaType type
Definition: ffmpeg.h:372
print_filtergraph
int print_filtergraph(FilterGraph *fg, AVFilterGraph *graph)
Definition: graphprint.c:947
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:770
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:522
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:39
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:212
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: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:473
AVTextFormatter
Definition: avtextformat.h:92
FilterGraph::outputs
OutputFilter ** outputs
Definition: ffmpeg.h:413
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:1073
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
avtextwriter_context_close
int avtextwriter_context_close(AVTextWriterContext **pwctx)
Definition: avtextformat.c:583
AVTextFormatSection
Definition: avtextformat.h:41
OutputFilter::linklabel
uint8_t * linklabel
Definition: ffmpeg.h:397
InputFilter
Definition: ffmpeg.h:366
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:126
print_graphs_file
char * print_graphs_file
Definition: ffmpeg_opt.c:81
GraphPrintContext
Definition: graphprint.c:122
InputFilter::linklabel
uint8_t * linklabel
Definition: ffmpeg.h:380
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: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:3772
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: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:74
AVFilterGraph::filters
AVFilterContext ** filters
Definition: avfilter.h:591
SECTION_ID_INPUTFILE
@ SECTION_ID_INPUTFILE
Definition: graphprint.c:62
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:112
AVFilterGraph
Definition: avfilter.h:589
OutputFile::index
int index
Definition: ffmpeg.h:701
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:661
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:743
FilterGraph::nb_outputs
int nb_outputs
Definition: ffmpeg.h:414
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:492
print_graphs_format
char * print_graphs_format
Definition: ffmpeg_opt.c:82
OutputFile::streams
OutputStream ** streams
Definition: ffmpeg.h:705
init_graphprint
static int init_graphprint(GraphPrintContext **pgpc, AVBPrint *target_buf)
Definition: graphprint.c:865
FilterGraph
Definition: ffmpeg.h:407
InputFilter::filter
AVFilterContext * filter
Definition: ffmpeg.h:374
SECTION_ID_FILTERGRAPHS
@ SECTION_ID_FILTERGRAPHS
Definition: graphprint.c:48
OutputFilter::output_name
char * output_name
Definition: ffmpeg.h:392
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:582
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:235
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:95
AVFrame::sample_rate
int sample_rate
Sample rate of the audio data.
Definition: frame.h:590
avtext_print_section_footer
void avtext_print_section_footer(AVTextFormatContext *tctx)
Definition: avtextformat.c:270
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:544
OutputFile::url
const char * url
Definition: ffmpeg.h:703
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:514
buffer.h
FilterGraph::graph_print_buf
struct AVBPrint graph_print_buf
Definition: ffmpeg.h:422
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:206
OutputFilter::filter
AVFilterContext * filter
Definition: ffmpeg.h:390
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:142
AVTextFormatter::flags
int flags
a combination or AV_TEXTFORMAT__FLAG_*
Definition: avtextformat.h:104
SectionID
SectionID
Definition: graphprint.c:46
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:401
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
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: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:527
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: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:118
InputStream::decoder
Decoder * decoder
Definition: ffmpeg.h:493
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:1283
AVHWFramesContext::device_ctx
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:137
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:541
print_str
#define print_str(k, v)
Definition: graphprint.c:141
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:524
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:157
AVTextFormatOptions
Definition: avtextformat.h:155
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:227
print_id_noprefix
#define print_id_noprefix(k, v)
Definition: graphprint.c:137
uninit_graphprint
static void uninit_graphprint(GraphPrintContext *gpc)
Definition: graphprint.c:851
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:383
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:190
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:482
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: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: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:130
avcodec_descriptor_get
const AVCodecDescriptor * avcodec_descriptor_get(enum AVCodecID id)
Definition: codec_desc.c:3887
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:66
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:988
InputFile::nb_streams
int nb_streams
Definition: ffmpeg.h:542
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:148
InputStream::dec
const AVCodec * dec
Definition: ffmpeg.h:494
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:3376
OutputFile
Definition: ffmpeg.h:698
tf_mermaid.h
avtext_print_section_header
void avtext_print_section_header(AVTextFormatContext *tctx, const void *data, int section_id)
Definition: avtextformat.c:252
InputFilter::input_name
char * input_name
Definition: ffmpeg.h:376