[FFmpeg-devel] [PATCH 3/8] ffprobe/avtextformat: Generalize ffprobe specifics
softworkz
ffmpegagent at gmail.com
Thu Feb 27 16:01:35 EET 2025
From: softworkz <softworkz at hotmail.com>
Signed-off-by: softworkz <softworkz at 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
More information about the ffmpeg-devel
mailing list