From: softworkz <ffmpegagent@gmail.com> To: ffmpeg-devel@ffmpeg.org Cc: softworkz <softworkz@hotmail.com> Subject: [FFmpeg-devel] [PATCH 3/8] ffprobe/avtextformat: Generalize ffprobe specifics Date: Thu, 27 Feb 2025 14:01:35 +0000 Message-ID: <624927c38bf2e73b9b9c0e7a03c5ae530c16e5ff.1740664900.git.ffmpegagent@gmail.com> (raw) In-Reply-To: <pull.56.ffstaging.FFmpeg.1740664900.ffmpegagent@gmail.com> From: softworkz <softworkz@hotmail.com> Signed-off-by: softworkz <softworkz@hotmail.com> --- fftools/ffprobe.c | 34 +++++++++++++++-------------- libavutil/avtextformat.h | 13 +++++------ libavutil/textformat/avtextformat.c | 30 ++++++++++--------------- 3 files changed, 35 insertions(+), 42 deletions(-) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 837e21c0e2..5560f6b87e 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -272,7 +272,7 @@ static struct AVTextFormatSection sections[] = { [SECTION_ID_LIBRARY_VERSIONS] = { SECTION_ID_LIBRARY_VERSIONS, "library_versions", SECTION_FLAG_IS_ARRAY, { SECTION_ID_LIBRARY_VERSION, -1 } }, [SECTION_ID_LIBRARY_VERSION] = { SECTION_ID_LIBRARY_VERSION, "library_version", 0, { -1 } }, [SECTION_ID_PACKETS] = { SECTION_ID_PACKETS, "packets", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET, -1} }, - [SECTION_ID_PACKETS_AND_FRAMES] = { SECTION_ID_PACKETS_AND_FRAMES, "packets_and_frames", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET, -1} }, + [SECTION_ID_PACKETS_AND_FRAMES] = { SECTION_ID_PACKETS_AND_FRAMES, "packets_and_frames", SECTION_FLAG_IS_ARRAY | SECTION_FLAG_NUMBERING_BY_TYPE, { SECTION_ID_PACKET, -1} }, [SECTION_ID_PACKET] = { SECTION_ID_PACKET, "packet", 0, { SECTION_ID_PACKET_TAGS, SECTION_ID_PACKET_SIDE_DATA_LIST, -1 } }, [SECTION_ID_PACKET_TAGS] = { SECTION_ID_PACKET_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "packet_tags" }, [SECTION_ID_PACKET_SIDE_DATA_LIST] ={ SECTION_ID_PACKET_SIDE_DATA_LIST, "side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "packet_side_data_list" }, @@ -547,7 +547,7 @@ static const AVTextFormatter default_formatter = { .print_section_footer = default_print_section_footer, .print_integer = default_print_int, .print_string = default_print_str, - .flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS, + .flags = AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS, .priv_class = &default_class, }; @@ -747,7 +747,7 @@ static const AVTextFormatter compact_formatter = { .print_section_footer = compact_print_section_footer, .print_integer = compact_print_int, .print_string = compact_print_str, - .flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS, + .flags = AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS, .priv_class = &compact_class, }; @@ -778,7 +778,7 @@ static const AVTextFormatter csv_formatter = { .print_section_footer = compact_print_section_footer, .print_integer = compact_print_int, .print_string = compact_print_str, - .flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS, + .flags = AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS, .priv_class = &csv_class, }; @@ -870,8 +870,9 @@ static void flat_print_section_header(AVTextFormatContext *wctx, const void *dat av_bprintf(buf, "%s%s", wctx->section[wctx->level]->name, flat->sep_str); if (parent_section->flags & SECTION_FLAG_IS_ARRAY) { - int n = parent_section->id == SECTION_ID_PACKETS_AND_FRAMES ? - wctx->nb_section_packet_frame : wctx->nb_item[wctx->level-1]; + int n = parent_section->flags & SECTION_FLAG_NUMBERING_BY_TYPE ? + wctx->nb_item_type[wctx->level-1][section->id] : + wctx->nb_item[wctx->level-1]; av_bprintf(buf, "%d%s", n, flat->sep_str); } } @@ -902,7 +903,7 @@ static const AVTextFormatter flat_formatter = { .print_section_header = flat_print_section_header, .print_integer = flat_print_int, .print_string = flat_print_str, - .flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS|WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER, + .flags = AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS|AV_TEXTFORMAT_FLAG_SUPPORTS_MIXED_ARRAY_CONTENT, .priv_class = &flat_class, }; @@ -974,8 +975,9 @@ static void ini_print_section_header(AVTextFormatContext *wctx, const void *data av_bprintf(buf, "%s%s", buf->str[0] ? "." : "", wctx->section[wctx->level]->name); if (parent_section->flags & SECTION_FLAG_IS_ARRAY) { - int n = parent_section->id == SECTION_ID_PACKETS_AND_FRAMES ? - wctx->nb_section_packet_frame : wctx->nb_item[wctx->level-1]; + int n = parent_section->flags & SECTION_FLAG_NUMBERING_BY_TYPE ? + wctx->nb_item_type[wctx->level-1][section->id] : + wctx->nb_item[wctx->level-1]; av_bprintf(buf, ".%d", n); } } @@ -1006,7 +1008,7 @@ static const AVTextFormatter ini_formatter = { .print_section_header = ini_print_section_header, .print_integer = ini_print_int, .print_string = ini_print_str, - .flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS|WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER, + .flags = AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS|AV_TEXTFORMAT_FLAG_SUPPORTS_MIXED_ARRAY_CONTENT, .priv_class = &ini_class, }; @@ -1090,7 +1092,7 @@ static void json_print_section_header(AVTextFormatContext *wctx, const void *dat writer_printf(wctx, "{%s", json->item_start_end); /* this is required so the parser can distinguish between packets and frames */ - if (parent_section && parent_section->id == SECTION_ID_PACKETS_AND_FRAMES) { + if (parent_section && parent_section->flags & SECTION_FLAG_NUMBERING_BY_TYPE) { if (!json->compact) JSON_INDENT(); writer_printf(wctx, "\"type\": \"%s\"", section->name); @@ -1141,7 +1143,7 @@ static void json_print_str(AVTextFormatContext *wctx, const char *key, const cha const struct AVTextFormatSection *parent_section = wctx->level ? wctx->section[wctx->level-1] : NULL; - if (wctx->nb_item[wctx->level] || (parent_section && parent_section->id == SECTION_ID_PACKETS_AND_FRAMES)) + if (wctx->nb_item[wctx->level] || (parent_section && parent_section->flags & SECTION_FLAG_NUMBERING_BY_TYPE)) writer_put_str(wctx, json->item_sep); if (!json->compact) JSON_INDENT(); @@ -1155,7 +1157,7 @@ static void json_print_int(AVTextFormatContext *wctx, const char *key, int64_t v wctx->section[wctx->level-1] : NULL; AVBPrint buf; - if (wctx->nb_item[wctx->level] || (parent_section && parent_section->id == SECTION_ID_PACKETS_AND_FRAMES)) + if (wctx->nb_item[wctx->level] || (parent_section && parent_section->flags & SECTION_FLAG_NUMBERING_BY_TYPE)) writer_put_str(wctx, json->item_sep); if (!json->compact) JSON_INDENT(); @@ -1173,7 +1175,7 @@ static const AVTextFormatter json_formatter = { .print_section_footer = json_print_section_footer, .print_integer = json_print_int, .print_string = json_print_str, - .flags = WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER, + .flags = AV_TEXTFORMAT_FLAG_SUPPORTS_MIXED_ARRAY_CONTENT, .priv_class = &json_class, }; @@ -1345,7 +1347,7 @@ static AVTextFormatter xml_formatter = { .print_section_footer = xml_print_section_footer, .print_integer = xml_print_int, .print_string = xml_print_str, - .flags = WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER, + .flags = AV_TEXTFORMAT_FLAG_SUPPORTS_MIXED_ARRAY_CONTENT, .priv_class = &xml_class, }; @@ -3421,7 +3423,7 @@ static int probe_file(AVTextFormatContext *wctx, const char *filename, if (do_read_frames || do_read_packets) { if (do_show_frames && do_show_packets && - wctx->writer->flags & WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER) + wctx->writer->flags & AV_TEXTFORMAT_FLAG_SUPPORTS_MIXED_ARRAY_CONTENT) section_id = SECTION_ID_PACKETS_AND_FRAMES; else if (do_show_packets && !do_show_frames) section_id = SECTION_ID_PACKETS; diff --git a/libavutil/avtextformat.h b/libavutil/avtextformat.h index e1aa227aff..a7f8055783 100644 --- a/libavutil/avtextformat.h +++ b/libavutil/avtextformat.h @@ -42,6 +42,7 @@ struct AVTextFormatSection { #define SECTION_FLAG_HAS_VARIABLE_FIELDS 4 ///< the section may contain a variable number of fields with variable keys. /// For these sections the element_name field is mandatory. #define SECTION_FLAG_HAS_TYPE 8 ///< the section contains a type to distinguish multiple nested elements +#define SECTION_FLAG_NUMBERING_BY_TYPE 16 ///< the items in this array section should be numbered individually by type int flags; const int children_ids[SECTION_MAX_NB_CHILDREN+1]; ///< list of children section IDS, terminated by -1 @@ -54,8 +55,8 @@ struct AVTextFormatSection { typedef struct AVTextFormatContext AVTextFormatContext; -#define WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS 1 -#define WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER 2 +#define AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS 1 +#define AV_TEXTFORMAT_FLAG_SUPPORTS_MIXED_ARRAY_CONTENT 2 typedef enum { WRITER_STRING_VALIDATION_FAIL, @@ -80,7 +81,8 @@ typedef struct AVTextFormatter { int flags; ///< a combination or WRITER_FLAG_* } AVTextFormatter; -#define SECTION_MAX_NB_LEVELS 12 +#define SECTION_MAX_NB_LEVELS 12 +#define SECTION_MAX_NB_SECTIONS 100 struct AVTextFormatContext { const AVClass *class; ///< class of the writer @@ -101,16 +103,13 @@ struct AVTextFormatContext { /** number of the item printed in the given section, starting from 0 */ unsigned int nb_item[SECTION_MAX_NB_LEVELS]; + unsigned int nb_item_type[SECTION_MAX_NB_LEVELS][SECTION_MAX_NB_SECTIONS]; /** section per each level */ const struct AVTextFormatSection *section[SECTION_MAX_NB_LEVELS]; AVBPrint section_pbuf[SECTION_MAX_NB_LEVELS]; ///< generic print buffer dedicated to each section, /// used by various writers - unsigned int nb_section_packet; ///< number of the packet section in case we are in "packets_and_frames" section - unsigned int nb_section_frame; ///< number of the frame section in case we are in "packets_and_frames" section - unsigned int nb_section_packet_frame; ///< nb_section_packet or nb_section_frame according if is_packets_and_frames - int show_optional_fields; int show_value_unit; int use_value_prefix; diff --git a/libavutil/textformat/avtextformat.c b/libavutil/textformat/avtextformat.c index 2b67acae65..a2d87e8d42 100644 --- a/libavutil/textformat/avtextformat.c +++ b/libavutil/textformat/avtextformat.c @@ -189,6 +189,11 @@ int avtext_context_open(AVTextFormatContext **pwctx, const AVTextFormatter *writ wctx->use_byte_value_binary_prefix = use_byte_value_binary_prefix; wctx->use_value_sexagesimal_format = use_value_sexagesimal_format; wctx->show_optional_fields = show_optional_fields; + + if (nb_sections > SECTION_MAX_NB_SECTIONS) { + av_log(wctx, AV_LOG_ERROR, "The number of section definitions (%d) is larger than the maximum allowed (%d)\n", nb_sections, SECTION_MAX_NB_SECTIONS); + goto fail; + } wctx->class = &textcontext_class; wctx->writer = writer; @@ -293,8 +298,6 @@ fail: } /* Temporary definitions during refactoring */ -#define SECTION_ID_PACKETS_AND_FRAMES 24 -#define SECTION_ID_PACKET 21 static const char unit_second_str[] = "s" ; static const char unit_hertz_str[] = "Hz" ; static const char unit_byte_str[] = "byte" ; @@ -305,23 +308,13 @@ void avtext_print_section_header(AVTextFormatContext *wctx, const void *data, int section_id) { - int parent_section_id; wctx->level++; av_assert0(wctx->level < SECTION_MAX_NB_LEVELS); - parent_section_id = wctx->level ? - (wctx->section[wctx->level-1])->id : SECTION_ID_NONE; wctx->nb_item[wctx->level] = 0; + memset(wctx->nb_item_type[wctx->level], 0, sizeof(wctx->nb_item_type[wctx->level])); wctx->section[wctx->level] = &wctx->sections[section_id]; - if (section_id == SECTION_ID_PACKETS_AND_FRAMES) { - wctx->nb_section_packet = wctx->nb_section_frame = - wctx->nb_section_packet_frame = 0; - } else if (parent_section_id == SECTION_ID_PACKETS_AND_FRAMES) { - wctx->nb_section_packet_frame = section_id == SECTION_ID_PACKET ? - wctx->nb_section_packet : wctx->nb_section_frame; - } - if (wctx->writer->print_section_header) wctx->writer->print_section_header(wctx, data); } @@ -332,12 +325,11 @@ void avtext_print_section_footer(AVTextFormatContext *wctx) int parent_section_id = wctx->level ? wctx->section[wctx->level-1]->id : SECTION_ID_NONE; - if (parent_section_id != SECTION_ID_NONE) - wctx->nb_item[wctx->level-1]++; - if (parent_section_id == SECTION_ID_PACKETS_AND_FRAMES) { - if (section_id == SECTION_ID_PACKET) wctx->nb_section_packet++; - else wctx->nb_section_frame++; + if (parent_section_id != SECTION_ID_NONE) { + wctx->nb_item[wctx->level - 1]++; + wctx->nb_item_type[wctx->level - 1][section_id]++; } + if (wctx->writer->print_section_footer) wctx->writer->print_section_footer(wctx); wctx->level--; @@ -486,7 +478,7 @@ int avtext_print_string(AVTextFormatContext *wctx, const char *key, const char * if (wctx->show_optional_fields == SHOW_OPTIONAL_FIELDS_NEVER || (wctx->show_optional_fields == SHOW_OPTIONAL_FIELDS_AUTO && (flags & PRINT_STRING_OPT) - && !(wctx->writer->flags & WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS))) + && !(wctx->writer->flags & AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS))) return 0; if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) { -- ffmpeg-codebot _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2025-02-27 14:02 UTC|newest] Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top 2025-02-27 14:01 [FFmpeg-devel] [PATCH 0/8] [RFC] avtextformat: Transform text writing into an independent API ffmpegagent 2025-02-27 14:01 ` [FFmpeg-devel] [PATCH 1/8] ffprobe/avtextformat: Rename and move writer structs softworkz 2025-02-27 14:01 ` [FFmpeg-devel] [PATCH 2/8] ffprobe/avtextformat: Rename and move writer functions and options softworkz 2025-02-27 14:01 ` softworkz [this message] 2025-02-27 14:01 ` [FFmpeg-devel] [PATCH 4/8] ffprobe/avtextformat: Rename flags and enums softworkz 2025-02-27 14:01 ` [FFmpeg-devel] [PATCH 5/8] ffprobe/avtextformat: Move flags softworkz 2025-02-27 14:01 ` [FFmpeg-devel] [PATCH 6/8] ffprobe/avtextformat: Rename writer to formatter softworkz 2025-02-27 14:01 ` [FFmpeg-devel] [PATCH 7/8] ffprobe/avtextformat: Move formatters to avutil softworkz 2025-02-27 14:01 ` [FFmpeg-devel] [PATCH 8/8] ffprobe/avtextformat: Split out text writers as independent classes softworkz
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=624927c38bf2e73b9b9c0e7a03c5ae530c16e5ff.1740664900.git.ffmpegagent@gmail.com \ --to=ffmpegagent@gmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ --cc=softworkz@hotmail.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git