Andreas Rheinhardt: > Patches attached. > > - Andreas > v2 attached.
- Andreas
From f9ca71e0ef66830ba9a9a04f9f44d76abe352a0f Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Fri, 30 May 2025 16:02:08 +0200 Subject: [PATCH v2 01/11] fftools/graph/graphprint: Fix races when initializing graphprint Setting print_graphs_format (in case no -print_graphs_format option was specified) is racy, as is using av_strtok() to split it. Both have been removed. Notice that using av_strtok() was destructive: In the absence of races the options would only have been applied for the first initialization. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- fftools/graph/graphprint.c | 19 ++++--------------- fftools/textformat/avtextformat.c | 7 +++++-- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/fftools/graph/graphprint.c b/fftools/graph/graphprint.c index 852a8f6c0c..f87ccfa0e7 100644 --- a/fftools/graph/graphprint.c +++ b/fftools/graph/graphprint.c @@ -875,8 +875,6 @@ static int init_graphprint(GraphPrintContext **pgpc, AVBPrint *target_buf) AVTextFormatContext *tfc = NULL; AVTextWriterContext *wctx = NULL; GraphPrintContext *gpc = NULL; - char *w_args = NULL; - char *w_name; int ret; init_sections(); @@ -884,19 +882,7 @@ static int init_graphprint(GraphPrintContext **pgpc, AVBPrint *target_buf) av_bprint_init(target_buf, 0, AV_BPRINT_SIZE_UNLIMITED); - if (!print_graphs_format) - print_graphs_format = av_strdup("json"); - if (!print_graphs_format) { - ret = AVERROR(ENOMEM); - goto fail; - } - - w_name = av_strtok(print_graphs_format, "=", &w_args); - if (!w_name) { - av_log(NULL, AV_LOG_ERROR, "No name specified for the filter graph output format\n"); - ret = AVERROR(EINVAL); - goto fail; - } + const char *w_name = print_graphs_format ? print_graphs_format : "json"; text_formatter = avtext_get_formatter_by_name(w_name); if (!text_formatter) { @@ -913,6 +899,9 @@ static int init_graphprint(GraphPrintContext **pgpc, AVBPrint *target_buf) } AVTextFormatOptions tf_options = { .show_optional_fields = -1 }; + const char *w_args = print_graphs_format ? strchr(print_graphs_format, '=') : NULL; + if (w_args) + ++w_args; // consume '=' ret = avtext_context_open(&tfc, text_formatter, wctx, w_args, sections, FF_ARRAY_ELEMS(sections), tf_options, NULL); if (ret < 0) { goto fail; diff --git a/fftools/textformat/avtextformat.c b/fftools/textformat/avtextformat.c index bb90e66918..e8e43c3c37 100644 --- a/fftools/textformat/avtextformat.c +++ b/fftools/textformat/avtextformat.c @@ -706,9 +706,12 @@ const AVTextFormatter *avtext_get_formatter_by_name(const char *name) { formatters_register_all(); - for (int i = 0; registered_formatters[i]; i++) - if (!strcmp(registered_formatters[i]->name, name)) + for (int i = 0; registered_formatters[i]; i++) { + const char *end; + if (av_strstart(name, registered_formatters[i]->name, &end) && + (*end == '\0' || *end == '=')) return registered_formatters[i]; + } return NULL; } -- 2.45.2
From eecebb8da4094472ddda35bfcef3e9337e9ce92f Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Sun, 1 Jun 2025 00:13:54 +0200 Subject: [PATCH v2 02/11] fftools/textformat/avtextformat: Separate mutable and immutable data Only two fields of AVTextFormatSection are ever modified: entries_to_show and show_all_entries (they are only used by ffprobe; the graph printing code always prints everything). These fields do not belong into AVTextFormatSection, they are more ffprobe-internal (and if the graph printing code ever made use of them, these fields could very well be per GraphPrintContext). This commit therefore moves them out of AVTextFormatSection and adds a callback to AVTextFormatContext to decide which elements to discard. This also allows to make the AVTextFormatSections const. This also fixes a race when initializing the sections for graphprint. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- fftools/ffprobe.c | 38 +++++++++++++++++++++++-------- fftools/graph/graphprint.c | 9 +------- fftools/textformat/avtextformat.c | 9 +++----- fftools/textformat/avtextformat.h | 13 +++++++++-- 4 files changed, 44 insertions(+), 25 deletions(-) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 80ce38e73b..77a0ea67bf 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -246,7 +246,7 @@ static const char *get_stream_group_type(const void *data) return av_x_if_null(avformat_stream_group_name(stg->type), "unknown"); } -static struct AVTextFormatSection sections[] = { +static const AVTextFormatSection sections[] = { [SECTION_ID_CHAPTERS] = { SECTION_ID_CHAPTERS, "chapters", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_CHAPTER, -1 } }, [SECTION_ID_CHAPTER] = { SECTION_ID_CHAPTER, "chapter", 0, { SECTION_ID_CHAPTER_TAGS, -1 } }, [SECTION_ID_CHAPTER_TAGS] = { SECTION_ID_CHAPTER_TAGS, "tags", AV_TEXTFORMAT_SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "chapter_tags" }, @@ -318,6 +318,13 @@ static struct AVTextFormatSection sections[] = { [SECTION_ID_SUBTITLE] = { SECTION_ID_SUBTITLE, "subtitle", 0, { -1 } }, }; +typedef struct EntrySelection { + int show_all_entries; + AVDictionary *entries_to_show; +} EntrySelection; + +static EntrySelection selected_entries[FF_ARRAY_ELEMS(sections)] = { 0 }; + static const OptionDef *options; /* FFprobe context */ @@ -352,6 +359,14 @@ typedef struct LogBuffer { static LogBuffer *log_buffer; static int log_buffer_size; +static int is_key_selected_callback(AVTextFormatContext *tctx, const char *key) +{ + const AVTextFormatSection *section = tctx->section[tctx->level]; + const EntrySelection *selection = &selected_entries[section - sections]; + + return selection->show_all_entries || av_dict_get(selection->entries_to_show, key, NULL, 0); +} + static void log_callback(void *ptr, int level, const char *fmt, va_list vl) { AVClass* avc = ptr ? *(AVClass **) ptr : NULL; @@ -2655,14 +2670,15 @@ static int opt_format(void *optctx, const char *opt, const char *arg) static inline void mark_section_show_entries(SectionID section_id, int show_all_entries, AVDictionary *entries) { - struct AVTextFormatSection *section = §ions[section_id]; + EntrySelection *selection = &selected_entries[section_id]; - section->show_all_entries = show_all_entries; + selection->show_all_entries = show_all_entries; if (show_all_entries) { + const AVTextFormatSection *section = §ions[section_id]; for (const int *id = section->children_ids; *id != -1; id++) mark_section_show_entries(*id, show_all_entries, entries); } else { - av_dict_copy(§ion->entries_to_show, entries, 0); + av_dict_copy(&selection->entries_to_show, entries, 0); } } @@ -3053,9 +3069,12 @@ static const OptionDef real_options[] = { static inline int check_section_show_entries(int section_id) { - struct AVTextFormatSection *section = §ions[section_id]; - if (sections[section_id].show_all_entries || sections[section_id].entries_to_show) + const EntrySelection *selection = &selected_entries[section_id]; + + if (selection->show_all_entries || selection->entries_to_show) return 1; + + const AVTextFormatSection *section = §ions[section_id]; for (const int *id = section->children_ids; *id != -1; id++) if (check_section_show_entries(*id)) return 1; @@ -3074,7 +3093,7 @@ int main(int argc, char **argv) AVTextWriterContext *wctx; char *buf; char *f_name = NULL, *f_args = NULL; - int ret, input_ret, i; + int ret, input_ret; init_dynload(); @@ -3168,6 +3187,7 @@ int main(int argc, char **argv) goto end; AVTextFormatOptions tf_options = { + .is_key_selected = is_key_selected_callback, .show_optional_fields = show_optional_fields, .show_value_unit = show_value_unit, .use_value_prefix = use_value_prefix, @@ -3224,8 +3244,8 @@ end: av_freep(&read_intervals); uninit_opts(); - for (i = 0; i < FF_ARRAY_ELEMS(sections); i++) - av_dict_free(&(sections[i].entries_to_show)); + for (size_t i = 0; i < FF_ARRAY_ELEMS(selected_entries); ++i) + av_dict_free(&selected_entries[i].entries_to_show); avformat_network_deinit(); diff --git a/fftools/graph/graphprint.c b/fftools/graph/graphprint.c index f87ccfa0e7..71dd421245 100644 --- a/fftools/graph/graphprint.c +++ b/fftools/graph/graphprint.c @@ -74,7 +74,7 @@ typedef enum { SECTION_ID_ENCODER, } SectionID; -static struct AVTextFormatSection sections[] = { +static const AVTextFormatSection sections[] = { [SECTION_ID_ROOT] = { SECTION_ID_ROOT, "root", AV_TEXTFORMAT_SECTION_FLAG_IS_WRAPPER, { SECTION_ID_FILTERGRAPHS, SECTION_ID_INPUTFILES, SECTION_ID_OUTPUTFILES, SECTION_ID_DECODERS, SECTION_ID_ENCODERS, SECTION_ID_STREAMLINKS, -1 } }, [SECTION_ID_FILTERGRAPHS] = { SECTION_ID_FILTERGRAPHS, "graphs", AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY, { SECTION_ID_FILTERGRAPH, -1 } }, @@ -470,12 +470,6 @@ static void print_filter(GraphPrintContext *gpc, const AVFilterContext *filter, avtext_print_section_footer(tfc); // SECTION_ID_FILTER } -static void init_sections(void) -{ - for (unsigned i = 0; i < FF_ARRAY_ELEMS(sections); i++) - sections[i].show_all_entries = 1; -} - static void print_filtergraph_single(GraphPrintContext *gpc, FilterGraph *fg, AVFilterGraph *graph) { AVTextFormatContext *tfc = gpc->tfc; @@ -877,7 +871,6 @@ static int init_graphprint(GraphPrintContext **pgpc, AVBPrint *target_buf) GraphPrintContext *gpc = NULL; int ret; - init_sections(); *pgpc = NULL; av_bprint_init(target_buf, 0, AV_BPRINT_SIZE_UNLIMITED); diff --git a/fftools/textformat/avtextformat.c b/fftools/textformat/avtextformat.c index e8e43c3c37..8a87b9ee2c 100644 --- a/fftools/textformat/avtextformat.c +++ b/fftools/textformat/avtextformat.c @@ -150,6 +150,7 @@ int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *form goto fail; } + tctx->is_key_selected = options.is_key_selected; tctx->show_value_unit = options.show_value_unit; tctx->use_value_prefix = options.use_value_prefix; tctx->use_byte_value_binary_prefix = options.use_byte_value_binary_prefix; @@ -293,8 +294,6 @@ void avtext_print_section_footer(AVTextFormatContext *tctx) void avtext_print_integer(AVTextFormatContext *tctx, const char *key, int64_t val, int flags) { - const AVTextFormatSection *section; - av_assert0(tctx); if (tctx->show_optional_fields == SHOW_OPTIONAL_FIELDS_NEVER) @@ -307,9 +306,7 @@ void avtext_print_integer(AVTextFormatContext *tctx, const char *key, int64_t va av_assert0(key && tctx->level >= 0 && tctx->level < SECTION_MAX_NB_LEVELS); - section = tctx->section[tctx->level]; - - if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) { + if (!tctx->is_key_selected || tctx->is_key_selected(tctx, key)) { tctx->formatter->print_integer(tctx, key, val); tctx->nb_item[tctx->level]++; } @@ -464,7 +461,7 @@ int avtext_print_string(AVTextFormatContext *tctx, const char *key, const char * && !(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)) { + if (!tctx->is_key_selected || tctx->is_key_selected(tctx, key)) { if (flags & AV_TEXTFORMAT_PRINT_STRING_VALIDATE) { char *key1 = NULL, *val1 = NULL; ret = validate_string(tctx, &key1, key); diff --git a/fftools/textformat/avtextformat.h b/fftools/textformat/avtextformat.h index cf23d93871..bd8c5d742f 100644 --- a/fftools/textformat/avtextformat.h +++ b/fftools/textformat/avtextformat.h @@ -57,9 +57,7 @@ typedef struct AVTextFormatSection { const int children_ids[SECTION_MAX_NB_CHILDREN + 1]; ///< list of children section IDS, terminated by -1 const char *element_name; ///< name of the contained element, if provided const char *unique_name; ///< unique section name, in case the name is ambiguous - AVDictionary *entries_to_show; const char *(*get_type)(const void *data); ///< function returning a type if defined, must be defined when SECTION_FLAG_HAS_TYPE is defined - int show_all_entries; const char *id_key; ///< name of the key to be used as the id const char *src_id_key; ///< name of the key to be used as the source id for diagram connections const char *dest_id_key; ///< name of the key to be used as the target id for diagram connections @@ -131,6 +129,16 @@ struct AVTextFormatContext { AVBPrint section_pbuf[SECTION_MAX_NB_LEVELS]; ///< generic print buffer dedicated to each section, /// used by various formatters + /** + * Callback to discard certain elements based upon the key used. + * It is called before any element with a key is printed. + * If this callback is unset, all elements are printed. + * + * @retval 1 if the element is supposed to be printed + * @retval 0 if the element is supposed to be discarded + */ + int (*is_key_selected)(struct AVTextFormatContext *tctx, const char *key); + int show_optional_fields; int show_value_unit; int use_value_prefix; @@ -145,6 +153,7 @@ struct AVTextFormatContext { }; typedef struct AVTextFormatOptions { + int (*is_key_selected)(struct AVTextFormatContext *tctx, const char *key); int show_optional_fields; int show_value_unit; int use_value_prefix; -- 2.45.2
From 109843e52da507b8d78e70050157746345b490d9 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Sun, 1 Jun 2025 03:33:00 +0200 Subject: [PATCH v2 03/11] fftools/textformat/avtextformat: Avoid relocations Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- fftools/textformat/avtextformat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fftools/textformat/avtextformat.c b/fftools/textformat/avtextformat.c index 8a87b9ee2c..81c6b0f0e5 100644 --- a/fftools/textformat/avtextformat.c +++ b/fftools/textformat/avtextformat.c @@ -43,8 +43,8 @@ static const struct { double bin_val; double dec_val; - const char *bin_str; - const char *dec_str; + char bin_str[4]; + char dec_str[4]; } si_prefixes[] = { { 1.0, 1.0, "", "" }, { 1.024e3, 1e3, "Ki", "K" }, -- 2.45.2
From be5d966c8d422546eb403cc4c0a007cfb459708c Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Sun, 1 Jun 2025 04:15:58 +0200 Subject: [PATCH v2 04/11] fftools/resources/resman: Don't alloc ResourceManager, fix race The resman_ctx pointer was accessed outside of its guarding mutex. Also make the ResourceManager static. Reviewed-by: softworkz . <softworkz-at-hotmail....@ffmpeg.org> Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- fftools/resources/resman.c | 37 +++---------------------------------- 1 file changed, 3 insertions(+), 34 deletions(-) diff --git a/fftools/resources/resman.c b/fftools/resources/resman.c index a9e21626fa..e596c28039 100644 --- a/fftools/resources/resman.c +++ b/fftools/resources/resman.c @@ -61,7 +61,7 @@ typedef struct ResourceManagerContext { static AVMutex mutex = AV_MUTEX_INITIALIZER; -ResourceManagerContext *resman_ctx = NULL; +static ResourceManagerContext resman_ctx = { .class = &resman_class }; #if CONFIG_RESOURCE_COMPRESSION @@ -118,39 +118,11 @@ static int decompress_gzip(ResourceManagerContext *ctx, uint8_t *in, unsigned in } #endif -static ResourceManagerContext *get_resman_context(void) -{ - ResourceManagerContext *res = resman_ctx; - - ff_mutex_lock(&mutex); - - if (res) - goto end; - - res = av_mallocz(sizeof(ResourceManagerContext)); - if (!res) { - av_log(NULL, AV_LOG_ERROR, "Failed to allocate resource manager context\n"); - goto end; - } - - res->class = &resman_class; - resman_ctx = res; - -end: - ff_mutex_unlock(&mutex); - return res; -} - - void ff_resman_uninit(void) { ff_mutex_lock(&mutex); - if (resman_ctx) { - if (resman_ctx->resource_dic) - av_dict_free(&resman_ctx->resource_dic); - av_freep(&resman_ctx); - } + av_dict_free(&resman_ctx.resource_dic); ff_mutex_unlock(&mutex); } @@ -158,14 +130,11 @@ void ff_resman_uninit(void) char *ff_resman_get_string(FFResourceId resource_id) { - ResourceManagerContext *ctx = get_resman_context(); + ResourceManagerContext *ctx = &resman_ctx; FFResourceDefinition resource_definition = { 0 }; AVDictionaryEntry *dic_entry; char *res = NULL; - if (!ctx) - return NULL; - for (unsigned i = 0; i < FF_ARRAY_ELEMS(resource_definitions); ++i) { FFResourceDefinition def = resource_definitions[i]; if (def.resource_id == resource_id) { -- 2.45.2
From f6d469ca8484dfa44e6ba3cdeba6aec641b75d3a Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Sun, 1 Jun 2025 04:20:32 +0200 Subject: [PATCH v2 05/11] fftools/resources/resman: Use assert for always-false condition Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- fftools/resources/resman.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fftools/resources/resman.c b/fftools/resources/resman.c index e596c28039..dcbf43097d 100644 --- a/fftools/resources/resman.c +++ b/fftools/resources/resman.c @@ -143,10 +143,7 @@ char *ff_resman_get_string(FFResourceId resource_id) } } - if (!resource_definition.name) { - av_log(ctx, AV_LOG_ERROR, "Unable to find resource with ID %d\n", resource_id); - return NULL; - } + av_assert1(resource_definition.name); ff_mutex_lock(&mutex); -- 2.45.2
From 07c9664733e92fdd1e9a7d2372a8ca35508e1ca8 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Sun, 1 Jun 2025 13:06:14 +0200 Subject: [PATCH v2 06/11] fftools/resources/resman: Use proper logcontext Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- fftools/resources/resman.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fftools/resources/resman.c b/fftools/resources/resman.c index dcbf43097d..1c0cdb942d 100644 --- a/fftools/resources/resman.c +++ b/fftools/resources/resman.c @@ -160,13 +160,13 @@ char *ff_resman_get_string(FFResourceId resource_id) int ret = decompress_gzip(ctx, (uint8_t *)resource_definition.data, *resource_definition.data_len, &out, &out_len); if (ret) { - av_log(NULL, AV_LOG_ERROR, "Unable to decompress the resource with ID %d\n", resource_id); + av_log(ctx, AV_LOG_ERROR, "Unable to decompress the resource with ID %d\n", resource_id); goto end; } dict_ret = av_dict_set(&ctx->resource_dic, resource_definition.name, out, 0); if (dict_ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Failed to store decompressed resource in dictionary: %d\n", dict_ret); + av_log(ctx, AV_LOG_ERROR, "Failed to store decompressed resource in dictionary: %d\n", dict_ret); av_freep(&out); goto end; } @@ -176,7 +176,7 @@ char *ff_resman_get_string(FFResourceId resource_id) dict_ret = av_dict_set(&ctx->resource_dic, resource_definition.name, (const char *)resource_definition.data, 0); if (dict_ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Failed to store resource in dictionary: %d\n", dict_ret); + av_log(ctx, AV_LOG_ERROR, "Failed to store resource in dictionary: %d\n", dict_ret); goto end; } @@ -184,7 +184,7 @@ char *ff_resman_get_string(FFResourceId resource_id) dic_entry = av_dict_get(ctx->resource_dic, resource_definition.name, NULL, 0); if (!dic_entry) { - av_log(NULL, AV_LOG_ERROR, "Failed to retrieve resource from dictionary after storing it\n"); + av_log(ctx, AV_LOG_ERROR, "Failed to retrieve resource from dictionary after storing it\n"); goto end; } } -- 2.45.2
From edd6477256f13432efac6673c93d830a7b38fd91 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Sun, 1 Jun 2025 04:28:12 +0200 Subject: [PATCH v2 07/11] fftools/textformat/avtextformat: Fix races when initializing formatters Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- fftools/textformat/avtextformat.c | 33 +++++++++++-------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/fftools/textformat/avtextformat.c b/fftools/textformat/avtextformat.c index 81c6b0f0e5..30a017d1a1 100644 --- a/fftools/textformat/avtextformat.c +++ b/fftools/textformat/avtextformat.c @@ -678,31 +678,22 @@ fail: return ret; } -static const AVTextFormatter *registered_formatters[9 + 1]; - -static void formatters_register_all(void) +static const AVTextFormatter *const registered_formatters[] = { - static int initialized; - - if (initialized) - return; - initialized = 1; - - registered_formatters[0] = &avtextformatter_default; - registered_formatters[1] = &avtextformatter_compact; - registered_formatters[2] = &avtextformatter_csv; - registered_formatters[3] = &avtextformatter_flat; - registered_formatters[4] = &avtextformatter_ini; - registered_formatters[5] = &avtextformatter_json; - registered_formatters[6] = &avtextformatter_xml; - registered_formatters[7] = &avtextformatter_mermaid; - registered_formatters[8] = &avtextformatter_mermaidhtml; -} + &avtextformatter_default, + &avtextformatter_compact, + &avtextformatter_csv, + &avtextformatter_flat, + &avtextformatter_ini, + &avtextformatter_json, + &avtextformatter_xml, + &avtextformatter_mermaid, + &avtextformatter_mermaidhtml, + NULL +}; const AVTextFormatter *avtext_get_formatter_by_name(const char *name) { - formatters_register_all(); - for (int i = 0; registered_formatters[i]; i++) { const char *end; if (av_strstart(name, registered_formatters[i]->name, &end) && -- 2.45.2
From d2971ee087bc07a49454335e77cab7af966ff3bc Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Sun, 1 Jun 2025 04:54:45 +0200 Subject: [PATCH v2 08/11] fftools/ffprobe: Factor writing common side data types out Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- fftools/ffprobe.c | 95 +++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 52 deletions(-) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 77a0ea67bf..5cf5839202 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -472,6 +472,43 @@ static inline int show_tags(AVTextFormatContext *tfc, AVDictionary *tags, int se return ret; } +static void print_displaymatrix(AVTextFormatContext *tfc, const int32_t matrix[9]) +{ + double rotation = av_display_rotation_get(matrix); + if (isnan(rotation)) + rotation = 0; + avtext_print_integers(tfc, "displaymatrix", (void*)matrix, 9, " %11d", 3, 4, 1); + print_int("rotation", rotation); +} + +static void print_mastering_display_metadata(AVTextFormatContext *tfc, + const AVMasteringDisplayMetadata *metadata) +{ + if (metadata->has_primaries) { + print_q("red_x", metadata->display_primaries[0][0], '/'); + print_q("red_y", metadata->display_primaries[0][1], '/'); + print_q("green_x", metadata->display_primaries[1][0], '/'); + print_q("green_y", metadata->display_primaries[1][1], '/'); + print_q("blue_x", metadata->display_primaries[2][0], '/'); + print_q("blue_y", metadata->display_primaries[2][1], '/'); + + print_q("white_point_x", metadata->white_point[0], '/'); + print_q("white_point_y", metadata->white_point[1], '/'); + } + + if (metadata->has_luminance) { + print_q("min_luminance", metadata->min_luminance, '/'); + print_q("max_luminance", metadata->max_luminance, '/'); + } +} + +static void print_context_light_level(AVTextFormatContext *tfc, + const AVContentLightMetadata *metadata) +{ + print_int("max_content", metadata->MaxCLL); + print_int("max_average", metadata->MaxFALL); +} + static void print_dovi_metadata(AVTextFormatContext *tfc, const AVDOVIMetadata *dovi) { if (!dovi) @@ -949,11 +986,7 @@ static void print_pkt_side_data(AVTextFormatContext *tfc, avtext_print_section_header(tfc, sd, id_data); print_str("side_data_type", name ? name : "unknown"); if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9*4) { - double rotation = av_display_rotation_get((int32_t *)sd->data); - if (isnan(rotation)) - rotation = 0; - avtext_print_integers(tfc, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1); - print_int("rotation", rotation); + print_displaymatrix(tfc, (const int32_t*)sd->data); } else if (sd->type == AV_PKT_DATA_STEREO3D) { const AVStereo3D *stereo = (AVStereo3D *)sd->data; print_str("type", av_stereo3d_type_name(stereo->type)); @@ -987,28 +1020,9 @@ static void print_pkt_side_data(AVTextFormatContext *tfc, print_int("skip_reason", AV_RL8(sd->data + 8)); print_int("discard_reason", AV_RL8(sd->data + 9)); } else if (sd->type == AV_PKT_DATA_MASTERING_DISPLAY_METADATA) { - AVMasteringDisplayMetadata *metadata = (AVMasteringDisplayMetadata *)sd->data; - - if (metadata->has_primaries) { - print_q("red_x", metadata->display_primaries[0][0], '/'); - print_q("red_y", metadata->display_primaries[0][1], '/'); - print_q("green_x", metadata->display_primaries[1][0], '/'); - print_q("green_y", metadata->display_primaries[1][1], '/'); - print_q("blue_x", metadata->display_primaries[2][0], '/'); - print_q("blue_y", metadata->display_primaries[2][1], '/'); - - print_q("white_point_x", metadata->white_point[0], '/'); - print_q("white_point_y", metadata->white_point[1], '/'); - } - - if (metadata->has_luminance) { - print_q("min_luminance", metadata->min_luminance, '/'); - print_q("max_luminance", metadata->max_luminance, '/'); - } + print_mastering_display_metadata(tfc, (AVMasteringDisplayMetadata *)sd->data); } else if (sd->type == AV_PKT_DATA_CONTENT_LIGHT_LEVEL) { - AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data; - print_int("max_content", metadata->MaxCLL); - print_int("max_average", metadata->MaxFALL); + print_context_light_level(tfc, (AVContentLightMetadata *)sd->data); } else if (sd->type == AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT) { print_ambient_viewing_environment( tfc, (const AVAmbientViewingEnvironment *)sd->data); @@ -1294,11 +1308,7 @@ static void print_frame_side_data(AVTextFormatContext *tfc, name = av_frame_side_data_name(sd->type); print_str("side_data_type", name ? name : "unknown"); if (sd->type == AV_FRAME_DATA_DISPLAYMATRIX && sd->size >= 9*4) { - double rotation = av_display_rotation_get((int32_t *)sd->data); - if (isnan(rotation)) - rotation = 0; - avtext_print_integers(tfc, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1); - print_int("rotation", rotation); + print_displaymatrix(tfc, (const int32_t*)sd->data); } else if (sd->type == AV_FRAME_DATA_AFD && sd->size > 0) { print_int("active_format", *sd->data); } else if (sd->type == AV_FRAME_DATA_GOP_TIMECODE && sd->size >= 8) { @@ -1318,31 +1328,12 @@ static void print_frame_side_data(AVTextFormatContext *tfc, } avtext_print_section_footer(tfc); } else if (sd->type == AV_FRAME_DATA_MASTERING_DISPLAY_METADATA) { - AVMasteringDisplayMetadata *metadata = (AVMasteringDisplayMetadata *)sd->data; - - if (metadata->has_primaries) { - print_q("red_x", metadata->display_primaries[0][0], '/'); - print_q("red_y", metadata->display_primaries[0][1], '/'); - print_q("green_x", metadata->display_primaries[1][0], '/'); - print_q("green_y", metadata->display_primaries[1][1], '/'); - print_q("blue_x", metadata->display_primaries[2][0], '/'); - print_q("blue_y", metadata->display_primaries[2][1], '/'); - - print_q("white_point_x", metadata->white_point[0], '/'); - print_q("white_point_y", metadata->white_point[1], '/'); - } - - if (metadata->has_luminance) { - print_q("min_luminance", metadata->min_luminance, '/'); - print_q("max_luminance", metadata->max_luminance, '/'); - } + print_mastering_display_metadata(tfc, (AVMasteringDisplayMetadata *)sd->data); } else if (sd->type == AV_FRAME_DATA_DYNAMIC_HDR_PLUS) { AVDynamicHDRPlus *metadata = (AVDynamicHDRPlus *)sd->data; print_dynamic_hdr10_plus(tfc, metadata); } else if (sd->type == AV_FRAME_DATA_CONTENT_LIGHT_LEVEL) { - AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data; - print_int("max_content", metadata->MaxCLL); - print_int("max_average", metadata->MaxFALL); + print_context_light_level(tfc, (AVContentLightMetadata *)sd->data); } else if (sd->type == AV_FRAME_DATA_ICC_PROFILE) { const AVDictionaryEntry *tag = av_dict_get(sd->metadata, "name", NULL, AV_DICT_MATCH_CASE); if (tag) -- 2.45.2
From 17da5c4e50cb1f2190291d543ab797219ac525d9 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Sun, 1 Jun 2025 04:59:27 +0200 Subject: [PATCH v2 09/11] fftools/ffprobe: Fix indentation Forgotten after d76b0c4a3530005ce59ec1dcaefcb8dd03c4e0ce. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- fftools/ffprobe.c | 184 +++++++++++++++++++++++----------------------- 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 5cf5839202..91976fb8ec 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -981,98 +981,98 @@ static void print_pkt_side_data(AVTextFormatContext *tfc, const AVPacketSideData *sd, SectionID id_data) { - const char *name = av_packet_side_data_name(sd->type); - - avtext_print_section_header(tfc, sd, id_data); - print_str("side_data_type", name ? name : "unknown"); - if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9*4) { - print_displaymatrix(tfc, (const int32_t*)sd->data); - } else if (sd->type == AV_PKT_DATA_STEREO3D) { - const AVStereo3D *stereo = (AVStereo3D *)sd->data; - print_str("type", av_stereo3d_type_name(stereo->type)); - print_int("inverted", !!(stereo->flags & AV_STEREO3D_FLAG_INVERT)); - print_str("view", av_stereo3d_view_name(stereo->view)); - print_str("primary_eye", av_stereo3d_primary_eye_name(stereo->primary_eye)); - print_int("baseline", stereo->baseline); - print_q("horizontal_disparity_adjustment", stereo->horizontal_disparity_adjustment, '/'); - print_q("horizontal_field_of_view", stereo->horizontal_field_of_view, '/'); - } else if (sd->type == AV_PKT_DATA_SPHERICAL) { - const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data; - print_str("projection", av_spherical_projection_name(spherical->projection)); - if (spherical->projection == AV_SPHERICAL_CUBEMAP) { - print_int("padding", spherical->padding); - } else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) { - size_t l, t, r, b; - av_spherical_tile_bounds(spherical, par->width, par->height, - &l, &t, &r, &b); - print_int("bound_left", l); - print_int("bound_top", t); - print_int("bound_right", r); - print_int("bound_bottom", b); - } - - print_int("yaw", (double) spherical->yaw / (1 << 16)); - print_int("pitch", (double) spherical->pitch / (1 << 16)); - print_int("roll", (double) spherical->roll / (1 << 16)); - } else if (sd->type == AV_PKT_DATA_SKIP_SAMPLES && sd->size == 10) { - print_int("skip_samples", AV_RL32(sd->data)); - print_int("discard_padding", AV_RL32(sd->data + 4)); - print_int("skip_reason", AV_RL8(sd->data + 8)); - print_int("discard_reason", AV_RL8(sd->data + 9)); - } else if (sd->type == AV_PKT_DATA_MASTERING_DISPLAY_METADATA) { - print_mastering_display_metadata(tfc, (AVMasteringDisplayMetadata *)sd->data); - } else if (sd->type == AV_PKT_DATA_CONTENT_LIGHT_LEVEL) { - print_context_light_level(tfc, (AVContentLightMetadata *)sd->data); - } else if (sd->type == AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT) { - print_ambient_viewing_environment( - tfc, (const AVAmbientViewingEnvironment *)sd->data); - } else if (sd->type == AV_PKT_DATA_DYNAMIC_HDR10_PLUS) { - AVDynamicHDRPlus *metadata = (AVDynamicHDRPlus *)sd->data; - print_dynamic_hdr10_plus(tfc, metadata); - } else if (sd->type == AV_PKT_DATA_DOVI_CONF) { - AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *)sd->data; - const char *comp = "unknown"; - print_int("dv_version_major", dovi->dv_version_major); - print_int("dv_version_minor", dovi->dv_version_minor); - print_int("dv_profile", dovi->dv_profile); - print_int("dv_level", dovi->dv_level); - print_int("rpu_present_flag", dovi->rpu_present_flag); - print_int("el_present_flag", dovi->el_present_flag); - print_int("bl_present_flag", dovi->bl_present_flag); - print_int("dv_bl_signal_compatibility_id", dovi->dv_bl_signal_compatibility_id); - switch (dovi->dv_md_compression) - { - case AV_DOVI_COMPRESSION_NONE: comp = "none"; break; - case AV_DOVI_COMPRESSION_LIMITED: comp = "limited"; break; - case AV_DOVI_COMPRESSION_RESERVED: comp = "reserved"; break; - case AV_DOVI_COMPRESSION_EXTENDED: comp = "extended"; break; - } - print_str("dv_md_compression", comp); - } else if (sd->type == AV_PKT_DATA_AUDIO_SERVICE_TYPE) { - enum AVAudioServiceType *t = (enum AVAudioServiceType *)sd->data; - print_int("service_type", *t); - } else if (sd->type == AV_PKT_DATA_MPEGTS_STREAM_ID) { - print_int("id", *sd->data); - } else if (sd->type == AV_PKT_DATA_CPB_PROPERTIES) { - const AVCPBProperties *prop = (AVCPBProperties *)sd->data; - print_int("max_bitrate", prop->max_bitrate); - print_int("min_bitrate", prop->min_bitrate); - print_int("avg_bitrate", prop->avg_bitrate); - print_int("buffer_size", prop->buffer_size); - print_int("vbv_delay", prop->vbv_delay); - } else if (sd->type == AV_PKT_DATA_WEBVTT_IDENTIFIER || - sd->type == AV_PKT_DATA_WEBVTT_SETTINGS) { - if (do_show_data) - avtext_print_data(tfc, "data", sd->data, sd->size); - avtext_print_data_hash(tfc, "data_hash", sd->data, sd->size); - } else if (sd->type == AV_PKT_DATA_FRAME_CROPPING && sd->size >= sizeof(uint32_t) * 4) { - print_int("crop_top", AV_RL32(sd->data)); - print_int("crop_bottom", AV_RL32(sd->data + 4)); - print_int("crop_left", AV_RL32(sd->data + 8)); - print_int("crop_right", AV_RL32(sd->data + 12)); - } else if (sd->type == AV_PKT_DATA_AFD && sd->size > 0) { - print_int("active_format", *sd->data); - } + const char *name = av_packet_side_data_name(sd->type); + + avtext_print_section_header(tfc, sd, id_data); + print_str("side_data_type", name ? name : "unknown"); + if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9*4) { + print_displaymatrix(tfc, (const int32_t*)sd->data); + } else if (sd->type == AV_PKT_DATA_STEREO3D) { + const AVStereo3D *stereo = (AVStereo3D *)sd->data; + print_str("type", av_stereo3d_type_name(stereo->type)); + print_int("inverted", !!(stereo->flags & AV_STEREO3D_FLAG_INVERT)); + print_str("view", av_stereo3d_view_name(stereo->view)); + print_str("primary_eye", av_stereo3d_primary_eye_name(stereo->primary_eye)); + print_int("baseline", stereo->baseline); + print_q("horizontal_disparity_adjustment", stereo->horizontal_disparity_adjustment, '/'); + print_q("horizontal_field_of_view", stereo->horizontal_field_of_view, '/'); + } else if (sd->type == AV_PKT_DATA_SPHERICAL) { + const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data; + print_str("projection", av_spherical_projection_name(spherical->projection)); + if (spherical->projection == AV_SPHERICAL_CUBEMAP) { + print_int("padding", spherical->padding); + } else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) { + size_t l, t, r, b; + av_spherical_tile_bounds(spherical, par->width, par->height, + &l, &t, &r, &b); + print_int("bound_left", l); + print_int("bound_top", t); + print_int("bound_right", r); + print_int("bound_bottom", b); + } + + print_int("yaw", (double) spherical->yaw / (1 << 16)); + print_int("pitch", (double) spherical->pitch / (1 << 16)); + print_int("roll", (double) spherical->roll / (1 << 16)); + } else if (sd->type == AV_PKT_DATA_SKIP_SAMPLES && sd->size == 10) { + print_int("skip_samples", AV_RL32(sd->data)); + print_int("discard_padding", AV_RL32(sd->data + 4)); + print_int("skip_reason", AV_RL8(sd->data + 8)); + print_int("discard_reason", AV_RL8(sd->data + 9)); + } else if (sd->type == AV_PKT_DATA_MASTERING_DISPLAY_METADATA) { + print_mastering_display_metadata(tfc, (AVMasteringDisplayMetadata *)sd->data); + } else if (sd->type == AV_PKT_DATA_CONTENT_LIGHT_LEVEL) { + print_context_light_level(tfc, (AVContentLightMetadata *)sd->data); + } else if (sd->type == AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT) { + print_ambient_viewing_environment( + tfc, (const AVAmbientViewingEnvironment *)sd->data); + } else if (sd->type == AV_PKT_DATA_DYNAMIC_HDR10_PLUS) { + AVDynamicHDRPlus *metadata = (AVDynamicHDRPlus *)sd->data; + print_dynamic_hdr10_plus(tfc, metadata); + } else if (sd->type == AV_PKT_DATA_DOVI_CONF) { + AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *)sd->data; + const char *comp = "unknown"; + print_int("dv_version_major", dovi->dv_version_major); + print_int("dv_version_minor", dovi->dv_version_minor); + print_int("dv_profile", dovi->dv_profile); + print_int("dv_level", dovi->dv_level); + print_int("rpu_present_flag", dovi->rpu_present_flag); + print_int("el_present_flag", dovi->el_present_flag); + print_int("bl_present_flag", dovi->bl_present_flag); + print_int("dv_bl_signal_compatibility_id", dovi->dv_bl_signal_compatibility_id); + switch (dovi->dv_md_compression) + { + case AV_DOVI_COMPRESSION_NONE: comp = "none"; break; + case AV_DOVI_COMPRESSION_LIMITED: comp = "limited"; break; + case AV_DOVI_COMPRESSION_RESERVED: comp = "reserved"; break; + case AV_DOVI_COMPRESSION_EXTENDED: comp = "extended"; break; + } + print_str("dv_md_compression", comp); + } else if (sd->type == AV_PKT_DATA_AUDIO_SERVICE_TYPE) { + enum AVAudioServiceType *t = (enum AVAudioServiceType *)sd->data; + print_int("service_type", *t); + } else if (sd->type == AV_PKT_DATA_MPEGTS_STREAM_ID) { + print_int("id", *sd->data); + } else if (sd->type == AV_PKT_DATA_CPB_PROPERTIES) { + const AVCPBProperties *prop = (AVCPBProperties *)sd->data; + print_int("max_bitrate", prop->max_bitrate); + print_int("min_bitrate", prop->min_bitrate); + print_int("avg_bitrate", prop->avg_bitrate); + print_int("buffer_size", prop->buffer_size); + print_int("vbv_delay", prop->vbv_delay); + } else if (sd->type == AV_PKT_DATA_WEBVTT_IDENTIFIER || + sd->type == AV_PKT_DATA_WEBVTT_SETTINGS) { + if (do_show_data) + avtext_print_data(tfc, "data", sd->data, sd->size); + avtext_print_data_hash(tfc, "data_hash", sd->data, sd->size); + } else if (sd->type == AV_PKT_DATA_FRAME_CROPPING && sd->size >= sizeof(uint32_t) * 4) { + print_int("crop_top", AV_RL32(sd->data)); + print_int("crop_bottom", AV_RL32(sd->data + 4)); + print_int("crop_left", AV_RL32(sd->data + 8)); + print_int("crop_right", AV_RL32(sd->data + 12)); + } else if (sd->type == AV_PKT_DATA_AFD && sd->size > 0) { + print_int("active_format", *sd->data); + } } static void print_private_data(AVTextFormatContext *tfc, void *priv_data) -- 2.45.2
From eb86578fa6a561b973f577b652e9fb7b2c58d8ba Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Sun, 1 Jun 2025 05:09:32 +0200 Subject: [PATCH v2 10/11] fftools/textformat/avtextformat: Move avtext_print_integers to ffprobe.c This is its only user and because this function is so specialised it is very likely to stay that way. So move it back to ffprobe.c (where it already was before d7a3f68feae0b1c3718f9d2671c6d41c60a40680). Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- fftools/ffprobe.c | 27 ++++++++++++++++++++++++++- fftools/textformat/avtextformat.c | 30 ------------------------------ fftools/textformat/avtextformat.h | 3 --- 3 files changed, 26 insertions(+), 34 deletions(-) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 91976fb8ec..61c2260ea4 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -446,6 +446,31 @@ static void log_callback(void *ptr, int level, const char *fmt, va_list vl) #define print_duration_ts(k, v) avtext_print_ts(tfc, k, v, 1) #define print_val(k, v, u) avtext_print_unit_int(tfc, k, v, u) +static void print_integers(AVTextFormatContext *tfc, const char *key, + const void *data, int size, const char *format, + int columns, int bytes, int offset_add) +{ + AVBPrint bp; + unsigned offset = 0; + + av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC); + av_bprint_chars(&bp, '\n', 1); + while (size) { + av_bprintf(&bp, "%08x: ", offset); + int l = FFMIN(size, columns); + for (int i = 0; i < l; i++) { + if (bytes == 1) av_bprintf(&bp, format, *(const uint8_t*)data); + else if (bytes == 2) av_bprintf(&bp, format, AV_RN16(data)); + else if (bytes == 4) av_bprintf(&bp, format, AV_RN32(data)); + data = (const char*)data + bytes; + size--; + } + av_bprint_chars(&bp, '\n', 1); + offset += offset_add; + } + avtext_print_string(tfc, key, bp.str, 0); +} + #define REALLOCZ_ARRAY_STREAM(ptr, cur_n, new_n) \ { \ ret = av_reallocp_array(&(ptr), (new_n), sizeof(*(ptr))); \ @@ -477,7 +502,7 @@ static void print_displaymatrix(AVTextFormatContext *tfc, const int32_t matrix[9 double rotation = av_display_rotation_get(matrix); if (isnan(rotation)) rotation = 0; - avtext_print_integers(tfc, "displaymatrix", (void*)matrix, 9, " %11d", 3, 4, 1); + print_integers(tfc, "displaymatrix", matrix, 9, " %11d", 3, 4, 1); print_int("rotation", rotation); } diff --git a/fftools/textformat/avtextformat.c b/fftools/textformat/avtextformat.c index 30a017d1a1..532d0f5bfc 100644 --- a/fftools/textformat/avtextformat.c +++ b/fftools/textformat/avtextformat.c @@ -562,36 +562,6 @@ void avtext_print_data_hash(AVTextFormatContext *tctx, const char *key, avtext_print_string(tctx, key, buf, 0); } -void avtext_print_integers(AVTextFormatContext *tctx, const char *key, - uint8_t *data, int size, const char *format, - int columns, int bytes, int offset_add) -{ - AVBPrint bp; - unsigned offset = 0; - int l, i; - - if (!key || !data || !format || columns <= 0 || bytes <= 0) - return; - - av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED); - av_bprintf(&bp, "\n"); - while (size) { - av_bprintf(&bp, "%08x: ", offset); - l = FFMIN(size, columns); - for (i = 0; i < l; i++) { - if (bytes == 1) av_bprintf(&bp, format, *data); - else if (bytes == 2) av_bprintf(&bp, format, AV_RN16(data)); - else if (bytes == 4) av_bprintf(&bp, format, AV_RN32(data)); - data += bytes; - size--; - } - av_bprintf(&bp, "\n"); - offset += offset_add; - } - avtext_print_string(tctx, key, bp.str, 0); - av_bprint_finalize(&bp, NULL); -} - static const char *writercontext_get_writer_name(void *p) { AVTextWriterContext *wctx = p; diff --git a/fftools/textformat/avtextformat.h b/fftools/textformat/avtextformat.h index bd8c5d742f..4354181df4 100644 --- a/fftools/textformat/avtextformat.h +++ b/fftools/textformat/avtextformat.h @@ -190,9 +190,6 @@ void avtext_print_data(AVTextFormatContext *tctx, const char *key, const uint8_t void avtext_print_data_hash(AVTextFormatContext *tctx, const char *key, const uint8_t *data, int size); -void avtext_print_integers(AVTextFormatContext *tctx, const char *key, uint8_t *data, int size, - const char *format, int columns, int bytes, int offset_add); - const AVTextFormatter *avtext_get_formatter_by_name(const char *name); extern const AVTextFormatter avtextformatter_default; -- 2.45.2
From 48d07ef12388878832dcc4ecf91fc0508ff38216 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinha...@outlook.com> Date: Sun, 1 Jun 2025 05:14:23 +0200 Subject: [PATCH v2 11/11] fftools/graph/graphprint: Remove redundant avio_flush() The AVIOContext will be automatically flushed upon closure. Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- fftools/graph/graphprint.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fftools/graph/graphprint.c b/fftools/graph/graphprint.c index 71dd421245..6152866313 100644 --- a/fftools/graph/graphprint.c +++ b/fftools/graph/graphprint.c @@ -1067,7 +1067,6 @@ static int print_filtergraphs_priv(FilterGraph **graphs, int nb_graphs, InputFil } avio_write(avio, (const unsigned char *)target_buf.str, FFMIN(target_buf.len, target_buf.size - 1)); - avio_flush(avio); if ((ret = avio_closep(&avio)) < 0) av_log(NULL, AV_LOG_ERROR, "Error closing graph output file, loss of information possible: %s\n", av_err2str(ret)); -- 2.45.2
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".