[FFmpeg-devel] [PATCH v6 00/13] Execution Graph Printing
ffmpegagent
ffmpegagent at gmail.com
Thu Apr 24 04:12:58 EEST 2025
Shortest cover letter for my longest-running FFmpeg patchset:
* Apply
* Build
* Add the "-sg" switch to any FFmpeg command line
* Press 'q' when you don't want to wait
SG = Show Graph
Documentation and examples can be found here:
https://github.com/softworkz/ffmpeg_output_apis/wiki
Version Updates
===============
V2
==
* Rebased on top of Andreas' improvements
* Applied changes from review (thanks, Andreas)
V3
==
* Fixed all "new warnings"
* Fixed out-of-tree building (thanks, Michael)
V4
==
* Resolved merge conflict
* Fixed build on MinGW (missing include due to WIN32_LEAN_AND_MEAN being
defined) (thanks, Michael)
V5
==
* Applied changes as per review from Stefano (thanks!)
* Introduced AVTextFormatOptions struct for options in
avtext_context_open()
V6
==
* Fix "new warning" in 2nd last commit
* Squash patches 04 and 05 (they weren't truely independent)
* Applied changes as per review from Stefano (thanks!)
.
softworkz (13):
fftools/textformat: Formatting and whitespace changes
fftools/textformat: Apply quality improvements
fftools/avtextformat: Re-use BPrint in loop
fftools/textformat: Introduce AVTextFormatOptions for
avtext_context_open()
fftools/textformat: Introduce common header and deduplicate code
fftools/tf_internal: Use av_default_item_name
fftools/textformat: Add function avtext_print_integer_flags()
fftools/ffmpeg_filter: Move some declaration to new header file
avfilter/avfilter: Add avfilter_link_get_hw_frames_ctx()
fftools/resources: Add resource manager files
fftools/ffmpeg_mux: Make ms_from_ost() inline
fftools/graphprint: Add execution graph printing
fftools/graphprint: Now, make it a Killer-Feature!
doc/APIchanges | 3 +
doc/ffmpeg.texi | 14 +
ffbuild/common.mak | 28 +-
fftools/Makefile | 22 +-
fftools/ffmpeg.c | 4 +
fftools/ffmpeg.h | 4 +
fftools/ffmpeg_filter.c | 195 +----
fftools/ffmpeg_filter.h | 234 ++++++
fftools/ffmpeg_mux.h | 2 +-
fftools/ffmpeg_opt.c | 17 +
fftools/ffprobe.c | 13 +-
fftools/graph/filelauncher.c | 205 +++++
fftools/graph/graphprint.c | 1147 ++++++++++++++++++++++++++++
fftools/graph/graphprint.h | 62 ++
fftools/resources/.gitignore | 4 +
fftools/resources/Makefile | 27 +
fftools/resources/graph.css | 353 +++++++++
fftools/resources/graph.html | 86 +++
fftools/resources/resman.c | 213 ++++++
fftools/resources/resman.h | 50 ++
fftools/textformat/avtextformat.c | 228 +++---
fftools/textformat/avtextformat.h | 67 +-
fftools/textformat/avtextwriters.h | 11 +-
fftools/textformat/tf_compact.c | 121 +--
fftools/textformat/tf_default.c | 55 +-
fftools/textformat/tf_flat.c | 51 +-
fftools/textformat/tf_ini.c | 62 +-
fftools/textformat/tf_internal.h | 81 ++
fftools/textformat/tf_json.c | 56 +-
fftools/textformat/tf_mermaid.c | 658 ++++++++++++++++
fftools/textformat/tf_mermaid.h | 41 +
fftools/textformat/tf_xml.c | 68 +-
fftools/textformat/tw_avio.c | 20 +-
fftools/textformat/tw_buffer.c | 9 +-
fftools/textformat/tw_stdout.c | 10 +-
libavfilter/avfilter.c | 9 +
libavfilter/avfilter.h | 12 +
37 files changed, 3682 insertions(+), 560 deletions(-)
create mode 100644 fftools/ffmpeg_filter.h
create mode 100644 fftools/graph/filelauncher.c
create mode 100644 fftools/graph/graphprint.c
create mode 100644 fftools/graph/graphprint.h
create mode 100644 fftools/resources/.gitignore
create mode 100644 fftools/resources/Makefile
create mode 100644 fftools/resources/graph.css
create mode 100644 fftools/resources/graph.html
create mode 100644 fftools/resources/resman.c
create mode 100644 fftools/resources/resman.h
create mode 100644 fftools/textformat/tf_internal.h
create mode 100644 fftools/textformat/tf_mermaid.c
create mode 100644 fftools/textformat/tf_mermaid.h
base-commit: 25b0a8e295749a60a238ba0d6fe7a3742937b6bb
Published-As: https://github.com/ffstaging/FFmpeg/releases/tag/pr-ffstaging-66%2Fsoftworkz%2Fsubmit_print_execution_graph-v6
Fetch-It-Via: git fetch https://github.com/ffstaging/FFmpeg pr-ffstaging-66/softworkz/submit_print_execution_graph-v6
Pull-Request: https://github.com/ffstaging/FFmpeg/pull/66
Range-diff vs v5:
1: 0672fc41e7 ! 1: b4bb8cdcc6 fftools/textformat: Formatting and whitespace changes
@@ Metadata
## Commit message ##
fftools/textformat: Formatting and whitespace changes
+ Reviewed-by: Stefano Sabatini <stefasab at gmail.com>
Signed-off-by: softworkz <softworkz at hotmail.com>
## fftools/textformat/avtextformat.c ##
2: 1e312f4685 ! 2: 1a4044ba23 fftools/textformat: Apply quality improvements
@@ Commit message
In particular:
- favor unsigned counters for loops
- add missing checks
- - avoid possibly leaks
+ - avoid possible leaks
- move variable declarations to inner scopes when feasible
- provide explicit type-casting when needed
3: c71836fce0 ! 3: 5972ecf213 fftools/avtextformat: Re-use BPrint in loop
@@ fftools/textformat/avtextformat.c: void avtext_print_integer(AVTextFormatContext
- const uint8_t *p, *endp;
+ const uint8_t *p, *endp, *srcp = (const uint8_t *)src;
AVBPrint dstbuf;
-+ AVBPrint bp;
++ AVBPrint bp_invalid_seq;
int invalid_chars_nb = 0, ret = 0;
+ *dstp = NULL;
av_bprint_init(&dstbuf, 0, AV_BPRINT_SIZE_UNLIMITED);
-+ av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
++ av_bprint_init(&bp_invalid_seq, 0, AV_BPRINT_SIZE_UNLIMITED);
- endp = src + strlen(src);
- for (p = src; *p;) {
@@ fftools/textformat/avtextformat.c: void avtext_print_integer(AVTextFormatContext
- bprint_bytes(&bp, p0, p-p0);
- av_log(tctx, AV_LOG_DEBUG,
- "Invalid UTF-8 sequence %s found in string '%s'\n", bp.str, src);
-+ av_bprint_clear(&bp);
-+ bprint_bytes(&bp, p0, p - p0);
-+ av_log(tctx, AV_LOG_DEBUG, "Invalid UTF-8 sequence %s found in string '%s'\n", bp.str, src);
++
++ av_bprint_clear(&bp_invalid_seq);
++
++ bprint_bytes(&bp_invalid_seq, p0, p - p0);
++
++ av_log(tctx, AV_LOG_DEBUG, "Invalid UTF-8 sequence %s found in string '%s'\n", bp_invalid_seq.str, src);
invalid = 1;
}
-@@ fftools/textformat/avtextformat.c: static inline int validate_string(AVTextFormatContext *tctx, char **dstp, const
- }
-
- if (!invalid || tctx->string_validation == AV_TEXTFORMAT_STRING_VALIDATION_IGNORE)
-- av_bprint_append_data(&dstbuf, p0, p-p0);
-+ av_bprint_append_data(&dstbuf, (const char *)p0, p - p0);
- }
-
- if (invalid_chars_nb && tctx->string_validation == AV_TEXTFORMAT_STRING_VALIDATION_REPLACE)
@@ fftools/textformat/avtextformat.c: static inline int validate_string(AVTextFormatContext *tctx, char **dstp, const
end:
av_bprint_finalize(&dstbuf, dstp);
-+ av_bprint_finalize(&bp, NULL);
++ av_bprint_finalize(&bp_invalid_seq, NULL);
return ret;
}
4: 26be409371 ! 4: 97ab9e0426 fftools/textformat: Introduce AVTextFormatOptions for avtext_context_open()
@@ Commit message
This allows future addition of options without
changes to the signature of avtext_context_open().
+ Reviewed-by: Stefano Sabatini <stefasab at gmail.com>
Signed-off-by: softworkz <softworkz at hotmail.com>
## fftools/ffprobe.c ##
@@ fftools/textformat/avtextformat.h: struct AVTextFormatContext {
#define AV_TEXTFORMAT_PRINT_STRING_OPTIONAL 1
#define AV_TEXTFORMAT_PRINT_STRING_VALIDATE 2
-+#define AV_TEXTFORMAT_OPEN_SHOW_VALUE_UNIT 1
-+#define AV_TEXTFORMAT_OPEN_USE_VALUE_PREFIX 2
-+#define AV_TEXTFORMAT_OPEN_USE_BYTE_BINARY_PREFIX 4
-+#define AV_TEXTFORMAT_OPEN_USE_VALUE_SEXAGESIMAL_FORMAT 8
-+#define AV_TEXTFORMAT_OPEN_SHOW_OPTIONAL_FIELDS 16
-+
int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *formatter, AVTextWriterContext *writer_context, const char *args,
- const AVTextFormatSection *sections, int nb_sections,
- int show_value_unit,
5: 89da2c883e ! 5: 6d1cf2b3fd fftools/textformat: Introduce common header and deduplicate code
@@ Metadata
## Commit message ##
fftools/textformat: Introduce common header and deduplicate code
+ Also change writer_printf signature in AVTextWriter to use va_list,
+ so that it can be called by the new function writer_printf()
+ in tf_internal.h.
+
+ Reviewed-by: Stefano Sabatini <stefasab at gmail.com>
Signed-off-by: softworkz <softworkz at hotmail.com>
+ ## fftools/textformat/avtextwriters.h ##
+@@ fftools/textformat/avtextwriters.h: typedef struct AVTextWriter {
+ void (*uninit)(AVTextWriterContext *wctx);
+ void (*writer_w8)(AVTextWriterContext *wctx, int b);
+ void (*writer_put_str)(AVTextWriterContext *wctx, const char *str);
+- void (*writer_printf)(AVTextWriterContext *wctx, const char *fmt, ...);
++ void (*writer_vprintf)(AVTextWriterContext *wctx, const char *fmt, va_list vl);
+ } AVTextWriter;
+
+ typedef struct AVTextWriterContext {
+
## fftools/textformat/tf_compact.c ##
@@
#include "libavutil/bprint.h"
@@ fftools/textformat/tf_internal.h (new)
+{
+ va_list args;
+ va_start(args, fmt);
-+ wctx->writer->writer->writer_printf(wctx->writer, fmt, args);
++ wctx->writer->writer->writer_vprintf(wctx->writer, fmt, args);
+ va_end(args);
+}
+
@@ fftools/textformat/tf_xml.c: const AVTextFormatter avtextformatter_xml = {
.priv_class = &xml_class,
};
-
+
+ ## fftools/textformat/tw_avio.c ##
+@@ fftools/textformat/tw_avio.c: static void io_put_str(AVTextWriterContext *wctx, const char *str)
+ avio_write(ctx->avio_context, (const unsigned char *)str, (int)strlen(str));
+ }
+
+-static void io_printf(AVTextWriterContext *wctx, const char *fmt, ...)
++static void io_vprintf(AVTextWriterContext *wctx, const char *fmt, va_list vl)
+ {
+ IOWriterContext *ctx = wctx->priv;
+- va_list ap;
+
+- va_start(ap, fmt);
+- avio_vprintf(ctx->avio_context, fmt, ap);
+- va_end(ap);
++ avio_vprintf(ctx->avio_context, fmt, vl);
+ }
+
+
+@@ fftools/textformat/tw_avio.c: const AVTextWriter avtextwriter_avio = {
+ .priv_size = sizeof(IOWriterContext),
+ .uninit = iowriter_uninit,
+ .writer_put_str = io_put_str,
+- .writer_printf = io_printf,
++ .writer_vprintf = io_vprintf,
+ .writer_w8 = io_w8
+ };
+
+
+ ## fftools/textformat/tw_buffer.c ##
+@@ fftools/textformat/tw_buffer.c: static void buffer_put_str(AVTextWriterContext *wctx, const char *str)
+ av_bprintf(ctx->buffer, "%s", str);
+ }
+
+-static void buffer_printf(AVTextWriterContext *wctx, const char *fmt, ...)
++static void buffer_vprintf(AVTextWriterContext *wctx, const char *fmt, va_list vl)
+ {
+ BufferWriterContext *ctx = wctx->priv;
+
+- va_list vargs;
+- va_start(vargs, fmt);
+- av_vbprintf(ctx->buffer, fmt, vargs);
+- va_end(vargs);
++ av_vbprintf(ctx->buffer, fmt, vl);
+ }
+
+
+@@ fftools/textformat/tw_buffer.c: const AVTextWriter avtextwriter_buffer = {
+ .priv_size = sizeof(BufferWriterContext),
+ .priv_class = &bufferwriter_class,
+ .writer_put_str = buffer_put_str,
+- .writer_printf = buffer_printf,
++ .writer_vprintf = buffer_vprintf,
+ .writer_w8 = buffer_w8
+ };
+
+
+ ## fftools/textformat/tw_stdout.c ##
+@@ fftools/textformat/tw_stdout.c: static inline void stdout_put_str(AVTextWriterContext *wctx, const char *str)
+ printf("%s", str);
+ }
+
+-static inline void stdout_printf(AVTextWriterContext *wctx, const char *fmt, ...)
++static inline void stdout_vprintf(AVTextWriterContext *wctx, const char *fmt, va_list vl)
+ {
+- va_list ap;
+-
+- va_start(ap, fmt);
+- vprintf(fmt, ap);
+- va_end(ap);
++ vprintf(fmt, vl);
+ }
+
+
+@@ fftools/textformat/tw_stdout.c: static const AVTextWriter avtextwriter_stdout = {
+ .priv_size = sizeof(StdOutWriterContext),
+ .priv_class = &stdoutwriter_class,
+ .writer_put_str = stdout_put_str,
+- .writer_printf = stdout_printf,
++ .writer_vprintf = stdout_vprintf,
+ .writer_w8 = stdout_w8
+ };
+
6: ecf6f061b2 < -: ---------- fftools/textformat: AVTextWriter change writer_printf signature
7: c190f79565 ! 6: fa22ead3ef fftools/tf_internal: Use av_default_item_name
@@ Metadata
## Commit message ##
fftools/tf_internal: Use av_default_item_name
+ Reviewed-by: Stefano Sabatini <stefasab at gmail.com>
Signed-off-by: softworkz <softworkz at hotmail.com>
## fftools/textformat/tf_internal.h ##
8: 1fe4a8fe6c ! 7: 59dfd3ded6 fftools/textformat: Add function avtext_print_integer_flags()
@@ fftools/textformat/avtextformat.c: void avtext_print_integer(AVTextFormatContext
+void avtext_print_integer_flags(AVTextFormatContext *tctx, const char *key, int64_t val, int flags)
+{
-+ const AVTextFormatSection *section;
++ av_assert0(tctx);
+
-+ if (!tctx || !key || tctx->level < 0 || tctx->level >= SECTION_MAX_NB_LEVELS)
++ if (tctx->show_optional_fields == SHOW_OPTIONAL_FIELDS_NEVER)
+ return;
+
-+ section = tctx->section[tctx->level];
-+
-+ if (tctx->show_optional_fields == SHOW_OPTIONAL_FIELDS_NEVER ||
-+ (tctx->show_optional_fields == SHOW_OPTIONAL_FIELDS_AUTO
-+ && (flags & AV_TEXTFORMAT_PRINT_STRING_OPTIONAL)
-+ && !(tctx->formatter->flags & AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS)))
++ if (tctx->show_optional_fields == SHOW_OPTIONAL_FIELDS_AUTO
++ && (flags & AV_TEXTFORMAT_PRINT_STRING_OPTIONAL)
++ && !(tctx->formatter->flags & AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS))
+ return;
+
-+ if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) {
-+ tctx->formatter->print_integer(tctx, key, val);
-+ tctx->nb_item[tctx->level]++;
-+ }
++ avtext_print_integer(tctx, key, val);
+}
+
static inline int validate_string(AVTextFormatContext *tctx, char **dstp, const char *src)
{
const uint8_t *p, *endp, *srcp = (const uint8_t *)src;
+@@ fftools/textformat/avtextformat.c: int avtext_print_string(AVTextFormatContext *tctx, const char *key, const char *
+
+ section = tctx->section[tctx->level];
+
+- if (tctx->show_optional_fields == SHOW_OPTIONAL_FIELDS_NEVER ||
+- (tctx->show_optional_fields == SHOW_OPTIONAL_FIELDS_AUTO
+- && (flags & AV_TEXTFORMAT_PRINT_STRING_OPTIONAL)
+- && !(tctx->formatter->flags & AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS)))
++ if (tctx->show_optional_fields == SHOW_OPTIONAL_FIELDS_NEVER)
++ return 0;
++
++ if (tctx->show_optional_fields == SHOW_OPTIONAL_FIELDS_AUTO
++ && (flags & AV_TEXTFORMAT_PRINT_STRING_OPTIONAL)
++ && !(tctx->formatter->flags & AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS))
+ return 0;
+
+ if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) {
## fftools/textformat/avtextformat.h ##
@@ fftools/textformat/avtextformat.h: void avtext_print_section_footer(AVTextFormatContext *tctx);
9: ba034ef3b1 = 8: 55a704faa5 fftools/ffmpeg_filter: Move some declaration to new header file
10: 6e31aa603a = 9: b6320cab8c avfilter/avfilter: Add avfilter_link_get_hw_frames_ctx()
11: ea2d41b048 = 10: 0e3e9b3e40 fftools/resources: Add resource manager files
12: 4fa179848a = 11: 9464b8d9f4 fftools/ffmpeg_mux: Make ms_from_ost() inline
13: 62d4cab294 ! 12: 2b271af447 fftools/graphprint: Add execution graph printing
@@ fftools/graph/graphprint.c (new)
+ AVBPrint buf;
+ AVTextFormatSectionContext sec_ctx = { 0 };
+
-+ sec_ctx.context_id = "Inputs";
-+
+ av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
+
+ print_section_header_id(gpc, SECTION_ID_INPUTFILES, "Inputs", 0);
14: 35fc23039e ! 13: a23cc583de fftools/graphprint: Now, make it a Killer-Feature!
@@ fftools/graph/filelauncher.c (new)
+}
## fftools/graph/graphprint.c ##
-@@ fftools/graph/graphprint.c: static int print_streams(GraphPrintContext *gpc, InputFile **ifiles, int nb_ifil
- AVBPrint buf;
- AVTextFormatSectionContext sec_ctx = { 0 };
-
-- sec_ctx.context_id = "Inputs";
--
- av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
-
- print_section_header_id(gpc, SECTION_ID_INPUTFILES, "Inputs", 0);
@@ fftools/graph/graphprint.c: static int init_graphprint(GraphPrintContext **pgpc, AVBPrint *target_buf)
av_bprint_init(target_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
--
ffmpeg-codebot
More information about the ffmpeg-devel
mailing list