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