From: softworkz <ffmpegagent@gmail.com> To: ffmpeg-devel@ffmpeg.org Cc: softworkz <softworkz@hotmail.com> Subject: [FFmpeg-devel] [PATCH 1/8] ffprobe/avtextformat: Rename and move writer structs Date: Thu, 27 Feb 2025 14:01:33 +0000 Message-ID: <28b1c6d4cf7e7d577ffce832fb2632ea0fd0aa7a.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 | 356 +++++++++++++++------------------------ libavutil/Makefile | 1 + libavutil/avtextformat.h | 120 +++++++++++++ 3 files changed, 257 insertions(+), 220 deletions(-) create mode 100644 libavutil/avtextformat.h diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 7341731d2f..76848c3cf4 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -36,6 +36,7 @@ #include "libavutil/ambient_viewing_environment.h" #include "libavutil/avassert.h" #include "libavutil/avstring.h" +#include "libavutil/avtextformat.h" #include "libavutil/bprint.h" #include "libavutil/channel_layout.h" #include "libavutil/display.h" @@ -156,8 +157,6 @@ static int find_stream_info = 1; /* section structure definition */ -#define SECTION_MAX_NB_CHILDREN 11 - typedef enum { SECTION_ID_NONE = -1, SECTION_ID_CHAPTER, @@ -228,25 +227,6 @@ typedef enum { SECTION_ID_SUBTITLE, } SectionID; -struct section { - int id; ///< unique id identifying a section - const char *name; - -#define SECTION_FLAG_IS_WRAPPER 1 ///< the section only contains other sections, but has no data at its own level -#define SECTION_FLAG_IS_ARRAY 2 ///< the section contains an array of elements of the same type -#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 - - int flags; - const SectionID 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; -}; - static const char *get_packet_side_data_type(const void *data) { const AVPacketSideData *sd = (const AVPacketSideData *)data; @@ -270,7 +250,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 section sections[] = { +static struct AVTextFormatSection sections[] = { [SECTION_ID_CHAPTERS] = { SECTION_ID_CHAPTERS, "chapters", 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", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "chapter_tags" }, @@ -501,77 +481,13 @@ static char *value_string(char *buf, int buf_size, struct unit_value uv) /* WRITERS API */ -typedef struct WriterContext WriterContext; - -#define WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS 1 -#define WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER 2 - -typedef enum { - WRITER_STRING_VALIDATION_FAIL, - WRITER_STRING_VALIDATION_REPLACE, - WRITER_STRING_VALIDATION_IGNORE, - WRITER_STRING_VALIDATION_NB -} StringValidation; - -typedef struct Writer { - const AVClass *priv_class; ///< private class of the writer, if any - int priv_size; ///< private size for the writer context - const char *name; - - int (*init) (WriterContext *wctx); - void (*uninit)(WriterContext *wctx); - - void (*print_section_header)(WriterContext *wctx, const void *data); - void (*print_section_footer)(WriterContext *wctx); - void (*print_integer) (WriterContext *wctx, const char *, int64_t); - void (*print_rational) (WriterContext *wctx, AVRational *q, char *sep); - void (*print_string) (WriterContext *wctx, const char *, const char *); - int flags; ///< a combination or WRITER_FLAG_* -} Writer; - -#define SECTION_MAX_NB_LEVELS 12 - -struct WriterContext { - const AVClass *class; ///< class of the writer - const Writer *writer; ///< the Writer of which this is an instance - AVIOContext *avio; ///< the I/O context used to write - - void (* writer_w8)(WriterContext *wctx, int b); - void (* writer_put_str)(WriterContext *wctx, const char *str); - void (* writer_printf)(WriterContext *wctx, const char *fmt, ...); - - char *name; ///< name of this writer instance - void *priv; ///< private data for use by the filter - - const struct section *sections; ///< array containing all sections - int nb_sections; ///< number of sections - - int level; ///< current level, starting from 0 - - /** number of the item printed in the given section, starting from 0 */ - unsigned int nb_item[SECTION_MAX_NB_LEVELS]; - - /** section per each level */ - const struct section *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 string_validation; - char *string_validation_replacement; - unsigned int string_validation_utf8_flags; -}; - static const char *writer_get_name(void *p) { - WriterContext *wctx = p; + AVTextFormatContext *wctx = p; return wctx->writer->name; } -#define OFFSET(x) offsetof(WriterContext, x) +#define OFFSET(x) offsetof(AVTextFormatContext, x) static const AVOption writer_options[] = { { "string_validation", "set string validation mode", @@ -588,21 +504,21 @@ static const AVOption writer_options[] = { static void *writer_child_next(void *obj, void *prev) { - WriterContext *ctx = obj; + AVTextFormatContext *ctx = obj; if (!prev && ctx->writer && ctx->writer->priv_class && ctx->priv) return ctx->priv; return NULL; } static const AVClass writer_class = { - .class_name = "Writer", + .class_name = "AVTextFormatter", .item_name = writer_get_name, .option = writer_options, .version = LIBAVUTIL_VERSION_INT, .child_next = writer_child_next, }; -static int writer_close(WriterContext **wctx) +static int writer_close(AVTextFormatContext **wctx) { int i; int ret = 0; @@ -634,17 +550,17 @@ static void bprint_bytes(AVBPrint *bp, const uint8_t *ubuf, size_t ubuf_size) av_bprintf(bp, "%02X", ubuf[i]); } -static inline void writer_w8_avio(WriterContext *wctx, int b) +static inline void writer_w8_avio(AVTextFormatContext *wctx, int b) { avio_w8(wctx->avio, b); } -static inline void writer_put_str_avio(WriterContext *wctx, const char *str) +static inline void writer_put_str_avio(AVTextFormatContext *wctx, const char *str) { avio_write(wctx->avio, str, strlen(str)); } -static inline void writer_printf_avio(WriterContext *wctx, const char *fmt, ...) +static inline void writer_printf_avio(AVTextFormatContext *wctx, const char *fmt, ...) { va_list ap; @@ -653,17 +569,17 @@ static inline void writer_printf_avio(WriterContext *wctx, const char *fmt, ...) va_end(ap); } -static inline void writer_w8_printf(WriterContext *wctx, int b) +static inline void writer_w8_printf(AVTextFormatContext *wctx, int b) { printf("%c", b); } -static inline void writer_put_str_printf(WriterContext *wctx, const char *str) +static inline void writer_put_str_printf(AVTextFormatContext *wctx, const char *str) { printf("%s", str); } -static inline void writer_printf_printf(WriterContext *wctx, const char *fmt, ...) +static inline void writer_printf_printf(AVTextFormatContext *wctx, const char *fmt, ...) { va_list ap; @@ -672,12 +588,12 @@ static inline void writer_printf_printf(WriterContext *wctx, const char *fmt, .. va_end(ap); } -static int writer_open(WriterContext **wctx, const Writer *writer, const char *args, - const struct section *sections, int nb_sections, const char *output) +static int writer_open(AVTextFormatContext **wctx, const AVTextFormatter *writer, const char *args, + const struct AVTextFormatSection *sections, int nb_sections, const char *output) { int i, ret = 0; - if (!(*wctx = av_mallocz(sizeof(WriterContext)))) { + if (!(*wctx = av_mallocz(sizeof(AVTextFormatContext)))) { ret = AVERROR(ENOMEM); goto fail; } @@ -774,7 +690,7 @@ fail: return ret; } -static inline void writer_print_section_header(WriterContext *wctx, +static inline void writer_print_section_header(AVTextFormatContext *wctx, const void *data, int section_id) { @@ -799,7 +715,7 @@ static inline void writer_print_section_header(WriterContext *wctx, wctx->writer->print_section_header(wctx, data); } -static inline void writer_print_section_footer(WriterContext *wctx) +static inline void writer_print_section_footer(AVTextFormatContext *wctx) { int section_id = wctx->section[wctx->level]->id; int parent_section_id = wctx->level ? @@ -816,10 +732,10 @@ static inline void writer_print_section_footer(WriterContext *wctx) wctx->level--; } -static inline void writer_print_integer(WriterContext *wctx, +static inline void writer_print_integer(AVTextFormatContext *wctx, const char *key, int64_t val) { - const struct section *section = wctx->section[wctx->level]; + const struct AVTextFormatSection *section = wctx->section[wctx->level]; if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) { wctx->writer->print_integer(wctx, key, val); @@ -827,7 +743,7 @@ static inline void writer_print_integer(WriterContext *wctx, } } -static inline int validate_string(WriterContext *wctx, char **dstp, const char *src) +static inline int validate_string(AVTextFormatContext *wctx, char **dstp, const char *src) { const uint8_t *p, *endp; AVBPrint dstbuf; @@ -885,10 +801,10 @@ end: #define PRINT_STRING_OPT 1 #define PRINT_STRING_VALIDATE 2 -static inline int writer_print_string(WriterContext *wctx, +static inline int writer_print_string(AVTextFormatContext *wctx, const char *key, const char *val, int flags) { - const struct section *section = wctx->section[wctx->level]; + const struct AVTextFormatSection *section = wctx->section[wctx->level]; int ret = 0; if (show_optional_fields == SHOW_OPTIONAL_FIELDS_NEVER || @@ -923,7 +839,7 @@ static inline int writer_print_string(WriterContext *wctx, return ret; } -static inline void writer_print_rational(WriterContext *wctx, +static inline void writer_print_rational(AVTextFormatContext *wctx, const char *key, AVRational q, char sep) { AVBPrint buf; @@ -932,7 +848,7 @@ static inline void writer_print_rational(WriterContext *wctx, writer_print_string(wctx, key, buf.str, 0); } -static void writer_print_time(WriterContext *wctx, const char *key, +static void writer_print_time(AVTextFormatContext *wctx, const char *key, int64_t ts, const AVRational *time_base, int is_duration) { char buf[128]; @@ -949,7 +865,7 @@ static void writer_print_time(WriterContext *wctx, const char *key, } } -static void writer_print_ts(WriterContext *wctx, const char *key, int64_t ts, int is_duration) +static void writer_print_ts(AVTextFormatContext *wctx, const char *key, int64_t ts, int is_duration) { if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) { writer_print_string(wctx, key, "N/A", PRINT_STRING_OPT); @@ -958,7 +874,7 @@ static void writer_print_ts(WriterContext *wctx, const char *key, int64_t ts, in } } -static void writer_print_data(WriterContext *wctx, const char *name, +static void writer_print_data(AVTextFormatContext *wctx, const char *name, const uint8_t *data, int size) { AVBPrint bp; @@ -986,7 +902,7 @@ static void writer_print_data(WriterContext *wctx, const char *name, av_bprint_finalize(&bp, NULL); } -static void writer_print_data_hash(WriterContext *wctx, const char *name, +static void writer_print_data_hash(AVTextFormatContext *wctx, const char *name, const uint8_t *data, int size) { char *p, buf[AV_HASH_MAX_SIZE * 2 + 64] = { 0 }; @@ -1001,7 +917,7 @@ static void writer_print_data_hash(WriterContext *wctx, const char *name, writer_print_string(wctx, name, buf, 0); } -static void writer_print_integers(WriterContext *wctx, const char *name, +static void writer_print_integers(AVTextFormatContext *wctx, const char *name, uint8_t *data, int size, const char *format, int columns, int bytes, int offset_add) { @@ -1033,9 +949,9 @@ static void writer_print_integers(WriterContext *wctx, const char *name, #define MAX_REGISTERED_WRITERS_NB 64 -static const Writer *registered_writers[MAX_REGISTERED_WRITERS_NB + 1]; +static const AVTextFormatter *registered_writers[MAX_REGISTERED_WRITERS_NB + 1]; -static int writer_register(const Writer *writer) +static int writer_register(const AVTextFormatter *writer) { static int next_registered_writer_idx = 0; @@ -1046,7 +962,7 @@ static int writer_register(const Writer *writer) return 0; } -static const Writer *writer_get_by_name(const char *name) +static const AVTextFormatter *writer_get_by_name(const char *name) { int i; @@ -1103,12 +1019,12 @@ static inline char *upcase_string(char *dst, size_t dst_size, const char *src) return dst; } -static void default_print_section_header(WriterContext *wctx, const void *data) +static void default_print_section_header(AVTextFormatContext *wctx, const void *data) { DefaultContext *def = wctx->priv; char buf[32]; - const struct section *section = wctx->section[wctx->level]; - const struct section *parent_section = wctx->level ? + const struct AVTextFormatSection *section = wctx->section[wctx->level]; + const struct AVTextFormatSection *parent_section = wctx->level ? wctx->section[wctx->level-1] : NULL; av_bprint_clear(&wctx->section_pbuf[wctx->level]); @@ -1128,10 +1044,10 @@ static void default_print_section_header(WriterContext *wctx, const void *data) writer_printf(wctx, "[%s]\n", upcase_string(buf, sizeof(buf), section->name)); } -static void default_print_section_footer(WriterContext *wctx) +static void default_print_section_footer(AVTextFormatContext *wctx) { DefaultContext *def = wctx->priv; - const struct section *section = wctx->section[wctx->level]; + const struct AVTextFormatSection *section = wctx->section[wctx->level]; char buf[32]; if (def->noprint_wrappers || def->nested_section[wctx->level]) @@ -1141,7 +1057,7 @@ static void default_print_section_footer(WriterContext *wctx) writer_printf(wctx, "[/%s]\n", upcase_string(buf, sizeof(buf), section->name)); } -static void default_print_str(WriterContext *wctx, const char *key, const char *value) +static void default_print_str(AVTextFormatContext *wctx, const char *key, const char *value) { DefaultContext *def = wctx->priv; @@ -1150,7 +1066,7 @@ static void default_print_str(WriterContext *wctx, const char *key, const char * writer_printf(wctx, "%s\n", value); } -static void default_print_int(WriterContext *wctx, const char *key, int64_t value) +static void default_print_int(AVTextFormatContext *wctx, const char *key, int64_t value) { DefaultContext *def = wctx->priv; @@ -1159,7 +1075,7 @@ static void default_print_int(WriterContext *wctx, const char *key, int64_t valu writer_printf(wctx, "%"PRId64"\n", value); } -static const Writer default_writer = { +static const AVTextFormatter default_writer = { .name = "default", .priv_size = sizeof(DefaultContext), .print_section_header = default_print_section_header, @@ -1251,7 +1167,7 @@ static const AVOption compact_options[]= { DEFINE_WRITER_CLASS(compact); -static av_cold int compact_init(WriterContext *wctx) +static av_cold int compact_init(AVTextFormatContext *wctx) { CompactContext *compact = wctx->priv; @@ -1273,11 +1189,11 @@ static av_cold int compact_init(WriterContext *wctx) return 0; } -static void compact_print_section_header(WriterContext *wctx, const void *data) +static void compact_print_section_header(AVTextFormatContext *wctx, const void *data) { CompactContext *compact = wctx->priv; - const struct section *section = wctx->section[wctx->level]; - const struct section *parent_section = wctx->level ? + const struct AVTextFormatSection *section = wctx->section[wctx->level]; + const struct AVTextFormatSection *parent_section = wctx->level ? wctx->section[wctx->level-1] : NULL; compact->terminate_line[wctx->level] = 1; compact->has_nested_elems[wctx->level] = 0; @@ -1325,7 +1241,7 @@ static void compact_print_section_header(WriterContext *wctx, const void *data) } } -static void compact_print_section_footer(WriterContext *wctx) +static void compact_print_section_footer(AVTextFormatContext *wctx) { CompactContext *compact = wctx->priv; @@ -1335,7 +1251,7 @@ static void compact_print_section_footer(WriterContext *wctx) writer_w8(wctx, '\n'); } -static void compact_print_str(WriterContext *wctx, const char *key, const char *value) +static void compact_print_str(AVTextFormatContext *wctx, const char *key, const char *value) { CompactContext *compact = wctx->priv; AVBPrint buf; @@ -1348,7 +1264,7 @@ static void compact_print_str(WriterContext *wctx, const char *key, const char * av_bprint_finalize(&buf, NULL); } -static void compact_print_int(WriterContext *wctx, const char *key, int64_t value) +static void compact_print_int(AVTextFormatContext *wctx, const char *key, int64_t value) { CompactContext *compact = wctx->priv; @@ -1358,7 +1274,7 @@ static void compact_print_int(WriterContext *wctx, const char *key, int64_t valu writer_printf(wctx, "%"PRId64, value); } -static const Writer compact_writer = { +static const AVTextFormatter compact_formatter = { .name = "compact", .priv_size = sizeof(CompactContext), .init = compact_init, @@ -1389,7 +1305,7 @@ static const AVOption csv_options[] = { DEFINE_WRITER_CLASS(csv); -static const Writer csv_writer = { +static const AVTextFormatter csv_formatter = { .name = "csv", .priv_size = sizeof(CompactContext), .init = compact_init, @@ -1423,7 +1339,7 @@ static const AVOption flat_options[]= { DEFINE_WRITER_CLASS(flat); -static av_cold int flat_init(WriterContext *wctx) +static av_cold int flat_init(AVTextFormatContext *wctx) { FlatContext *flat = wctx->priv; @@ -1470,12 +1386,12 @@ static const char *flat_escape_value_str(AVBPrint *dst, const char *src) return dst->str; } -static void flat_print_section_header(WriterContext *wctx, const void *data) +static void flat_print_section_header(AVTextFormatContext *wctx, const void *data) { FlatContext *flat = wctx->priv; AVBPrint *buf = &wctx->section_pbuf[wctx->level]; - const struct section *section = wctx->section[wctx->level]; - const struct section *parent_section = wctx->level ? + const struct AVTextFormatSection *section = wctx->section[wctx->level]; + const struct AVTextFormatSection *parent_section = wctx->level ? wctx->section[wctx->level-1] : NULL; /* build section header */ @@ -1496,12 +1412,12 @@ static void flat_print_section_header(WriterContext *wctx, const void *data) } } -static void flat_print_int(WriterContext *wctx, const char *key, int64_t value) +static void flat_print_int(AVTextFormatContext *wctx, const char *key, int64_t value) { writer_printf(wctx, "%s%s=%"PRId64"\n", wctx->section_pbuf[wctx->level].str, key, value); } -static void flat_print_str(WriterContext *wctx, const char *key, const char *value) +static void flat_print_str(AVTextFormatContext *wctx, const char *key, const char *value) { FlatContext *flat = wctx->priv; AVBPrint buf; @@ -1514,7 +1430,7 @@ static void flat_print_str(WriterContext *wctx, const char *key, const char *val av_bprint_finalize(&buf, NULL); } -static const Writer flat_writer = { +static const AVTextFormatter flat_formatter = { .name = "flat", .priv_size = sizeof(FlatContext), .init = flat_init, @@ -1570,12 +1486,12 @@ static char *ini_escape_str(AVBPrint *dst, const char *src) return dst->str; } -static void ini_print_section_header(WriterContext *wctx, const void *data) +static void ini_print_section_header(AVTextFormatContext *wctx, const void *data) { INIContext *ini = wctx->priv; AVBPrint *buf = &wctx->section_pbuf[wctx->level]; - const struct section *section = wctx->section[wctx->level]; - const struct section *parent_section = wctx->level ? + const struct AVTextFormatSection *section = wctx->section[wctx->level]; + const struct AVTextFormatSection *parent_section = wctx->level ? wctx->section[wctx->level-1] : NULL; av_bprint_clear(buf); @@ -1603,7 +1519,7 @@ static void ini_print_section_header(WriterContext *wctx, const void *data) writer_printf(wctx, "[%s]\n", buf->str); } -static void ini_print_str(WriterContext *wctx, const char *key, const char *value) +static void ini_print_str(AVTextFormatContext *wctx, const char *key, const char *value) { AVBPrint buf; @@ -1614,12 +1530,12 @@ static void ini_print_str(WriterContext *wctx, const char *key, const char *valu av_bprint_finalize(&buf, NULL); } -static void ini_print_int(WriterContext *wctx, const char *key, int64_t value) +static void ini_print_int(AVTextFormatContext *wctx, const char *key, int64_t value) { writer_printf(wctx, "%s=%"PRId64"\n", key, value); } -static const Writer ini_writer = { +static const AVTextFormatter ini_formatter = { .name = "ini", .priv_size = sizeof(INIContext), .print_section_header = ini_print_section_header, @@ -1649,7 +1565,7 @@ static const AVOption json_options[]= { DEFINE_WRITER_CLASS(json); -static av_cold int json_init(WriterContext *wctx) +static av_cold int json_init(AVTextFormatContext *wctx) { JSONContext *json = wctx->priv; @@ -1681,12 +1597,12 @@ static const char *json_escape_str(AVBPrint *dst, const char *src, void *log_ctx #define JSON_INDENT() writer_printf(wctx, "%*c", json->indent_level * 4, ' ') -static void json_print_section_header(WriterContext *wctx, const void *data) +static void json_print_section_header(AVTextFormatContext *wctx, const void *data) { JSONContext *json = wctx->priv; AVBPrint buf; - const struct section *section = wctx->section[wctx->level]; - const struct section *parent_section = wctx->level ? + const struct AVTextFormatSection *section = wctx->section[wctx->level]; + const struct AVTextFormatSection *parent_section = wctx->level ? wctx->section[wctx->level-1] : NULL; if (wctx->level && wctx->nb_item[wctx->level-1]) @@ -1720,10 +1636,10 @@ static void json_print_section_header(WriterContext *wctx, const void *data) } } -static void json_print_section_footer(WriterContext *wctx) +static void json_print_section_footer(AVTextFormatContext *wctx) { JSONContext *json = wctx->priv; - const struct section *section = wctx->section[wctx->level]; + const struct AVTextFormatSection *section = wctx->section[wctx->level]; if (wctx->level == 0) { json->indent_level--; @@ -1742,7 +1658,7 @@ static void json_print_section_footer(WriterContext *wctx) } } -static inline void json_print_item_str(WriterContext *wctx, +static inline void json_print_item_str(AVTextFormatContext *wctx, const char *key, const char *value) { AVBPrint buf; @@ -1754,10 +1670,10 @@ static inline void json_print_item_str(WriterContext *wctx, av_bprint_finalize(&buf, NULL); } -static void json_print_str(WriterContext *wctx, const char *key, const char *value) +static void json_print_str(AVTextFormatContext *wctx, const char *key, const char *value) { JSONContext *json = wctx->priv; - const struct section *parent_section = wctx->level ? + 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)) @@ -1767,10 +1683,10 @@ static void json_print_str(WriterContext *wctx, const char *key, const char *val json_print_item_str(wctx, key, value); } -static void json_print_int(WriterContext *wctx, const char *key, int64_t value) +static void json_print_int(AVTextFormatContext *wctx, const char *key, int64_t value) { JSONContext *json = wctx->priv; - const struct section *parent_section = wctx->level ? + const struct AVTextFormatSection *parent_section = wctx->level ? wctx->section[wctx->level-1] : NULL; AVBPrint buf; @@ -1784,7 +1700,7 @@ static void json_print_int(WriterContext *wctx, const char *key, int64_t value) av_bprint_finalize(&buf, NULL); } -static const Writer json_writer = { +static const AVTextFormatter json_formatter = { .name = "json", .priv_size = sizeof(JSONContext), .init = json_init, @@ -1819,7 +1735,7 @@ static const AVOption xml_options[] = { DEFINE_WRITER_CLASS(xml); -static av_cold int xml_init(WriterContext *wctx) +static av_cold int xml_init(AVTextFormatContext *wctx) { XMLContext *xml = wctx->priv; @@ -1842,11 +1758,11 @@ static av_cold int xml_init(WriterContext *wctx) #define XML_INDENT() writer_printf(wctx, "%*c", xml->indent_level * 4, ' ') -static void xml_print_section_header(WriterContext *wctx, const void *data) +static void xml_print_section_header(AVTextFormatContext *wctx, const void *data) { XMLContext *xml = wctx->priv; - const struct section *section = wctx->section[wctx->level]; - const struct section *parent_section = wctx->level ? + const struct AVTextFormatSection *section = wctx->section[wctx->level]; + const struct AVTextFormatSection *parent_section = wctx->level ? wctx->section[wctx->level-1] : NULL; if (wctx->level == 0) { @@ -1888,10 +1804,10 @@ static void xml_print_section_header(WriterContext *wctx, const void *data) } } -static void xml_print_section_footer(WriterContext *wctx) +static void xml_print_section_footer(AVTextFormatContext *wctx) { XMLContext *xml = wctx->priv; - const struct section *section = wctx->section[wctx->level]; + const struct AVTextFormatSection *section = wctx->section[wctx->level]; if (wctx->level == 0) { writer_printf(wctx, "</%sffprobe>\n", xml->fully_qualified ? "ffprobe:" : ""); @@ -1905,12 +1821,12 @@ static void xml_print_section_footer(WriterContext *wctx) } } -static void xml_print_value(WriterContext *wctx, const char *key, +static void xml_print_value(AVTextFormatContext *wctx, const char *key, const char *str, int64_t num, const int is_int) { AVBPrint buf; XMLContext *xml = wctx->priv; - const struct section *section = wctx->section[wctx->level]; + const struct AVTextFormatSection *section = wctx->section[wctx->level]; av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED); @@ -1947,16 +1863,16 @@ static void xml_print_value(WriterContext *wctx, const char *key, av_bprint_finalize(&buf, NULL); } -static inline void xml_print_str(WriterContext *wctx, const char *key, const char *value) { +static inline void xml_print_str(AVTextFormatContext *wctx, const char *key, const char *value) { xml_print_value(wctx, key, value, 0, 0); } -static void xml_print_int(WriterContext *wctx, const char *key, int64_t value) +static void xml_print_int(AVTextFormatContext *wctx, const char *key, int64_t value) { xml_print_value(wctx, key, NULL, value, 1); } -static Writer xml_writer = { +static AVTextFormatter xml_formatter = { .name = "xml", .priv_size = sizeof(XMLContext), .init = xml_init, @@ -2031,7 +1947,7 @@ static void writer_register_all(void) memset( (ptr) + (cur_n), 0, ((new_n) - (cur_n)) * sizeof(*(ptr)) ); \ } -static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id) +static inline int show_tags(AVTextFormatContext *w, AVDictionary *tags, int section_id) { const AVDictionaryEntry *tag = NULL; int ret = 0; @@ -2049,7 +1965,7 @@ static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id return ret; } -static void print_dovi_metadata(WriterContext *w, const AVDOVIMetadata *dovi) +static void print_dovi_metadata(AVTextFormatContext *w, const AVDOVIMetadata *dovi) { if (!dovi) return; @@ -2211,7 +2127,7 @@ static void print_dovi_metadata(WriterContext *w, const AVDOVIMetadata *dovi) } } -static void print_dynamic_hdr10_plus(WriterContext *w, const AVDynamicHDRPlus *metadata) +static void print_dynamic_hdr10_plus(AVTextFormatContext *w, const AVDynamicHDRPlus *metadata) { if (!metadata) return; @@ -2310,7 +2226,7 @@ static void print_dynamic_hdr10_plus(WriterContext *w, const AVDynamicHDRPlus *m } } -static void print_dynamic_hdr_vivid(WriterContext *w, const AVDynamicHDRVivid *metadata) +static void print_dynamic_hdr_vivid(AVTextFormatContext *w, const AVDynamicHDRVivid *metadata) { if (!metadata) return; @@ -2380,7 +2296,7 @@ static void print_dynamic_hdr_vivid(WriterContext *w, const AVDynamicHDRVivid *m } } -static void print_ambient_viewing_environment(WriterContext *w, +static void print_ambient_viewing_environment(AVTextFormatContext *w, const AVAmbientViewingEnvironment *env) { if (!env) @@ -2391,7 +2307,7 @@ static void print_ambient_viewing_environment(WriterContext *w, print_q("ambient_light_y", env->ambient_light_y, '/'); } -static void print_film_grain_params(WriterContext *w, +static void print_film_grain_params(AVTextFormatContext *w, const AVFilmGrainParams *fgp) { const char *color_range, *color_primaries, *color_trc, *color_space; @@ -2516,7 +2432,7 @@ static void print_film_grain_params(WriterContext *w, av_bprint_finalize(&pbuf, NULL); } -static void print_pkt_side_data(WriterContext *w, +static void print_pkt_side_data(AVTextFormatContext *w, AVCodecParameters *par, const AVPacketSideData *sd, SectionID id_data) @@ -2638,7 +2554,7 @@ static void print_pkt_side_data(WriterContext *w, } } -static void print_private_data(WriterContext *w, void *priv_data) +static void print_private_data(AVTextFormatContext *w, void *priv_data) { const AVOption *opt = NULL; while (opt = av_opt_next(priv_data, opt)) { @@ -2651,7 +2567,7 @@ static void print_private_data(WriterContext *w, void *priv_data) } } -static void print_color_range(WriterContext *w, enum AVColorRange color_range) +static void print_color_range(AVTextFormatContext *w, enum AVColorRange color_range) { const char *val = av_color_range_name(color_range); if (!val || color_range == AVCOL_RANGE_UNSPECIFIED) { @@ -2661,7 +2577,7 @@ static void print_color_range(WriterContext *w, enum AVColorRange color_range) } } -static void print_color_space(WriterContext *w, enum AVColorSpace color_space) +static void print_color_space(AVTextFormatContext *w, enum AVColorSpace color_space) { const char *val = av_color_space_name(color_space); if (!val || color_space == AVCOL_SPC_UNSPECIFIED) { @@ -2671,7 +2587,7 @@ static void print_color_space(WriterContext *w, enum AVColorSpace color_space) } } -static void print_primaries(WriterContext *w, enum AVColorPrimaries color_primaries) +static void print_primaries(AVTextFormatContext *w, enum AVColorPrimaries color_primaries) { const char *val = av_color_primaries_name(color_primaries); if (!val || color_primaries == AVCOL_PRI_UNSPECIFIED) { @@ -2681,7 +2597,7 @@ static void print_primaries(WriterContext *w, enum AVColorPrimaries color_primar } } -static void print_color_trc(WriterContext *w, enum AVColorTransferCharacteristic color_trc) +static void print_color_trc(AVTextFormatContext *w, enum AVColorTransferCharacteristic color_trc) { const char *val = av_color_transfer_name(color_trc); if (!val || color_trc == AVCOL_TRC_UNSPECIFIED) { @@ -2691,7 +2607,7 @@ static void print_color_trc(WriterContext *w, enum AVColorTransferCharacteristic } } -static void print_chroma_location(WriterContext *w, enum AVChromaLocation chroma_location) +static void print_chroma_location(AVTextFormatContext *w, enum AVChromaLocation chroma_location) { const char *val = av_chroma_location_name(chroma_location); if (!val || chroma_location == AVCHROMA_LOC_UNSPECIFIED) { @@ -2717,7 +2633,7 @@ static void clear_log(int need_lock) ff_mutex_unlock(&log_mutex); } -static int show_log(WriterContext *w, int section_ids, int section_id, int log_level) +static int show_log(AVTextFormatContext *w, int section_ids, int section_id, int log_level) { int i; ff_mutex_lock(&log_mutex); @@ -2752,7 +2668,7 @@ static int show_log(WriterContext *w, int section_ids, int section_id, int log_l return 0; } -static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int packet_idx) +static void show_packet(AVTextFormatContext *w, InputFile *ifile, AVPacket *pkt, int packet_idx) { char val_str[128]; AVStream *st = ifile->streams[pkt->stream_index].st; @@ -2810,7 +2726,7 @@ static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int p fflush(stdout); } -static void show_subtitle(WriterContext *w, AVSubtitle *sub, AVStream *stream, +static void show_subtitle(AVTextFormatContext *w, AVSubtitle *sub, AVStream *stream, AVFormatContext *fmt_ctx) { AVBPrint pbuf; @@ -2833,7 +2749,7 @@ static void show_subtitle(WriterContext *w, AVSubtitle *sub, AVStream *stream, fflush(stdout); } -static void print_frame_side_data(WriterContext *w, +static void print_frame_side_data(AVTextFormatContext *w, const AVFrame *frame, const AVStream *stream) { @@ -2919,7 +2835,7 @@ static void print_frame_side_data(WriterContext *w, writer_print_section_footer(w); } -static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, +static void show_frame(AVTextFormatContext *w, AVFrame *frame, AVStream *stream, AVFormatContext *fmt_ctx) { FrameData *fd = frame->opaque_ref ? (FrameData*)frame->opaque_ref->data : NULL; @@ -3007,7 +2923,7 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, fflush(stdout); } -static av_always_inline int process_frame(WriterContext *w, +static av_always_inline int process_frame(AVTextFormatContext *w, InputFile *ifile, AVFrame *frame, const AVPacket *pkt, int *packet_new) @@ -3104,7 +3020,7 @@ static void log_read_interval(const ReadInterval *interval, void *log_ctx, int l av_log(log_ctx, log_level, "\n"); } -static int read_interval_packets(WriterContext *w, InputFile *ifile, +static int read_interval_packets(AVTextFormatContext *w, InputFile *ifile, const ReadInterval *interval, int64_t *cur_ts) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; @@ -3229,7 +3145,7 @@ end: return ret; } -static int read_packets(WriterContext *w, InputFile *ifile) +static int read_packets(AVTextFormatContext *w, InputFile *ifile) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; int i, ret = 0; @@ -3249,7 +3165,7 @@ static int read_packets(WriterContext *w, InputFile *ifile) return ret; } -static void print_dispositions(WriterContext *w, uint32_t disposition, SectionID section_id) +static void print_dispositions(AVTextFormatContext *w, uint32_t disposition, SectionID section_id) { writer_print_section_header(w, NULL, section_id); for (int i = 0; i < sizeof(disposition) * CHAR_BIT; i++) { @@ -3264,7 +3180,7 @@ static void print_dispositions(WriterContext *w, uint32_t disposition, SectionID #define IN_PROGRAM 1 #define IN_STREAM_GROUP 2 -static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx, InputStream *ist, int container) +static int show_stream(AVTextFormatContext *w, AVFormatContext *fmt_ctx, int stream_idx, InputStream *ist, int container) { AVStream *stream = ist->st; AVCodecParameters *par; @@ -3487,7 +3403,7 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id return ret; } -static int show_streams(WriterContext *w, InputFile *ifile) +static int show_streams(AVTextFormatContext *w, InputFile *ifile) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; int i, ret = 0; @@ -3504,7 +3420,7 @@ static int show_streams(WriterContext *w, InputFile *ifile) return ret; } -static int show_program(WriterContext *w, InputFile *ifile, AVProgram *program) +static int show_program(AVTextFormatContext *w, InputFile *ifile, AVProgram *program) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; int i, ret = 0; @@ -3535,7 +3451,7 @@ end: return ret; } -static int show_programs(WriterContext *w, InputFile *ifile) +static int show_programs(AVTextFormatContext *w, InputFile *ifile) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; int i, ret = 0; @@ -3553,7 +3469,7 @@ static int show_programs(WriterContext *w, InputFile *ifile) return ret; } -static void print_tile_grid_params(WriterContext *w, const AVStreamGroup *stg, +static void print_tile_grid_params(AVTextFormatContext *w, const AVStreamGroup *stg, const AVStreamGroupTileGrid *tile_grid) { writer_print_section_header(w, stg, SECTION_ID_STREAM_GROUP_COMPONENT); @@ -3576,7 +3492,7 @@ static void print_tile_grid_params(WriterContext *w, const AVStreamGroup *stg, writer_print_section_footer(w); } -static void print_iamf_param_definition(WriterContext *w, const char *name, +static void print_iamf_param_definition(AVTextFormatContext *w, const char *name, const AVIAMFParamDefinition *param, SectionID section_id) { SectionID subsection_id, parameter_section_id; @@ -3631,7 +3547,7 @@ static void print_iamf_param_definition(WriterContext *w, const char *name, writer_print_section_footer(w); // section_id } -static void print_iamf_audio_element_params(WriterContext *w, const AVStreamGroup *stg, +static void print_iamf_audio_element_params(AVTextFormatContext *w, const AVStreamGroup *stg, const AVIAMFAudioElement *audio_element) { writer_print_section_header(w, stg, SECTION_ID_STREAM_GROUP_COMPONENT); @@ -3662,7 +3578,7 @@ static void print_iamf_audio_element_params(WriterContext *w, const AVStreamGrou writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_COMPONENT } -static void print_iamf_submix_params(WriterContext *w, const AVIAMFSubmix *submix) +static void print_iamf_submix_params(AVTextFormatContext *w, const AVIAMFSubmix *submix) { writer_print_section_header(w, "IAMF Submix", SECTION_ID_STREAM_GROUP_SUBCOMPONENT); print_int("nb_elements", submix->nb_elements); @@ -3709,7 +3625,7 @@ static void print_iamf_submix_params(WriterContext *w, const AVIAMFSubmix *submi writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_SUBCOMPONENT } -static void print_iamf_mix_presentation_params(WriterContext *w, const AVStreamGroup *stg, +static void print_iamf_mix_presentation_params(AVTextFormatContext *w, const AVStreamGroup *stg, const AVIAMFMixPresentation *mix_presentation) { writer_print_section_header(w, stg, SECTION_ID_STREAM_GROUP_COMPONENT); @@ -3728,7 +3644,7 @@ static void print_iamf_mix_presentation_params(WriterContext *w, const AVStreamG writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_COMPONENT } -static void print_stream_group_params(WriterContext *w, AVStreamGroup *stg) +static void print_stream_group_params(AVTextFormatContext *w, AVStreamGroup *stg) { writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_COMPONENTS); if (stg->type == AV_STREAM_GROUP_PARAMS_TILE_GRID) @@ -3740,7 +3656,7 @@ static void print_stream_group_params(WriterContext *w, AVStreamGroup *stg) writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_COMPONENTS } -static int show_stream_group(WriterContext *w, InputFile *ifile, AVStreamGroup *stg) +static int show_stream_group(AVTextFormatContext *w, InputFile *ifile, AVStreamGroup *stg) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; AVBPrint pbuf; @@ -3784,7 +3700,7 @@ end: return ret; } -static int show_stream_groups(WriterContext *w, InputFile *ifile) +static int show_stream_groups(AVTextFormatContext *w, InputFile *ifile) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; int i, ret = 0; @@ -3801,7 +3717,7 @@ static int show_stream_groups(WriterContext *w, InputFile *ifile) return ret; } -static int show_chapters(WriterContext *w, InputFile *ifile) +static int show_chapters(AVTextFormatContext *w, InputFile *ifile) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; int i, ret = 0; @@ -3826,7 +3742,7 @@ static int show_chapters(WriterContext *w, InputFile *ifile) return ret; } -static int show_format(WriterContext *w, InputFile *ifile) +static int show_format(AVTextFormatContext *w, InputFile *ifile) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; char val_str[128]; @@ -3858,7 +3774,7 @@ static int show_format(WriterContext *w, InputFile *ifile) return ret; } -static void show_error(WriterContext *w, int err) +static void show_error(AVTextFormatContext *w, int err) { writer_print_section_header(w, NULL, SECTION_ID_ERROR); print_int("code", err); @@ -4005,7 +3921,7 @@ static void close_input_file(InputFile *ifile) avformat_close_input(&ifile->fmt_ctx); } -static int probe_file(WriterContext *wctx, const char *filename, +static int probe_file(AVTextFormatContext *wctx, const char *filename, const char *print_filename) { InputFile ifile = { 0 }; @@ -4103,7 +4019,7 @@ static void show_usage(void) av_log(NULL, AV_LOG_INFO, "\n"); } -static void ffprobe_show_program_version(WriterContext *w) +static void ffprobe_show_program_version(AVTextFormatContext *w) { AVBPrint pbuf; av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED); @@ -4134,7 +4050,7 @@ static void ffprobe_show_program_version(WriterContext *w) } \ } while (0) -static void ffprobe_show_library_versions(WriterContext *w) +static void ffprobe_show_library_versions(AVTextFormatContext *w) { writer_print_section_header(w, NULL, SECTION_ID_LIBRARY_VERSIONS); SHOW_LIB_VERSION(avutil, AVUTIL); @@ -4153,7 +4069,7 @@ static void ffprobe_show_library_versions(WriterContext *w) print_int(name, !!(pixdesc->flags & AV_PIX_FMT_FLAG_##flagname)); \ } while (0) -static void ffprobe_show_pixel_formats(WriterContext *w) +static void ffprobe_show_pixel_formats(AVTextFormatContext *w) { const AVPixFmtDescriptor *pixdesc = NULL; int i, n; @@ -4229,11 +4145,11 @@ 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 section *section = §ions[section_id]; + struct AVTextFormatSection *section = §ions[section_id]; section->show_all_entries = show_all_entries; if (show_all_entries) { - for (const SectionID *id = section->children_ids; *id != -1; 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); @@ -4246,7 +4162,7 @@ static int match_section(const char *section_name, int i, ret = 0; for (i = 0; i < FF_ARRAY_ELEMS(sections); i++) { - const struct section *section = §ions[i]; + const struct AVTextFormatSection *section = §ions[i]; if (!strcmp(section_name, section->name) || (section->unique_name && !strcmp(section_name, section->unique_name))) { av_log(NULL, AV_LOG_DEBUG, @@ -4518,8 +4434,8 @@ static int opt_pretty(void *optctx, const char *opt, const char *arg) static void print_section(SectionID id, int level) { - const SectionID *pid; - const struct section *section = §ions[id]; + const int *pid; + const struct AVTextFormatSection *section = §ions[id]; printf("%c%c%c%c", section->flags & SECTION_FLAG_IS_WRAPPER ? 'W' : '.', section->flags & SECTION_FLAG_IS_ARRAY ? 'A' : '.', @@ -4627,10 +4543,10 @@ static const OptionDef real_options[] = { static inline int check_section_show_entries(int section_id) { - struct section *section = §ions[section_id]; + struct AVTextFormatSection *section = §ions[section_id]; if (sections[section_id].show_all_entries || sections[section_id].entries_to_show) return 1; - for (const SectionID *id = section->children_ids; *id != -1; id++) + for (const int *id = section->children_ids; *id != -1; id++) if (check_section_show_entries(*id)) return 1; return 0; @@ -4643,8 +4559,8 @@ static inline int check_section_show_entries(int section_id) int main(int argc, char **argv) { - const Writer *w; - WriterContext *wctx; + const AVTextFormatter *w; + AVTextFormatContext *wctx; char *buf; char *w_name = NULL, *w_args = NULL; int ret, input_ret, i; @@ -4749,7 +4665,7 @@ int main(int argc, char **argv) if ((ret = writer_open(&wctx, w, w_args, sections, FF_ARRAY_ELEMS(sections), output_filename)) >= 0) { - if (w == &xml_writer) + if (w == &xml_formatter) wctx->string_validation_utf8_flags |= AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES; writer_print_section_header(wctx, NULL, SECTION_ID_ROOT); diff --git a/libavutil/Makefile b/libavutil/Makefile index b2b3b9c156..ad5aab7d40 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -9,6 +9,7 @@ HEADERS = adler32.h \ audio_fifo.h \ avassert.h \ avstring.h \ + avtextformat.h \ avutil.h \ base64.h \ blowfish.h \ diff --git a/libavutil/avtextformat.h b/libavutil/avtextformat.h new file mode 100644 index 0000000000..1740a73249 --- /dev/null +++ b/libavutil/avtextformat.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) The ffmpeg developers + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AVTEXTFORMAT_H +#define AVUTIL_AVTEXTFORMAT_H + +#include <stddef.h> +#include <stdint.h> +#include "attributes.h" +#include "dict.h" +#include <libavformat/avio.h> +#include "bprint.h" +#include "rational.h" + +#define SECTION_MAX_NB_CHILDREN 11 + + +struct AVTextFormatSection { + int id; ///< unique id identifying a section + const char *name; + +#define SECTION_FLAG_IS_WRAPPER 1 ///< the section only contains other sections, but has no data at its own level +#define SECTION_FLAG_IS_ARRAY 2 ///< the section contains an array of elements of the same type +#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 + + int flags; + 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; +}; + +typedef struct AVTextFormatContext AVTextFormatContext; + +#define WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS 1 +#define WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER 2 + +typedef enum { + WRITER_STRING_VALIDATION_FAIL, + WRITER_STRING_VALIDATION_REPLACE, + WRITER_STRING_VALIDATION_IGNORE, + WRITER_STRING_VALIDATION_NB +} StringValidation; + +typedef struct AVTextFormatter { + const AVClass *priv_class; ///< private class of the writer, if any + int priv_size; ///< private size for the writer context + const char *name; + + int (*init) (AVTextFormatContext *wctx); + void (*uninit)(AVTextFormatContext *wctx); + + void (*print_section_header)(AVTextFormatContext *wctx, const void *data); + void (*print_section_footer)(AVTextFormatContext *wctx); + void (*print_integer) (AVTextFormatContext *wctx, const char *, int64_t); + void (*print_rational) (AVTextFormatContext *wctx, AVRational *q, char *sep); + void (*print_string) (AVTextFormatContext *wctx, const char *, const char *); + int flags; ///< a combination or WRITER_FLAG_* +} AVTextFormatter; + +#define SECTION_MAX_NB_LEVELS 12 + +struct AVTextFormatContext { + const AVClass *class; ///< class of the writer + const AVTextFormatter *writer; ///< the AVTextFormatter of which this is an instance + AVIOContext *avio; ///< the I/O context used to write + + void (* writer_w8)(AVTextFormatContext *wctx, int b); + void (* writer_put_str)(AVTextFormatContext *wctx, const char *str); + void (* writer_printf)(AVTextFormatContext *wctx, const char *fmt, ...); + + char *name; ///< name of this writer instance + void *priv; ///< private data for use by the filter + + const struct AVTextFormatSection *sections; ///< array containing all sections + int nb_sections; ///< number of sections + + int level; ///< current level, starting from 0 + + /** number of the item printed in the given section, starting from 0 */ + unsigned int nb_item[SECTION_MAX_NB_LEVELS]; + + /** 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 string_validation; + char *string_validation_replacement; + unsigned int string_validation_utf8_flags; +}; + + + +#endif /* AVUTIL_AVTEXTFORMAT_H */ -- 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 ` softworkz [this message] 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 ` [FFmpeg-devel] [PATCH 3/8] ffprobe/avtextformat: Generalize ffprobe specifics softworkz 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=28b1c6d4cf7e7d577ffce832fb2632ea0fd0aa7a.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