From: softworkz <ffmpegagent@gmail.com> To: ffmpeg-devel@ffmpeg.org Cc: softworkz <softworkz@hotmail.com> Subject: [FFmpeg-devel] [PATCH 2/8] ffprobe/avtextformat: Rename and move writer functions and options Date: Thu, 27 Feb 2025 14:01:34 +0000 Message-ID: <89d538cab47c517b35ecaccb563e14334c9f9927.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 | 910 ++++++---------------------- libavutil/Makefile | 1 + libavutil/avtextformat.h | 50 ++ libavutil/textformat/avtextformat.c | 620 +++++++++++++++++++ 4 files changed, 848 insertions(+), 733 deletions(-) create mode 100644 libavutil/textformat/avtextformat.c diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 76848c3cf4..837e21c0e2 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -41,7 +41,6 @@ #include "libavutil/channel_layout.h" #include "libavutil/display.h" #include "libavutil/film_grain_params.h" -#include "libavutil/hash.h" #include "libavutil/hdr_dynamic_metadata.h" #include "libavutil/iamf.h" #include "libavutil/mastering_display_metadata.h" @@ -131,6 +130,7 @@ static int show_value_unit = 0; static int use_value_prefix = 0; static int use_byte_value_binary_prefix = 0; static int use_value_sexagesimal_format = 0; + static int show_private_data = 1; #define SHOW_OPTIONAL_FIELDS_AUTO -1 @@ -158,7 +158,6 @@ static int find_stream_info = 1; /* section structure definition */ typedef enum { - SECTION_ID_NONE = -1, SECTION_ID_CHAPTER, SECTION_ID_CHAPTER_TAGS, SECTION_ID_CHAPTERS, @@ -330,22 +329,6 @@ static const char *print_input_filename; static const AVInputFormat *iformat = NULL; static const char *output_filename = NULL; -static struct AVHashContext *hash; - -static const struct { - double bin_val; - double dec_val; - const char *bin_str; - const char *dec_str; -} si_prefixes[] = { - { 1.0, 1.0, "", "" }, - { 1.024e3, 1e3, "Ki", "K" }, - { 1.048576e6, 1e6, "Mi", "M" }, - { 1.073741824e9, 1e9, "Gi", "G" }, - { 1.099511627776e12, 1e12, "Ti", "T" }, - { 1.125899906842624e15, 1e15, "Pi", "P" }, -}; - static const char unit_second_str[] = "s" ; static const char unit_hertz_str[] = "Hz" ; static const char unit_byte_str[] = "byte" ; @@ -421,527 +404,9 @@ static void log_callback(void *ptr, int level, const char *fmt, va_list vl) #endif } -struct unit_value { - union { double d; int64_t i; } val; - const char *unit; -}; - -static char *value_string(char *buf, int buf_size, struct unit_value uv) -{ - double vald; - int64_t vali; - int show_float = 0; - - if (uv.unit == unit_second_str) { - vald = uv.val.d; - show_float = 1; - } else { - vald = vali = uv.val.i; - } - - if (uv.unit == unit_second_str && use_value_sexagesimal_format) { - double secs; - int hours, mins; - secs = vald; - mins = (int)secs / 60; - secs = secs - mins * 60; - hours = mins / 60; - mins %= 60; - snprintf(buf, buf_size, "%d:%02d:%09.6f", hours, mins, secs); - } else { - const char *prefix_string = ""; - - if (use_value_prefix && vald > 1) { - int64_t index; - - if (uv.unit == unit_byte_str && use_byte_value_binary_prefix) { - index = (int64_t) (log2(vald)) / 10; - index = av_clip(index, 0, FF_ARRAY_ELEMS(si_prefixes) - 1); - vald /= si_prefixes[index].bin_val; - prefix_string = si_prefixes[index].bin_str; - } else { - index = (int64_t) (log10(vald)) / 3; - index = av_clip(index, 0, FF_ARRAY_ELEMS(si_prefixes) - 1); - vald /= si_prefixes[index].dec_val; - prefix_string = si_prefixes[index].dec_str; - } - vali = vald; - } - - if (show_float || (use_value_prefix && vald != (int64_t)vald)) - snprintf(buf, buf_size, "%f", vald); - else - snprintf(buf, buf_size, "%"PRId64, vali); - av_strlcatf(buf, buf_size, "%s%s%s", *prefix_string || show_value_unit ? " " : "", - prefix_string, show_value_unit ? uv.unit : ""); - } - - return buf; -} - /* WRITERS API */ -static const char *writer_get_name(void *p) -{ - AVTextFormatContext *wctx = p; - return wctx->writer->name; -} - -#define OFFSET(x) offsetof(AVTextFormatContext, x) - -static const AVOption writer_options[] = { - { "string_validation", "set string validation mode", - OFFSET(string_validation), AV_OPT_TYPE_INT, {.i64=WRITER_STRING_VALIDATION_REPLACE}, 0, WRITER_STRING_VALIDATION_NB-1, .unit = "sv" }, - { "sv", "set string validation mode", - OFFSET(string_validation), AV_OPT_TYPE_INT, {.i64=WRITER_STRING_VALIDATION_REPLACE}, 0, WRITER_STRING_VALIDATION_NB-1, .unit = "sv" }, - { "ignore", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = WRITER_STRING_VALIDATION_IGNORE}, .unit = "sv" }, - { "replace", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = WRITER_STRING_VALIDATION_REPLACE}, .unit = "sv" }, - { "fail", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = WRITER_STRING_VALIDATION_FAIL}, .unit = "sv" }, - { "string_validation_replacement", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, {.str=""}}, - { "svr", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, {.str="\xEF\xBF\xBD"}}, - { NULL } -}; - -static void *writer_child_next(void *obj, void *prev) -{ - 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 = "AVTextFormatter", - .item_name = writer_get_name, - .option = writer_options, - .version = LIBAVUTIL_VERSION_INT, - .child_next = writer_child_next, -}; - -static int writer_close(AVTextFormatContext **wctx) -{ - int i; - int ret = 0; - - if (!*wctx) - return -1; - - if ((*wctx)->writer->uninit) - (*wctx)->writer->uninit(*wctx); - for (i = 0; i < SECTION_MAX_NB_LEVELS; i++) - av_bprint_finalize(&(*wctx)->section_pbuf[i], NULL); - if ((*wctx)->writer->priv_class) - av_opt_free((*wctx)->priv); - av_freep(&((*wctx)->priv)); - av_opt_free(*wctx); - if ((*wctx)->avio) { - avio_flush((*wctx)->avio); - ret = avio_close((*wctx)->avio); - } - av_freep(wctx); - return ret; -} - -static void bprint_bytes(AVBPrint *bp, const uint8_t *ubuf, size_t ubuf_size) -{ - int i; - av_bprintf(bp, "0X"); - for (i = 0; i < ubuf_size; i++) - av_bprintf(bp, "%02X", ubuf[i]); -} - -static inline void writer_w8_avio(AVTextFormatContext *wctx, int b) -{ - avio_w8(wctx->avio, b); -} - -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(AVTextFormatContext *wctx, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - avio_vprintf(wctx->avio, fmt, ap); - va_end(ap); -} - -static inline void writer_w8_printf(AVTextFormatContext *wctx, int b) -{ - printf("%c", b); -} - -static inline void writer_put_str_printf(AVTextFormatContext *wctx, const char *str) -{ - printf("%s", str); -} - -static inline void writer_printf_printf(AVTextFormatContext *wctx, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); -} - -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(AVTextFormatContext)))) { - ret = AVERROR(ENOMEM); - goto fail; - } - - if (!((*wctx)->priv = av_mallocz(writer->priv_size))) { - ret = AVERROR(ENOMEM); - goto fail; - } - - (*wctx)->class = &writer_class; - (*wctx)->writer = writer; - (*wctx)->level = -1; - (*wctx)->sections = sections; - (*wctx)->nb_sections = nb_sections; - - av_opt_set_defaults(*wctx); - - if (writer->priv_class) { - void *priv_ctx = (*wctx)->priv; - *((const AVClass **)priv_ctx) = writer->priv_class; - av_opt_set_defaults(priv_ctx); - } - - /* convert options to dictionary */ - if (args) { - AVDictionary *opts = NULL; - const AVDictionaryEntry *opt = NULL; - - if ((ret = av_dict_parse_string(&opts, args, "=", ":", 0)) < 0) { - av_log(*wctx, AV_LOG_ERROR, "Failed to parse option string '%s' provided to writer context\n", args); - av_dict_free(&opts); - goto fail; - } - - while ((opt = av_dict_iterate(opts, opt))) { - if ((ret = av_opt_set(*wctx, opt->key, opt->value, AV_OPT_SEARCH_CHILDREN)) < 0) { - av_log(*wctx, AV_LOG_ERROR, "Failed to set option '%s' with value '%s' provided to writer context\n", - opt->key, opt->value); - av_dict_free(&opts); - goto fail; - } - } - - av_dict_free(&opts); - } - - /* validate replace string */ - { - const uint8_t *p = (*wctx)->string_validation_replacement; - const uint8_t *endp = p + strlen(p); - while (*p) { - const uint8_t *p0 = p; - int32_t code; - ret = av_utf8_decode(&code, &p, endp, (*wctx)->string_validation_utf8_flags); - if (ret < 0) { - AVBPrint bp; - av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC); - bprint_bytes(&bp, p0, p-p0), - av_log(wctx, AV_LOG_ERROR, - "Invalid UTF8 sequence %s found in string validation replace '%s'\n", - bp.str, (*wctx)->string_validation_replacement); - return ret; - } - } - } - - if (!output_filename) { - (*wctx)->writer_w8 = writer_w8_printf; - (*wctx)->writer_put_str = writer_put_str_printf; - (*wctx)->writer_printf = writer_printf_printf; - } else { - if ((ret = avio_open(&(*wctx)->avio, output, AVIO_FLAG_WRITE)) < 0) { - av_log(*wctx, AV_LOG_ERROR, - "Failed to open output '%s' with error: %s\n", output, av_err2str(ret)); - goto fail; - } - (*wctx)->writer_w8 = writer_w8_avio; - (*wctx)->writer_put_str = writer_put_str_avio; - (*wctx)->writer_printf = writer_printf_avio; - } - - for (i = 0; i < SECTION_MAX_NB_LEVELS; i++) - av_bprint_init(&(*wctx)->section_pbuf[i], 1, AV_BPRINT_SIZE_UNLIMITED); - if ((*wctx)->writer->init) - ret = (*wctx)->writer->init(*wctx); - if (ret < 0) - goto fail; - - return 0; - -fail: - writer_close(wctx); - return ret; -} - -static inline void writer_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; - 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); -} - -static inline void writer_print_section_footer(AVTextFormatContext *wctx) -{ - int section_id = wctx->section[wctx->level]->id; - 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 (wctx->writer->print_section_footer) - wctx->writer->print_section_footer(wctx); - wctx->level--; -} - -static inline void writer_print_integer(AVTextFormatContext *wctx, - const char *key, int64_t val) -{ - 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); - wctx->nb_item[wctx->level]++; - } -} - -static inline int validate_string(AVTextFormatContext *wctx, char **dstp, const char *src) -{ - const uint8_t *p, *endp; - AVBPrint dstbuf; - int invalid_chars_nb = 0, ret = 0; - - av_bprint_init(&dstbuf, 0, AV_BPRINT_SIZE_UNLIMITED); - - endp = src + strlen(src); - for (p = src; *p;) { - uint32_t code; - int invalid = 0; - const uint8_t *p0 = p; - - if (av_utf8_decode(&code, &p, endp, wctx->string_validation_utf8_flags) < 0) { - AVBPrint bp; - av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC); - bprint_bytes(&bp, p0, p-p0); - av_log(wctx, AV_LOG_DEBUG, - "Invalid UTF-8 sequence %s found in string '%s'\n", bp.str, src); - invalid = 1; - } - - if (invalid) { - invalid_chars_nb++; - - switch (wctx->string_validation) { - case WRITER_STRING_VALIDATION_FAIL: - av_log(wctx, AV_LOG_ERROR, - "Invalid UTF-8 sequence found in string '%s'\n", src); - ret = AVERROR_INVALIDDATA; - goto end; - break; - - case WRITER_STRING_VALIDATION_REPLACE: - av_bprintf(&dstbuf, "%s", wctx->string_validation_replacement); - break; - } - } - - if (!invalid || wctx->string_validation == WRITER_STRING_VALIDATION_IGNORE) - av_bprint_append_data(&dstbuf, p0, p-p0); - } - - if (invalid_chars_nb && wctx->string_validation == WRITER_STRING_VALIDATION_REPLACE) { - av_log(wctx, AV_LOG_WARNING, - "%d invalid UTF-8 sequence(s) found in string '%s', replaced with '%s'\n", - invalid_chars_nb, src, wctx->string_validation_replacement); - } - -end: - av_bprint_finalize(&dstbuf, dstp); - return ret; -} - -#define PRINT_STRING_OPT 1 -#define PRINT_STRING_VALIDATE 2 - -static inline int writer_print_string(AVTextFormatContext *wctx, - const char *key, const char *val, int flags) -{ - const struct AVTextFormatSection *section = wctx->section[wctx->level]; - int ret = 0; - - if (show_optional_fields == SHOW_OPTIONAL_FIELDS_NEVER || - (show_optional_fields == SHOW_OPTIONAL_FIELDS_AUTO - && (flags & PRINT_STRING_OPT) - && !(wctx->writer->flags & WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS))) - return 0; - - if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) { - if (flags & PRINT_STRING_VALIDATE) { - char *key1 = NULL, *val1 = NULL; - ret = validate_string(wctx, &key1, key); - if (ret < 0) goto end; - ret = validate_string(wctx, &val1, val); - if (ret < 0) goto end; - wctx->writer->print_string(wctx, key1, val1); - end: - if (ret < 0) { - av_log(wctx, AV_LOG_ERROR, - "Invalid key=value string combination %s=%s in section %s\n", - key, val, section->unique_name); - } - av_free(key1); - av_free(val1); - } else { - wctx->writer->print_string(wctx, key, val); - } - - wctx->nb_item[wctx->level]++; - } - - return ret; -} - -static inline void writer_print_rational(AVTextFormatContext *wctx, - const char *key, AVRational q, char sep) -{ - AVBPrint buf; - av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC); - av_bprintf(&buf, "%d%c%d", q.num, sep, q.den); - writer_print_string(wctx, key, buf.str, 0); -} - -static void writer_print_time(AVTextFormatContext *wctx, const char *key, - int64_t ts, const AVRational *time_base, int is_duration) -{ - char buf[128]; - - if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) { - writer_print_string(wctx, key, "N/A", PRINT_STRING_OPT); - } else { - double d = ts * av_q2d(*time_base); - struct unit_value uv; - uv.val.d = d; - uv.unit = unit_second_str; - value_string(buf, sizeof(buf), uv); - writer_print_string(wctx, key, buf, 0); - } -} - -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); - } else { - writer_print_integer(wctx, key, ts); - } -} - -static void writer_print_data(AVTextFormatContext *wctx, const char *name, - const uint8_t *data, int size) -{ - AVBPrint bp; - int offset = 0, l, i; - - av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED); - av_bprintf(&bp, "\n"); - while (size) { - av_bprintf(&bp, "%08x: ", offset); - l = FFMIN(size, 16); - for (i = 0; i < l; i++) { - av_bprintf(&bp, "%02x", data[i]); - if (i & 1) - av_bprintf(&bp, " "); - } - av_bprint_chars(&bp, ' ', 41 - 2 * i - i / 2); - for (i = 0; i < l; i++) - av_bprint_chars(&bp, data[i] - 32U < 95 ? data[i] : '.', 1); - av_bprintf(&bp, "\n"); - offset += l; - data += l; - size -= l; - } - writer_print_string(wctx, name, bp.str, 0); - av_bprint_finalize(&bp, NULL); -} - -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 }; - - if (!hash) - return; - av_hash_init(hash); - av_hash_update(hash, data, size); - snprintf(buf, sizeof(buf), "%s:", av_hash_get_name(hash)); - p = buf + strlen(buf); - av_hash_final_hex(hash, p, buf + sizeof(buf) - p); - writer_print_string(wctx, name, buf, 0); -} - -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) -{ - AVBPrint bp; - int offset = 0, l, i; - - 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; - } - writer_print_string(wctx, name, bp.str, 0); - av_bprint_finalize(&bp, NULL); -} #define writer_w8(wctx_, b_) (wctx_)->writer_w8(wctx_, b_) #define writer_put_str(wctx_, str_) (wctx_)->writer_put_str(wctx_, str_) @@ -1075,7 +540,7 @@ static void default_print_int(AVTextFormatContext *wctx, const char *key, int64_ writer_printf(wctx, "%"PRId64"\n", value); } -static const AVTextFormatter default_writer = { +static const AVTextFormatter default_formatter = { .name = "default", .priv_size = sizeof(DefaultContext), .print_section_header = default_print_section_header, @@ -1749,8 +1214,8 @@ static av_cold int xml_init(AVTextFormatContext *wctx) return AVERROR(EINVAL); \ } CHECK_COMPLIANCE(show_private_data, "private"); - CHECK_COMPLIANCE(show_value_unit, "unit"); - CHECK_COMPLIANCE(use_value_prefix, "prefix"); + CHECK_COMPLIANCE(wctx->show_value_unit, "unit"); + CHECK_COMPLIANCE(wctx->use_value_prefix, "prefix"); } return 0; @@ -1892,19 +1357,19 @@ static void writer_register_all(void) return; initialized = 1; - writer_register(&default_writer); - writer_register(&compact_writer); - writer_register(&csv_writer); - writer_register(&flat_writer); - writer_register(&ini_writer); - writer_register(&json_writer); - writer_register(&xml_writer); + writer_register(&default_formatter); + writer_register(&compact_formatter); + writer_register(&csv_formatter); + writer_register(&flat_formatter); + writer_register(&ini_formatter); + writer_register(&json_formatter); + writer_register(&xml_formatter); } #define print_fmt(k, f, ...) do { \ av_bprint_clear(&pbuf); \ av_bprintf(&pbuf, f, __VA_ARGS__); \ - writer_print_string(w, k, pbuf.str, 0); \ + avtext_print_string(w, k, pbuf.str, 0); \ } while (0) #define print_list_fmt(k, f, n, m, ...) do { \ @@ -1916,28 +1381,23 @@ static void writer_register_all(void) av_bprintf(&pbuf, f, __VA_ARGS__); \ } \ } \ - writer_print_string(w, k, pbuf.str, 0); \ -} while (0) - -#define print_int(k, v) writer_print_integer(w, k, v) -#define print_q(k, v, s) writer_print_rational(w, k, v, s) -#define print_str(k, v) writer_print_string(w, k, v, 0) -#define print_str_opt(k, v) writer_print_string(w, k, v, PRINT_STRING_OPT) -#define print_str_validate(k, v) writer_print_string(w, k, v, PRINT_STRING_VALIDATE) -#define print_time(k, v, tb) writer_print_time(w, k, v, tb, 0) -#define print_ts(k, v) writer_print_ts(w, k, v, 0) -#define print_duration_time(k, v, tb) writer_print_time(w, k, v, tb, 1) -#define print_duration_ts(k, v) writer_print_ts(w, k, v, 1) -#define print_val(k, v, u) do { \ - struct unit_value uv; \ - uv.val.i = v; \ - uv.unit = u; \ - writer_print_string(w, k, value_string(val_str, sizeof(val_str), uv), 0); \ + avtext_print_string(w, k, pbuf.str, 0); \ } while (0) -#define print_section_header(s) writer_print_section_header(w, NULL, s) -#define print_section_header_data(s, d) writer_print_section_header(w, d, s) -#define print_section_footer(s) writer_print_section_footer(w, s) +#define print_int(k, v) avtext_print_integer(w, k, v) +#define print_q(k, v, s) avtext_print_rational(w, k, v, s) +#define print_str(k, v) avtext_print_string(w, k, v, 0) +#define print_str_opt(k, v) avtext_print_string(w, k, v, PRINT_STRING_OPT) +#define print_str_validate(k, v) avtext_print_string(w, k, v, PRINT_STRING_VALIDATE) +#define print_time(k, v, tb) avtext_print_time(w, k, v, tb, 0) +#define print_ts(k, v) avtext_print_ts(w, k, v, 0) +#define print_duration_time(k, v, tb) avtext_print_time(w, k, v, tb, 1) +#define print_duration_ts(k, v) avtext_print_ts(w, k, v, 1) +#define print_val(k, v, u) avtext_print_unit_int(w, k, v, u) + +#define print_section_header(s) avtext_print_section_header(w, NULL, s) +#define print_section_header_data(s, d) avtext_print_section_header(w, d, s) +#define print_section_footer(s) avtext_print_section_footer(w, s) #define REALLOCZ_ARRAY_STREAM(ptr, cur_n, new_n) \ { \ @@ -1954,13 +1414,13 @@ static inline int show_tags(AVTextFormatContext *w, AVDictionary *tags, int sect if (!tags) return 0; - writer_print_section_header(w, NULL, section_id); + avtext_print_section_header(w, NULL, section_id); while ((tag = av_dict_iterate(tags, tag))) { if ((ret = print_str_validate(tag->key, tag->value)) < 0) break; } - writer_print_section_footer(w); + avtext_print_section_footer(w); return ret; } @@ -2020,15 +1480,15 @@ static void print_dovi_metadata(AVTextFormatContext *w, const AVDOVIMetadata *do print_int("num_x_partitions", mapping->num_x_partitions); print_int("num_y_partitions", mapping->num_y_partitions); - writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST); + avtext_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST); for (int c = 0; c < 3; c++) { const AVDOVIReshapingCurve *curve = &mapping->curves[c]; - writer_print_section_header(w, "Reshaping curve", SECTION_ID_FRAME_SIDE_DATA_COMPONENT); + avtext_print_section_header(w, "Reshaping curve", SECTION_ID_FRAME_SIDE_DATA_COMPONENT); print_list_fmt("pivots", "%"PRIu16, curve->num_pivots, 1, curve->pivots[idx]); - writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST); + avtext_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST); for (int i = 0; i < curve->num_pivots - 1; i++) { AVBPrint piece_buf; @@ -2046,7 +1506,7 @@ static void print_dovi_metadata(AVTextFormatContext *w, const AVDOVIMetadata *do } av_bprintf(&piece_buf, " mapping"); - writer_print_section_header(w, piece_buf.str, SECTION_ID_FRAME_SIDE_DATA_PIECE); + avtext_print_section_header(w, piece_buf.str, SECTION_ID_FRAME_SIDE_DATA_PIECE); print_int("mapping_idc", curve->mapping_idc[i]); switch (curve->mapping_idc[i]) { case AV_DOVI_MAPPING_POLYNOMIAL: @@ -2070,11 +1530,11 @@ static void print_dovi_metadata(AVTextFormatContext *w, const AVDOVIMetadata *do } // SECTION_ID_FRAME_SIDE_DATA_PIECE - writer_print_section_footer(w); + avtext_print_section_footer(w); } // SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST - writer_print_section_footer(w); + avtext_print_section_footer(w); if (mapping->nlq_method_idc != AV_DOVI_NLQ_NONE) { const AVDOVINLQParams *nlq = &mapping->nlq[c]; @@ -2090,11 +1550,11 @@ static void print_dovi_metadata(AVTextFormatContext *w, const AVDOVIMetadata *do } // SECTION_ID_FRAME_SIDE_DATA_COMPONENT - writer_print_section_footer(w); + avtext_print_section_footer(w); } // SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST - writer_print_section_footer(w); + avtext_print_section_footer(w); // color metadata print_int("dm_metadata_id", color->dm_metadata_id); @@ -2353,10 +1813,10 @@ static void print_film_grain_params(AVTextFormatContext *w, print_int("overlap_flag", aom->overlap_flag); print_int("limit_output_range", aom->limit_output_range); - writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST); + avtext_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST); if (aom->num_y_points) { - writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT); + avtext_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT); print_int("bit_depth_luma", fgp->bit_depth_luma); print_list_fmt("y_points_value", "%"PRIu8, aom->num_y_points, 1, aom->y_points[idx][0]); @@ -2364,14 +1824,14 @@ static void print_film_grain_params(AVTextFormatContext *w, print_list_fmt("ar_coeffs_y", "%"PRId8, num_ar_coeffs_y, 1, aom->ar_coeffs_y[idx]); // SECTION_ID_FRAME_SIDE_DATA_COMPONENT - writer_print_section_footer(w); + avtext_print_section_footer(w); } for (int uv = 0; uv < 2; uv++) { if (!aom->num_uv_points[uv] && !aom->chroma_scaling_from_luma) continue; - writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT); + avtext_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT); print_int("bit_depth_chroma", fgp->bit_depth_chroma); print_list_fmt("uv_points_value", "%"PRIu8, aom->num_uv_points[uv], 1, aom->uv_points[uv][idx][0]); @@ -2382,11 +1842,11 @@ static void print_film_grain_params(AVTextFormatContext *w, print_int("uv_offset", aom->uv_offset[uv]); // SECTION_ID_FRAME_SIDE_DATA_COMPONENT - writer_print_section_footer(w); + avtext_print_section_footer(w); } // SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST - writer_print_section_footer(w); + avtext_print_section_footer(w); break; } case AV_FILM_GRAIN_PARAMS_H274: { @@ -2395,36 +1855,36 @@ static void print_film_grain_params(AVTextFormatContext *w, print_int("blending_mode_id", h274->blending_mode_id); print_int("log2_scale_factor", h274->log2_scale_factor); - writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST); + avtext_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST); for (int c = 0; c < 3; c++) { if (!h274->component_model_present[c]) continue; - writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT); + avtext_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT); print_int(c ? "bit_depth_chroma" : "bit_depth_luma", c ? fgp->bit_depth_chroma : fgp->bit_depth_luma); - writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST); + avtext_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST); for (int i = 0; i < h274->num_intensity_intervals[c]; i++) { - writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_PIECE); + avtext_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_PIECE); print_int("intensity_interval_lower_bound", h274->intensity_interval_lower_bound[c][i]); print_int("intensity_interval_upper_bound", h274->intensity_interval_upper_bound[c][i]); print_list_fmt("comp_model_value", "%"PRId16, h274->num_model_values[c], 1, h274->comp_model_value[c][i][idx]); // SECTION_ID_FRAME_SIDE_DATA_PIECE - writer_print_section_footer(w); + avtext_print_section_footer(w); } // SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST - writer_print_section_footer(w); + avtext_print_section_footer(w); // SECTION_ID_FRAME_SIDE_DATA_COMPONENT - writer_print_section_footer(w); + avtext_print_section_footer(w); } // SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST - writer_print_section_footer(w); + avtext_print_section_footer(w); break; } } @@ -2439,13 +1899,13 @@ static void print_pkt_side_data(AVTextFormatContext *w, { const char *name = av_packet_side_data_name(sd->type); - writer_print_section_header(w, sd, id_data); + avtext_print_section_header(w, 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; - writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1); + avtext_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1); print_int("rotation", rotation); } else if (sd->type == AV_PKT_DATA_STEREO3D) { const AVStereo3D *stereo = (AVStereo3D *)sd->data; @@ -2542,8 +2002,8 @@ static void print_pkt_side_data(AVTextFormatContext *w, } else if (sd->type == AV_PKT_DATA_WEBVTT_IDENTIFIER || sd->type == AV_PKT_DATA_WEBVTT_SETTINGS) { if (do_show_data) - writer_print_data(w, "data", sd->data, sd->size); - writer_print_data_hash(w, "data_hash", sd->data, sd->size); + avtext_print_data(w, "data", sd->data, sd->size); + avtext_print_data_hash(w, "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)); @@ -2641,11 +2101,11 @@ static int show_log(AVTextFormatContext *w, int section_ids, int section_id, int ff_mutex_unlock(&log_mutex); return 0; } - writer_print_section_header(w, NULL, section_ids); + avtext_print_section_header(w, NULL, section_ids); for (i=0; i<log_buffer_size; i++) { if (log_buffer[i].log_level <= log_level) { - writer_print_section_header(w, NULL, section_id); + avtext_print_section_header(w, NULL, section_id); print_str("context", log_buffer[i].context_name); print_int("level", log_buffer[i].log_level); print_int("category", log_buffer[i].category); @@ -2657,27 +2117,26 @@ static int show_log(AVTextFormatContext *w, int section_ids, int section_id, int print_str_opt("parent_category", "N/A"); } print_str("message", log_buffer[i].log_message); - writer_print_section_footer(w); + avtext_print_section_footer(w); } } clear_log(0); ff_mutex_unlock(&log_mutex); - writer_print_section_footer(w); + avtext_print_section_footer(w); return 0; } 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; AVBPrint pbuf; const char *s; av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED); - writer_print_section_header(w, NULL, SECTION_ID_PACKET); + avtext_print_section_header(w, NULL, SECTION_ID_PACKET); s = av_get_media_type_string(st->codecpar->codec_type); if (s) print_str ("codec_type", s); @@ -2696,8 +2155,8 @@ static void show_packet(AVTextFormatContext *w, InputFile *ifile, AVPacket *pkt, pkt->flags & AV_PKT_FLAG_DISCARD ? 'D' : '_', pkt->flags & AV_PKT_FLAG_CORRUPT ? 'C' : '_'); if (do_show_data) - writer_print_data(w, "data", pkt->data, pkt->size); - writer_print_data_hash(w, "data_hash", pkt->data, pkt->size); + avtext_print_data(w, "data", pkt->data, pkt->size); + avtext_print_data_hash(w, "data_hash", pkt->data, pkt->size); if (pkt->side_data_elems) { size_t size; @@ -2711,16 +2170,16 @@ static void show_packet(AVTextFormatContext *w, InputFile *ifile, AVPacket *pkt, av_dict_free(&dict); } - writer_print_section_header(w, NULL, SECTION_ID_PACKET_SIDE_DATA_LIST); + avtext_print_section_header(w, NULL, SECTION_ID_PACKET_SIDE_DATA_LIST); for (int i = 0; i < pkt->side_data_elems; i++) { print_pkt_side_data(w, st->codecpar, &pkt->side_data[i], SECTION_ID_PACKET_SIDE_DATA); - writer_print_section_footer(w); + avtext_print_section_footer(w); } - writer_print_section_footer(w); + avtext_print_section_footer(w); } - writer_print_section_footer(w); + avtext_print_section_footer(w); av_bprint_finalize(&pbuf, NULL); fflush(stdout); @@ -2733,7 +2192,7 @@ static void show_subtitle(AVTextFormatContext *w, AVSubtitle *sub, AVStream *str av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED); - writer_print_section_header(w, NULL, SECTION_ID_SUBTITLE); + avtext_print_section_header(w, NULL, SECTION_ID_SUBTITLE); print_str ("media_type", "subtitle"); print_ts ("pts", sub->pts); @@ -2743,7 +2202,7 @@ static void show_subtitle(AVTextFormatContext *w, AVSubtitle *sub, AVStream *str print_int ("end_display_time", sub->end_display_time); print_int ("num_rects", sub->num_rects); - writer_print_section_footer(w); + avtext_print_section_footer(w); av_bprint_finalize(&pbuf, NULL); fflush(stdout); @@ -2753,20 +2212,20 @@ static void print_frame_side_data(AVTextFormatContext *w, const AVFrame *frame, const AVStream *stream) { - writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_LIST); + avtext_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_LIST); for (int i = 0; i < frame->nb_side_data; i++) { const AVFrameSideData *sd = frame->side_data[i]; const char *name; - writer_print_section_header(w, sd, SECTION_ID_FRAME_SIDE_DATA); + avtext_print_section_header(w, sd, SECTION_ID_FRAME_SIDE_DATA); 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; - writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1); + avtext_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1); print_int("rotation", rotation); } else if (sd->type == AV_FRAME_DATA_AFD && sd->size > 0) { print_int("active_format", *sd->data); @@ -2777,15 +2236,15 @@ static void print_frame_side_data(AVTextFormatContext *w, } else if (sd->type == AV_FRAME_DATA_S12M_TIMECODE && sd->size == 16) { uint32_t *tc = (uint32_t*)sd->data; int m = FFMIN(tc[0],3); - writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST); + avtext_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST); for (int j = 1; j <= m ; j++) { char tcbuf[AV_TIMECODE_STR_SIZE]; av_timecode_make_smpte_tc_string2(tcbuf, stream->avg_frame_rate, tc[j], 0, 0); - writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_TIMECODE); + avtext_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_TIMECODE); print_str("value", tcbuf); - writer_print_section_footer(w); + avtext_print_section_footer(w); } - writer_print_section_footer(w); + avtext_print_section_footer(w); } else if (sd->type == AV_FRAME_DATA_MASTERING_DISPLAY_METADATA) { AVMasteringDisplayMetadata *metadata = (AVMasteringDisplayMetadata *)sd->data; @@ -2830,9 +2289,9 @@ static void print_frame_side_data(AVTextFormatContext *w, } else if (sd->type == AV_FRAME_DATA_VIEW_ID) { print_int("view_id", *(int*)sd->data); } - writer_print_section_footer(w); + avtext_print_section_footer(w); } - writer_print_section_footer(w); + avtext_print_section_footer(w); } static void show_frame(AVTextFormatContext *w, AVFrame *frame, AVStream *stream, @@ -2845,7 +2304,7 @@ static void show_frame(AVTextFormatContext *w, AVFrame *frame, AVStream *stream, av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED); - writer_print_section_header(w, NULL, SECTION_ID_FRAME); + avtext_print_section_header(w, NULL, SECTION_ID_FRAME); s = av_get_media_type_string(stream->codecpar->codec_type); if (s) print_str ("media_type", s); @@ -2917,7 +2376,7 @@ static void show_frame(AVTextFormatContext *w, AVFrame *frame, AVStream *stream, if (frame->nb_side_data) print_frame_side_data(w, frame, stream); - writer_print_section_footer(w); + avtext_print_section_footer(w); av_bprint_finalize(&pbuf, NULL); fflush(stdout); @@ -3167,14 +2626,14 @@ static int read_packets(AVTextFormatContext *w, InputFile *ifile) static void print_dispositions(AVTextFormatContext *w, uint32_t disposition, SectionID section_id) { - writer_print_section_header(w, NULL, section_id); + avtext_print_section_header(w, NULL, section_id); for (int i = 0; i < sizeof(disposition) * CHAR_BIT; i++) { const char *disposition_str = av_disposition_to_string(1U << i); if (disposition_str) print_int(disposition_str, !!(disposition & (1U << i))); } - writer_print_section_footer(w); + avtext_print_section_footer(w); } #define IN_PROGRAM 1 @@ -3212,7 +2671,7 @@ static int show_stream(AVTextFormatContext *w, AVFormatContext *fmt_ctx, int str av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED); - writer_print_section_header(w, NULL, section_header[container]); + avtext_print_section_header(w, NULL, section_header[container]); print_int("index", stream->index); @@ -3366,12 +2825,12 @@ static int show_stream(AVTextFormatContext *w, AVFormatContext *fmt_ctx, int str if (nb_streams_packets[stream_idx]) print_fmt ("nb_read_packets", "%"PRIu64, nb_streams_packets[stream_idx]); else print_str_opt("nb_read_packets", "N/A"); if (do_show_data) - writer_print_data(w, "extradata", par->extradata, + avtext_print_data(w, "extradata", par->extradata, par->extradata_size); if (par->extradata_size > 0) { print_int("extradata_size", par->extradata_size); - writer_print_data_hash(w, "extradata_hash", par->extradata, + avtext_print_data_hash(w, "extradata_hash", par->extradata, par->extradata_size); } @@ -3387,16 +2846,16 @@ static int show_stream(AVTextFormatContext *w, AVFormatContext *fmt_ctx, int str } if (stream->codecpar->nb_coded_side_data) { - writer_print_section_header(w, NULL, SECTION_ID_STREAM_SIDE_DATA_LIST); + avtext_print_section_header(w, NULL, SECTION_ID_STREAM_SIDE_DATA_LIST); for (int i = 0; i < stream->codecpar->nb_coded_side_data; i++) { print_pkt_side_data(w, stream->codecpar, &stream->codecpar->coded_side_data[i], SECTION_ID_STREAM_SIDE_DATA); - writer_print_section_footer(w); + avtext_print_section_footer(w); } - writer_print_section_footer(w); + avtext_print_section_footer(w); } - writer_print_section_footer(w); + avtext_print_section_footer(w); av_bprint_finalize(&pbuf, NULL); fflush(stdout); @@ -3408,14 +2867,14 @@ static int show_streams(AVTextFormatContext *w, InputFile *ifile) AVFormatContext *fmt_ctx = ifile->fmt_ctx; int i, ret = 0; - writer_print_section_header(w, NULL, SECTION_ID_STREAMS); + avtext_print_section_header(w, NULL, SECTION_ID_STREAMS); for (i = 0; i < ifile->nb_streams; i++) if (selected_streams[i]) { ret = show_stream(w, fmt_ctx, i, &ifile->streams[i], 0); if (ret < 0) break; } - writer_print_section_footer(w); + avtext_print_section_footer(w); return ret; } @@ -3425,7 +2884,7 @@ static int show_program(AVTextFormatContext *w, InputFile *ifile, AVProgram *pro AVFormatContext *fmt_ctx = ifile->fmt_ctx; int i, ret = 0; - writer_print_section_header(w, NULL, SECTION_ID_PROGRAM); + avtext_print_section_header(w, NULL, SECTION_ID_PROGRAM); print_int("program_id", program->id); print_int("program_num", program->program_num); print_int("nb_streams", program->nb_stream_indexes); @@ -3436,7 +2895,7 @@ static int show_program(AVTextFormatContext *w, InputFile *ifile, AVProgram *pro if (ret < 0) goto end; - writer_print_section_header(w, NULL, SECTION_ID_PROGRAM_STREAMS); + avtext_print_section_header(w, NULL, SECTION_ID_PROGRAM_STREAMS); for (i = 0; i < program->nb_stream_indexes; i++) { if (selected_streams[program->stream_index[i]]) { ret = show_stream(w, fmt_ctx, program->stream_index[i], &ifile->streams[program->stream_index[i]], IN_PROGRAM); @@ -3444,10 +2903,10 @@ static int show_program(AVTextFormatContext *w, InputFile *ifile, AVProgram *pro break; } } - writer_print_section_footer(w); + avtext_print_section_footer(w); end: - writer_print_section_footer(w); + avtext_print_section_footer(w); return ret; } @@ -3456,7 +2915,7 @@ static int show_programs(AVTextFormatContext *w, InputFile *ifile) AVFormatContext *fmt_ctx = ifile->fmt_ctx; int i, ret = 0; - writer_print_section_header(w, NULL, SECTION_ID_PROGRAMS); + avtext_print_section_header(w, NULL, SECTION_ID_PROGRAMS); for (i = 0; i < fmt_ctx->nb_programs; i++) { AVProgram *program = fmt_ctx->programs[i]; if (!program) @@ -3465,14 +2924,14 @@ static int show_programs(AVTextFormatContext *w, InputFile *ifile) if (ret < 0) break; } - writer_print_section_footer(w); + avtext_print_section_footer(w); return ret; } 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); + avtext_print_section_header(w, stg, SECTION_ID_STREAM_GROUP_COMPONENT); print_int("nb_tiles", tile_grid->nb_tiles); print_int("coded_width", tile_grid->coded_width); print_int("coded_height", tile_grid->coded_height); @@ -3480,16 +2939,16 @@ static void print_tile_grid_params(AVTextFormatContext *w, const AVStreamGroup * print_int("vertical_offset", tile_grid->vertical_offset); print_int("width", tile_grid->width); print_int("height", tile_grid->height); - writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_SUBCOMPONENTS); + avtext_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_SUBCOMPONENTS); for (int i = 0; i < tile_grid->nb_tiles; i++) { - writer_print_section_header(w, "tile_offset", SECTION_ID_STREAM_GROUP_SUBCOMPONENT); + avtext_print_section_header(w, "tile_offset", SECTION_ID_STREAM_GROUP_SUBCOMPONENT); print_int("stream_index", tile_grid->offsets[i].idx); print_int("tile_horizontal_offset", tile_grid->offsets[i].horizontal); print_int("tile_vertical_offset", tile_grid->offsets[i].vertical); - writer_print_section_footer(w); + avtext_print_section_footer(w); } - writer_print_section_footer(w); - writer_print_section_footer(w); + avtext_print_section_footer(w); + avtext_print_section_footer(w); } static void print_iamf_param_definition(AVTextFormatContext *w, const char *name, @@ -3500,7 +2959,7 @@ static void print_iamf_param_definition(AVTextFormatContext *w, const char *name av_assert0(subsection_id != -1); parameter_section_id = sections[subsection_id].children_ids[0]; av_assert0(parameter_section_id != -1); - writer_print_section_header(w, "IAMF Param Definition", section_id); + avtext_print_section_header(w, "IAMF Param Definition", section_id); print_str("name", name); print_int("nb_subblocks", param->nb_subblocks); print_int("type", param->type); @@ -3509,56 +2968,56 @@ static void print_iamf_param_definition(AVTextFormatContext *w, const char *name print_int("duration", param->duration); print_int("constant_subblock_duration", param->constant_subblock_duration); if (param->nb_subblocks > 0) - writer_print_section_header(w, NULL, subsection_id); + avtext_print_section_header(w, NULL, subsection_id); for (int i = 0; i < param->nb_subblocks; i++) { const void *subblock = av_iamf_param_definition_get_subblock(param, i); switch(param->type) { case AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN: { const AVIAMFMixGain *mix = subblock; - writer_print_section_header(w, "IAMF Mix Gain Parameters", parameter_section_id); + avtext_print_section_header(w, "IAMF Mix Gain Parameters", parameter_section_id); print_int("subblock_duration", mix->subblock_duration); print_int("animation_type", mix->animation_type); print_q("start_point_value", mix->start_point_value, '/'); print_q("end_point_value", mix->end_point_value, '/'); print_q("control_point_value", mix->control_point_value, '/'); print_q("control_point_relative_time", mix->control_point_relative_time, '/'); - writer_print_section_footer(w); // parameter_section_id + avtext_print_section_footer(w); // parameter_section_id break; } case AV_IAMF_PARAMETER_DEFINITION_DEMIXING: { const AVIAMFDemixingInfo *demix = subblock; - writer_print_section_header(w, "IAMF Demixing Info", parameter_section_id); + avtext_print_section_header(w, "IAMF Demixing Info", parameter_section_id); print_int("subblock_duration", demix->subblock_duration); print_int("dmixp_mode", demix->dmixp_mode); - writer_print_section_footer(w); // parameter_section_id + avtext_print_section_footer(w); // parameter_section_id break; } case AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN: { const AVIAMFReconGain *recon = subblock; - writer_print_section_header(w, "IAMF Recon Gain", parameter_section_id); + avtext_print_section_header(w, "IAMF Recon Gain", parameter_section_id); print_int("subblock_duration", recon->subblock_duration); - writer_print_section_footer(w); // parameter_section_id + avtext_print_section_footer(w); // parameter_section_id break; } } } if (param->nb_subblocks > 0) - writer_print_section_footer(w); // subsection_id - writer_print_section_footer(w); // section_id + avtext_print_section_footer(w); // subsection_id + avtext_print_section_footer(w); // section_id } 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); + avtext_print_section_header(w, stg, SECTION_ID_STREAM_GROUP_COMPONENT); print_int("nb_layers", audio_element->nb_layers); print_int("audio_element_type", audio_element->audio_element_type); print_int("default_w", audio_element->default_w); - writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_SUBCOMPONENTS); + avtext_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_SUBCOMPONENTS); for (int i = 0; i < audio_element->nb_layers; i++) { const AVIAMFLayer *layer = audio_element->layers[i]; char val_str[128]; - writer_print_section_header(w, "IAMF Audio Layer", SECTION_ID_STREAM_GROUP_SUBCOMPONENT); + avtext_print_section_header(w, "IAMF Audio Layer", SECTION_ID_STREAM_GROUP_SUBCOMPONENT); av_channel_layout_describe(&layer->ch_layout, val_str, sizeof(val_str)); print_str("channel_layout", val_str); if (audio_element->audio_element_type == AV_IAMF_AUDIO_ELEMENT_TYPE_CHANNEL) { @@ -3566,7 +3025,7 @@ static void print_iamf_audio_element_params(AVTextFormatContext *w, const AVStre print_q("output_gain", layer->output_gain, '/'); } else if (audio_element->audio_element_type == AV_IAMF_AUDIO_ELEMENT_TYPE_SCENE) print_int("ambisonics_mode", layer->ambisonics_mode); - writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_SUBCOMPONENT + avtext_print_section_footer(w); // SECTION_ID_STREAM_GROUP_SUBCOMPONENT } if (audio_element->demixing_info) print_iamf_param_definition(w, "demixing_info", audio_element->demixing_info, @@ -3574,36 +3033,36 @@ static void print_iamf_audio_element_params(AVTextFormatContext *w, const AVStre if (audio_element->recon_gain_info) print_iamf_param_definition(w, "recon_gain_info", audio_element->recon_gain_info, SECTION_ID_STREAM_GROUP_SUBCOMPONENT); - writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_SUBCOMPONENTS - writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_COMPONENT + avtext_print_section_footer(w); // SECTION_ID_STREAM_GROUP_SUBCOMPONENTS + avtext_print_section_footer(w); // SECTION_ID_STREAM_GROUP_COMPONENT } static void print_iamf_submix_params(AVTextFormatContext *w, const AVIAMFSubmix *submix) { - writer_print_section_header(w, "IAMF Submix", SECTION_ID_STREAM_GROUP_SUBCOMPONENT); + avtext_print_section_header(w, "IAMF Submix", SECTION_ID_STREAM_GROUP_SUBCOMPONENT); print_int("nb_elements", submix->nb_elements); print_int("nb_layouts", submix->nb_layouts); print_q("default_mix_gain", submix->default_mix_gain, '/'); - writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_PIECES); + avtext_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_PIECES); for (int i = 0; i < submix->nb_elements; i++) { const AVIAMFSubmixElement *element = submix->elements[i]; - writer_print_section_header(w, "IAMF Submix Element", SECTION_ID_STREAM_GROUP_PIECE); + avtext_print_section_header(w, "IAMF Submix Element", SECTION_ID_STREAM_GROUP_PIECE); print_int("stream_id", element->audio_element_id); print_q("default_mix_gain", element->default_mix_gain, '/'); print_int("headphones_rendering_mode", element->headphones_rendering_mode); - writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_SUBPIECES); + avtext_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_SUBPIECES); if (element->annotations) { const AVDictionaryEntry *annotation = NULL; - writer_print_section_header(w, "IAMF Annotations", SECTION_ID_STREAM_GROUP_SUBPIECE); + avtext_print_section_header(w, "IAMF Annotations", SECTION_ID_STREAM_GROUP_SUBPIECE); while (annotation = av_dict_iterate(element->annotations, annotation)) print_str(annotation->key, annotation->value); - writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_SUBPIECE + avtext_print_section_footer(w); // SECTION_ID_STREAM_GROUP_SUBPIECE } if (element->element_mix_config) print_iamf_param_definition(w, "element_mix_config", element->element_mix_config, SECTION_ID_STREAM_GROUP_SUBPIECE); - writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_SUBPIECES - writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_PIECE + avtext_print_section_footer(w); // SECTION_ID_STREAM_GROUP_SUBPIECES + avtext_print_section_footer(w); // SECTION_ID_STREAM_GROUP_PIECE } if (submix->output_mix_config) print_iamf_param_definition(w, "output_mix_config", submix->output_mix_config, @@ -3611,7 +3070,7 @@ static void print_iamf_submix_params(AVTextFormatContext *w, const AVIAMFSubmix for (int i = 0; i < submix->nb_layouts; i++) { const AVIAMFSubmixLayout *layout = submix->layouts[i]; char val_str[128]; - writer_print_section_header(w, "IAMF Submix Layout", SECTION_ID_STREAM_GROUP_PIECE); + avtext_print_section_header(w, "IAMF Submix Layout", SECTION_ID_STREAM_GROUP_PIECE); av_channel_layout_describe(&layout->sound_system, val_str, sizeof(val_str)); print_str("sound_system", val_str); print_q("integrated_loudness", layout->integrated_loudness, '/'); @@ -3619,41 +3078,41 @@ static void print_iamf_submix_params(AVTextFormatContext *w, const AVIAMFSubmix print_q("true_peak", layout->true_peak, '/'); print_q("dialogue_anchored_loudness", layout->dialogue_anchored_loudness, '/'); print_q("album_anchored_loudness", layout->album_anchored_loudness, '/'); - writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_PIECE + avtext_print_section_footer(w); // SECTION_ID_STREAM_GROUP_PIECE } - writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_PIECES - writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_SUBCOMPONENT + avtext_print_section_footer(w); // SECTION_ID_STREAM_GROUP_PIECES + avtext_print_section_footer(w); // SECTION_ID_STREAM_GROUP_SUBCOMPONENT } 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); + avtext_print_section_header(w, stg, SECTION_ID_STREAM_GROUP_COMPONENT); print_int("nb_submixes", mix_presentation->nb_submixes); - writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_SUBCOMPONENTS); + avtext_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_SUBCOMPONENTS); if (mix_presentation->annotations) { const AVDictionaryEntry *annotation = NULL; - writer_print_section_header(w, "IAMF Annotations", SECTION_ID_STREAM_GROUP_SUBCOMPONENT); + avtext_print_section_header(w, "IAMF Annotations", SECTION_ID_STREAM_GROUP_SUBCOMPONENT); while (annotation = av_dict_iterate(mix_presentation->annotations, annotation)) print_str(annotation->key, annotation->value); - writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_SUBCOMPONENT + avtext_print_section_footer(w); // SECTION_ID_STREAM_GROUP_SUBCOMPONENT } for (int i = 0; i < mix_presentation->nb_submixes; i++) print_iamf_submix_params(w, mix_presentation->submixes[i]); - writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_SUBCOMPONENTS - writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_COMPONENT + avtext_print_section_footer(w); // SECTION_ID_STREAM_GROUP_SUBCOMPONENTS + avtext_print_section_footer(w); // SECTION_ID_STREAM_GROUP_COMPONENT } static void print_stream_group_params(AVTextFormatContext *w, AVStreamGroup *stg) { - writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_COMPONENTS); + avtext_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_COMPONENTS); if (stg->type == AV_STREAM_GROUP_PARAMS_TILE_GRID) print_tile_grid_params(w, stg, stg->params.tile_grid); else if (stg->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT) print_iamf_audio_element_params(w, stg, stg->params.iamf_audio_element); else if (stg->type == AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION) print_iamf_mix_presentation_params(w, stg, stg->params.iamf_mix_presentation); - writer_print_section_footer(w); // SECTION_ID_STREAM_GROUP_COMPONENTS + avtext_print_section_footer(w); // SECTION_ID_STREAM_GROUP_COMPONENTS } static int show_stream_group(AVTextFormatContext *w, InputFile *ifile, AVStreamGroup *stg) @@ -3663,7 +3122,7 @@ static int show_stream_group(AVTextFormatContext *w, InputFile *ifile, AVStreamG int i, ret = 0; av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED); - writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP); + avtext_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP); print_int("index", stg->index); if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS) print_fmt ("id", "0x%"PRIx64, stg->id); else print_str_opt("id", "N/A"); @@ -3684,7 +3143,7 @@ static int show_stream_group(AVTextFormatContext *w, InputFile *ifile, AVStreamG if (ret < 0) goto end; - writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_STREAMS); + avtext_print_section_header(w, NULL, SECTION_ID_STREAM_GROUP_STREAMS); for (i = 0; i < stg->nb_streams; i++) { if (selected_streams[stg->streams[i]->index]) { ret = show_stream(w, fmt_ctx, stg->streams[i]->index, &ifile->streams[stg->streams[i]->index], IN_STREAM_GROUP); @@ -3692,11 +3151,11 @@ static int show_stream_group(AVTextFormatContext *w, InputFile *ifile, AVStreamG break; } } - writer_print_section_footer(w); + avtext_print_section_footer(w); end: av_bprint_finalize(&pbuf, NULL); - writer_print_section_footer(w); + avtext_print_section_footer(w); return ret; } @@ -3705,7 +3164,7 @@ static int show_stream_groups(AVTextFormatContext *w, InputFile *ifile) AVFormatContext *fmt_ctx = ifile->fmt_ctx; int i, ret = 0; - writer_print_section_header(w, NULL, SECTION_ID_STREAM_GROUPS); + avtext_print_section_header(w, NULL, SECTION_ID_STREAM_GROUPS); for (i = 0; i < fmt_ctx->nb_stream_groups; i++) { AVStreamGroup *stg = fmt_ctx->stream_groups[i]; @@ -3713,7 +3172,7 @@ static int show_stream_groups(AVTextFormatContext *w, InputFile *ifile) if (ret < 0) break; } - writer_print_section_footer(w); + avtext_print_section_footer(w); return ret; } @@ -3722,11 +3181,11 @@ static int show_chapters(AVTextFormatContext *w, InputFile *ifile) AVFormatContext *fmt_ctx = ifile->fmt_ctx; int i, ret = 0; - writer_print_section_header(w, NULL, SECTION_ID_CHAPTERS); + avtext_print_section_header(w, NULL, SECTION_ID_CHAPTERS); for (i = 0; i < fmt_ctx->nb_chapters; i++) { AVChapter *chapter = fmt_ctx->chapters[i]; - writer_print_section_header(w, NULL, SECTION_ID_CHAPTER); + avtext_print_section_header(w, NULL, SECTION_ID_CHAPTER); print_int("id", chapter->id); print_q ("time_base", chapter->time_base, '/'); print_int("start", chapter->start); @@ -3735,9 +3194,9 @@ static int show_chapters(AVTextFormatContext *w, InputFile *ifile) print_time("end_time", chapter->end, &chapter->time_base); if (do_show_chapter_tags) ret = show_tags(w, chapter->metadata, SECTION_ID_CHAPTER_TAGS); - writer_print_section_footer(w); + avtext_print_section_footer(w); } - writer_print_section_footer(w); + avtext_print_section_footer(w); return ret; } @@ -3745,11 +3204,10 @@ static int show_chapters(AVTextFormatContext *w, InputFile *ifile) static int show_format(AVTextFormatContext *w, InputFile *ifile) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; - char val_str[128]; int64_t size = fmt_ctx->pb ? avio_size(fmt_ctx->pb) : -1; int ret = 0; - writer_print_section_header(w, NULL, SECTION_ID_FORMAT); + avtext_print_section_header(w, NULL, SECTION_ID_FORMAT); print_str_validate("filename", fmt_ctx->url); print_int("nb_streams", fmt_ctx->nb_streams); print_int("nb_programs", fmt_ctx->nb_programs); @@ -3769,17 +3227,17 @@ static int show_format(AVTextFormatContext *w, InputFile *ifile) if (do_show_format_tags) ret = show_tags(w, fmt_ctx->metadata, SECTION_ID_FORMAT_TAGS); - writer_print_section_footer(w); + avtext_print_section_footer(w); fflush(stdout); return ret; } static void show_error(AVTextFormatContext *w, int err) { - writer_print_section_header(w, NULL, SECTION_ID_ERROR); + avtext_print_section_header(w, NULL, SECTION_ID_ERROR); print_int("code", err); print_str("string", av_err2str(err)); - writer_print_section_footer(w); + avtext_print_section_footer(w); } static int open_input_file(InputFile *ifile, const char *filename, @@ -3970,10 +3428,10 @@ static int probe_file(AVTextFormatContext *wctx, const char *filename, else // (!do_show_packets && do_show_frames) section_id = SECTION_ID_FRAMES; if (do_show_frames || do_show_packets) - writer_print_section_header(wctx, NULL, section_id); + avtext_print_section_header(wctx, NULL, section_id); ret = read_packets(wctx, &ifile); if (do_show_frames || do_show_packets) - writer_print_section_footer(wctx); + avtext_print_section_footer(wctx); CHECK_END; } @@ -4024,13 +3482,13 @@ static void ffprobe_show_program_version(AVTextFormatContext *w) AVBPrint pbuf; av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED); - writer_print_section_header(w, NULL, SECTION_ID_PROGRAM_VERSION); + avtext_print_section_header(w, NULL, SECTION_ID_PROGRAM_VERSION); print_str("version", FFMPEG_VERSION); print_fmt("copyright", "Copyright (c) %d-%d the FFmpeg developers", program_birth_year, CONFIG_THIS_YEAR); print_str("compiler_ident", CC_IDENT); print_str("configuration", FFMPEG_CONFIGURATION); - writer_print_section_footer(w); + avtext_print_section_footer(w); av_bprint_finalize(&pbuf, NULL); } @@ -4039,20 +3497,20 @@ static void ffprobe_show_program_version(AVTextFormatContext *w) do { \ if (CONFIG_##LIBNAME) { \ unsigned int version = libname##_version(); \ - writer_print_section_header(w, NULL, SECTION_ID_LIBRARY_VERSION); \ + avtext_print_section_header(w, NULL, SECTION_ID_LIBRARY_VERSION); \ print_str("name", "lib" #libname); \ print_int("major", LIB##LIBNAME##_VERSION_MAJOR); \ print_int("minor", LIB##LIBNAME##_VERSION_MINOR); \ print_int("micro", LIB##LIBNAME##_VERSION_MICRO); \ print_int("version", version); \ print_str("ident", LIB##LIBNAME##_IDENT); \ - writer_print_section_footer(w); \ + avtext_print_section_footer(w); \ } \ } while (0) static void ffprobe_show_library_versions(AVTextFormatContext *w) { - writer_print_section_header(w, NULL, SECTION_ID_LIBRARY_VERSIONS); + avtext_print_section_header(w, NULL, SECTION_ID_LIBRARY_VERSIONS); SHOW_LIB_VERSION(avutil, AVUTIL); SHOW_LIB_VERSION(avcodec, AVCODEC); SHOW_LIB_VERSION(avformat, AVFORMAT); @@ -4061,7 +3519,7 @@ static void ffprobe_show_library_versions(AVTextFormatContext *w) SHOW_LIB_VERSION(swscale, SWSCALE); SHOW_LIB_VERSION(swresample, SWRESAMPLE); SHOW_LIB_VERSION(postproc, POSTPROC); - writer_print_section_footer(w); + avtext_print_section_footer(w); } #define PRINT_PIX_FMT_FLAG(flagname, name) \ @@ -4074,9 +3532,9 @@ static void ffprobe_show_pixel_formats(AVTextFormatContext *w) const AVPixFmtDescriptor *pixdesc = NULL; int i, n; - writer_print_section_header(w, NULL, SECTION_ID_PIXEL_FORMATS); + avtext_print_section_header(w, NULL, SECTION_ID_PIXEL_FORMATS); while (pixdesc = av_pix_fmt_desc_next(pixdesc)) { - writer_print_section_header(w, NULL, SECTION_ID_PIXEL_FORMAT); + avtext_print_section_header(w, NULL, SECTION_ID_PIXEL_FORMAT); print_str("name", pixdesc->name); print_int("nb_components", pixdesc->nb_components); if ((pixdesc->nb_components >= 3) && !(pixdesc->flags & AV_PIX_FMT_FLAG_RGB)) { @@ -4090,7 +3548,7 @@ static void ffprobe_show_pixel_formats(AVTextFormatContext *w) if (n) print_int ("bits_per_pixel", n); else print_str_opt("bits_per_pixel", "N/A"); if (do_show_pixel_format_flags) { - writer_print_section_header(w, NULL, SECTION_ID_PIXEL_FORMAT_FLAGS); + avtext_print_section_header(w, NULL, SECTION_ID_PIXEL_FORMAT_FLAGS); PRINT_PIX_FMT_FLAG(BE, "big_endian"); PRINT_PIX_FMT_FLAG(PAL, "palette"); PRINT_PIX_FMT_FLAG(BITSTREAM, "bitstream"); @@ -4098,21 +3556,21 @@ static void ffprobe_show_pixel_formats(AVTextFormatContext *w) PRINT_PIX_FMT_FLAG(PLANAR, "planar"); PRINT_PIX_FMT_FLAG(RGB, "rgb"); PRINT_PIX_FMT_FLAG(ALPHA, "alpha"); - writer_print_section_footer(w); + avtext_print_section_footer(w); } if (do_show_pixel_format_components && (pixdesc->nb_components > 0)) { - writer_print_section_header(w, NULL, SECTION_ID_PIXEL_FORMAT_COMPONENTS); + avtext_print_section_header(w, NULL, SECTION_ID_PIXEL_FORMAT_COMPONENTS); for (i = 0; i < pixdesc->nb_components; i++) { - writer_print_section_header(w, NULL, SECTION_ID_PIXEL_FORMAT_COMPONENT); + avtext_print_section_header(w, NULL, SECTION_ID_PIXEL_FORMAT_COMPONENT); print_int("index", i + 1); print_int("bit_depth", pixdesc->comp[i].depth); - writer_print_section_footer(w); + avtext_print_section_footer(w); } - writer_print_section_footer(w); + avtext_print_section_footer(w); } - writer_print_section_footer(w); + avtext_print_section_footer(w); } - writer_print_section_footer(w); + avtext_print_section_footer(w); } static int opt_show_optional_fields(void *optctx, const char *opt, const char *arg) @@ -4641,21 +4099,6 @@ int main(int argc, char **argv) } w_args = buf; - if (show_data_hash) { - if ((ret = av_hash_alloc(&hash, show_data_hash)) < 0) { - if (ret == AVERROR(EINVAL)) { - const char *n; - av_log(NULL, AV_LOG_ERROR, - "Unknown hash algorithm '%s'\nKnown algorithms:", - show_data_hash); - for (i = 0; (n = av_hash_names(i)); i++) - av_log(NULL, AV_LOG_ERROR, " %s", n); - av_log(NULL, AV_LOG_ERROR, "\n"); - } - goto end; - } - } - w = writer_get_by_name(w_name); if (!w) { av_log(NULL, AV_LOG_ERROR, "Unknown output format with name '%s'\n", w_name); @@ -4663,12 +4106,14 @@ int main(int argc, char **argv) goto end; } - if ((ret = writer_open(&wctx, w, w_args, - sections, FF_ARRAY_ELEMS(sections), output_filename)) >= 0) { + if ((ret = avtext_context_open(&wctx, w, w_args, + sections, FF_ARRAY_ELEMS(sections), output_filename, show_value_unit, + use_value_prefix, use_byte_value_binary_prefix, use_value_sexagesimal_format, + show_optional_fields, show_data_hash)) >= 0) { 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); + avtext_print_section_header(wctx, NULL, SECTION_ID_ROOT); if (do_show_program_version) ffprobe_show_program_version(wctx); @@ -4692,8 +4137,8 @@ int main(int argc, char **argv) input_ret = ret; - writer_print_section_footer(wctx); - ret = writer_close(&wctx); + avtext_print_section_footer(wctx); + ret = avtext_context_close(&wctx); if (ret < 0) av_log(NULL, AV_LOG_ERROR, "Writing output failed: %s\n", av_err2str(ret)); @@ -4706,7 +4151,6 @@ end: av_freep(&input_filename); av_freep(&print_input_filename); av_freep(&read_intervals); - av_hash_freep(&hash); uninit_opts(); for (i = 0; i < FF_ARRAY_ELEMS(sections); i++) diff --git a/libavutil/Makefile b/libavutil/Makefile index ad5aab7d40..78c2c0d707 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -115,6 +115,7 @@ OBJS = adler32.o \ audio_fifo.o \ avstring.o \ avsscanf.o \ + textformat/avtextformat.o \ base64.o \ blowfish.o \ bprint.o \ diff --git a/libavutil/avtextformat.h b/libavutil/avtextformat.h index 1740a73249..e1aa227aff 100644 --- a/libavutil/avtextformat.h +++ b/libavutil/avtextformat.h @@ -28,6 +28,7 @@ #include <libavformat/avio.h> #include "bprint.h" #include "rational.h" +#include "libavutil/hash.h" #define SECTION_MAX_NB_CHILDREN 11 @@ -110,11 +111,60 @@ struct AVTextFormatContext { 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; + int use_byte_value_binary_prefix; + int use_value_sexagesimal_format; + + struct AVHashContext *hash; + int string_validation; char *string_validation_replacement; unsigned int string_validation_utf8_flags; }; +#define SHOW_OPTIONAL_FIELDS_AUTO -1 +#define SHOW_OPTIONAL_FIELDS_NEVER 0 +#define SHOW_OPTIONAL_FIELDS_ALWAYS 1 + +#define PRINT_STRING_OPT 1 +#define PRINT_STRING_VALIDATE 2 + +int avtext_context_open(AVTextFormatContext **pwctx, const AVTextFormatter *writer, const char *args, + const struct AVTextFormatSection *sections, int nb_sections, + const char *output_filename, + int show_value_unit, + int use_value_prefix, + int use_byte_value_binary_prefix, + int use_value_sexagesimal_format, + int show_optional_fields, + char *show_data_hash); + +int avtext_context_close(AVTextFormatContext **wctx); + + +void avtext_print_section_header(AVTextFormatContext *wctx, const void *data, int section_id); + +void avtext_print_section_footer(AVTextFormatContext *wctx); + +void avtext_print_integer(AVTextFormatContext *wctx, const char *key, int64_t val); + +int avtext_print_string(AVTextFormatContext *wctx, const char *key, const char *val, int flags); + +void avtext_print_unit_int(AVTextFormatContext *wctx, const char *key, int value, const char *unit); + +void avtext_print_rational(AVTextFormatContext *wctx, const char *key, AVRational q, char sep); + +void avtext_print_time(AVTextFormatContext *wctx, const char *key, int64_t ts, const AVRational *time_base, int is_duration); + +void avtext_print_ts(AVTextFormatContext *wctx, const char *key, int64_t ts, int is_duration); + +void avtext_print_data(AVTextFormatContext *wctx, const char *name, const uint8_t *data, int size); + +void avtext_print_data_hash(AVTextFormatContext *wctx, const char *name, const uint8_t *data, int size); +void avtext_print_integers(AVTextFormatContext *wctx, const char *name, uint8_t *data, int size, + const char *format, int columns, int bytes, int offset_add); #endif /* AVUTIL_AVTEXTFORMAT_H */ diff --git a/libavutil/textformat/avtextformat.c b/libavutil/textformat/avtextformat.c new file mode 100644 index 0000000000..2b67acae65 --- /dev/null +++ b/libavutil/textformat/avtextformat.c @@ -0,0 +1,620 @@ +/* + * 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 + */ + +#include <limits.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#include "../mem.h" +#include "../avassert.h" +#include "../avtextformat.h" +#include "../bprint.h" +#include "../error.h" +#include "../hash.h" +#include "../intreadwrite.h" +#include "../macros.h" +#include "../opt.h" + +#define SECTION_ID_NONE -1 + +static const struct { + double bin_val; + double dec_val; + const char *bin_str; + const char *dec_str; +} si_prefixes[] = { + { 1.0, 1.0, "", "" }, + { 1.024e3, 1e3, "Ki", "K" }, + { 1.048576e6, 1e6, "Mi", "M" }, + { 1.073741824e9, 1e9, "Gi", "G" }, + { 1.099511627776e12, 1e12, "Ti", "T" }, + { 1.125899906842624e15, 1e15, "Pi", "P" }, +}; + +static const char *avtext_context_get_writer_name(void *p) +{ + AVTextFormatContext *wctx = p; + return wctx->writer->name; +} + +#define OFFSET(x) offsetof(AVTextFormatContext, x) + +static const AVOption textcontext_options[] = { + { "string_validation", "set string validation mode", + OFFSET(string_validation), AV_OPT_TYPE_INT, {.i64=WRITER_STRING_VALIDATION_REPLACE}, 0, WRITER_STRING_VALIDATION_NB-1, .unit = "sv" }, + { "sv", "set string validation mode", + OFFSET(string_validation), AV_OPT_TYPE_INT, {.i64=WRITER_STRING_VALIDATION_REPLACE}, 0, WRITER_STRING_VALIDATION_NB-1, .unit = "sv" }, + { "ignore", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = WRITER_STRING_VALIDATION_IGNORE}, .unit = "sv" }, + { "replace", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = WRITER_STRING_VALIDATION_REPLACE}, .unit = "sv" }, + { "fail", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = WRITER_STRING_VALIDATION_FAIL}, .unit = "sv" }, + { "string_validation_replacement", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, {.str=""}}, + { "svr", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, {.str="\xEF\xBF\xBD"}}, +}; + +static void *trextcontext_child_next(void *obj, void *prev) +{ + AVTextFormatContext *ctx = obj; + if (!prev && ctx->writer && ctx->writer->priv_class && ctx->priv) + return ctx->priv; + return NULL; +} + +static const AVClass textcontext_class = { + .class_name = "AVTextContext", + .item_name = avtext_context_get_writer_name, + .option = textcontext_options, + .version = LIBAVUTIL_VERSION_INT, + .child_next = trextcontext_child_next, +}; + + +static inline void textoutput_w8_avio(AVTextFormatContext *wctx, int b) +{ + avio_w8(wctx->avio, b); +} + +static inline void textoutput_put_str_avio(AVTextFormatContext *wctx, const char *str) +{ + avio_write(wctx->avio, str, strlen(str)); +} + +static inline void textoutput_printf_avio(AVTextFormatContext *wctx, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + avio_vprintf(wctx->avio, fmt, ap); + va_end(ap); +} + +static inline void textoutput_w8_printf(AVTextFormatContext *wctx, int b) +{ + printf("%c", b); +} + +static inline void textoutput_put_str_printf(AVTextFormatContext *wctx, const char *str) +{ + printf("%s", str); +} + +static inline void textoutput_printf_printf(AVTextFormatContext *wctx, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); +} + +static void bprint_bytes(AVBPrint *bp, const uint8_t *ubuf, size_t ubuf_size) +{ + int i; + av_bprintf(bp, "0X"); + for (i = 0; i < ubuf_size; i++) + av_bprintf(bp, "%02X", ubuf[i]); +} + +int avtext_context_close(AVTextFormatContext **pwctx) +{ + AVTextFormatContext *wctx = *pwctx; + int i; + int ret = 0; + + if (!wctx) + return -1; + + av_hash_freep(&wctx->hash); + + if (wctx->writer->uninit) + wctx->writer->uninit(wctx); + for (i = 0; i < SECTION_MAX_NB_LEVELS; i++) + av_bprint_finalize(&wctx->section_pbuf[i], NULL); + if (wctx->writer->priv_class) + av_opt_free(wctx->priv); + av_freep(&wctx->priv); + av_opt_free(wctx); + if (wctx->avio) { + avio_flush(wctx->avio); + ret = avio_close(wctx->avio); + } + av_freep(pwctx); + return ret; +} + + +int avtext_context_open(AVTextFormatContext **pwctx, const AVTextFormatter *writer, const char *args, + const struct AVTextFormatSection *sections, int nb_sections, + const char *output_filename, + int show_value_unit, + int use_value_prefix, + int use_byte_value_binary_prefix, + int use_value_sexagesimal_format, + int show_optional_fields, + char *show_data_hash) +{ + AVTextFormatContext *wctx; + int i, ret = 0; + + if (!(wctx = av_mallocz(sizeof(AVTextFormatContext)))) { + ret = AVERROR(ENOMEM); + goto fail; + } + + if (!(wctx->priv = av_mallocz(writer->priv_size))) { + ret = AVERROR(ENOMEM); + goto fail; + } + + wctx->show_value_unit = show_value_unit; + wctx->use_value_prefix = use_value_prefix; + 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; + + wctx->class = &textcontext_class; + wctx->writer = writer; + wctx->level = -1; + wctx->sections = sections; + wctx->nb_sections = nb_sections; + + av_opt_set_defaults(wctx); + + if (writer->priv_class) { + void *priv_ctx = wctx->priv; + *(const AVClass **)priv_ctx = writer->priv_class; + av_opt_set_defaults(priv_ctx); + } + + /* convert options to dictionary */ + if (args) { + AVDictionary *opts = NULL; + const AVDictionaryEntry *opt = NULL; + + if ((ret = av_dict_parse_string(&opts, args, "=", ":", 0)) < 0) { + av_log(wctx, AV_LOG_ERROR, "Failed to parse option string '%s' provided to writer context\n", args); + av_dict_free(&opts); + goto fail; + } + + while ((opt = av_dict_iterate(opts, opt))) { + if ((ret = av_opt_set(wctx, opt->key, opt->value, AV_OPT_SEARCH_CHILDREN)) < 0) { + av_log(wctx, AV_LOG_ERROR, "Failed to set option '%s' with value '%s' provided to writer context\n", + opt->key, opt->value); + av_dict_free(&opts); + goto fail; + } + } + + av_dict_free(&opts); + } + + if (show_data_hash) { + if ((ret = av_hash_alloc(&wctx->hash, show_data_hash)) < 0) { + if (ret == AVERROR(EINVAL)) { + const char *n; + av_log(NULL, AV_LOG_ERROR, "Unknown hash algorithm '%s'\nKnown algorithms:", show_data_hash); + for (i = 0; (n = av_hash_names(i)); i++) + av_log(NULL, AV_LOG_ERROR, " %s", n); + av_log(NULL, AV_LOG_ERROR, "\n"); + } + return ret; + } + } + + /* validate replace string */ + { + const uint8_t *p = wctx->string_validation_replacement; + const uint8_t *endp = p + strlen(p); + while (*p) { + const uint8_t *p0 = p; + int32_t code; + ret = av_utf8_decode(&code, &p, endp, wctx->string_validation_utf8_flags); + if (ret < 0) { + AVBPrint bp; + av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC); + bprint_bytes(&bp, p0, p-p0), + av_log(wctx, AV_LOG_ERROR, + "Invalid UTF8 sequence %s found in string validation replace '%s'\n", + bp.str, wctx->string_validation_replacement); + return ret; + } + } + } + + if (!output_filename) { + wctx->writer_w8 = textoutput_w8_printf; + wctx->writer_put_str = textoutput_put_str_printf; + wctx->writer_printf = textoutput_printf_printf; + } else { + if ((ret = avio_open(&wctx->avio, output_filename, AVIO_FLAG_WRITE)) < 0) { + av_log(wctx, AV_LOG_ERROR, + "Failed to open output '%s' with error: %s\n", output_filename, av_err2str(ret)); + goto fail; + } + wctx->writer_w8 = textoutput_w8_avio; + wctx->writer_put_str = textoutput_put_str_avio; + wctx->writer_printf = textoutput_printf_avio; + } + + for (i = 0; i < SECTION_MAX_NB_LEVELS; i++) + av_bprint_init(&wctx->section_pbuf[i], 1, AV_BPRINT_SIZE_UNLIMITED); + + if (wctx->writer->init) + ret = wctx->writer->init(wctx); + if (ret < 0) + goto fail; + + *pwctx = wctx; + + return 0; + +fail: + avtext_context_close(&wctx); + return ret; +} + +/* 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" ; +static const char unit_bit_per_second_str[] = "bit/s"; + + +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; + 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); +} + +void avtext_print_section_footer(AVTextFormatContext *wctx) +{ + int section_id = wctx->section[wctx->level]->id; + 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 (wctx->writer->print_section_footer) + wctx->writer->print_section_footer(wctx); + wctx->level--; +} + +void avtext_print_integer(AVTextFormatContext *wctx, + const char *key, int64_t val) +{ + 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); + wctx->nb_item[wctx->level]++; + } +} + +static inline int validate_string(AVTextFormatContext *wctx, char **dstp, const char *src) +{ + const uint8_t *p, *endp; + AVBPrint dstbuf; + int invalid_chars_nb = 0, ret = 0; + + av_bprint_init(&dstbuf, 0, AV_BPRINT_SIZE_UNLIMITED); + + endp = src + strlen(src); + for (p = src; *p;) { + uint32_t code; + int invalid = 0; + const uint8_t *p0 = p; + + if (av_utf8_decode(&code, &p, endp, wctx->string_validation_utf8_flags) < 0) { + AVBPrint bp; + av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC); + bprint_bytes(&bp, p0, p-p0); + av_log(wctx, AV_LOG_DEBUG, + "Invalid UTF-8 sequence %s found in string '%s'\n", bp.str, src); + invalid = 1; + } + + if (invalid) { + invalid_chars_nb++; + + switch (wctx->string_validation) { + case WRITER_STRING_VALIDATION_FAIL: + av_log(wctx, AV_LOG_ERROR, + "Invalid UTF-8 sequence found in string '%s'\n", src); + ret = AVERROR_INVALIDDATA; + goto end; + break; + + case WRITER_STRING_VALIDATION_REPLACE: + av_bprintf(&dstbuf, "%s", wctx->string_validation_replacement); + break; + } + } + + if (!invalid || wctx->string_validation == WRITER_STRING_VALIDATION_IGNORE) + av_bprint_append_data(&dstbuf, p0, p-p0); + } + + if (invalid_chars_nb && wctx->string_validation == WRITER_STRING_VALIDATION_REPLACE) { + av_log(wctx, AV_LOG_WARNING, + "%d invalid UTF-8 sequence(s) found in string '%s', replaced with '%s'\n", + invalid_chars_nb, src, wctx->string_validation_replacement); + } + +end: + av_bprint_finalize(&dstbuf, dstp); + return ret; +} + +struct unit_value { + union { double d; int64_t i; } val; + const char *unit; +}; + +static char *value_string(AVTextFormatContext *wctx, char *buf, int buf_size, struct unit_value uv) +{ + double vald; + int64_t vali; + int show_float = 0; + + if (uv.unit == unit_second_str) { + vald = uv.val.d; + show_float = 1; + } else { + vald = vali = uv.val.i; + } + + if (uv.unit == unit_second_str && wctx->use_value_sexagesimal_format) { + double secs; + int hours, mins; + secs = vald; + mins = (int)secs / 60; + secs = secs - mins * 60; + hours = mins / 60; + mins %= 60; + snprintf(buf, buf_size, "%d:%02d:%09.6f", hours, mins, secs); + } else { + const char *prefix_string = ""; + + if (wctx->use_value_prefix && vald > 1) { + int64_t index; + + if (uv.unit == unit_byte_str && wctx->use_byte_value_binary_prefix) { + index = (int64_t) (log2(vald)) / 10; + index = av_clip(index, 0, FF_ARRAY_ELEMS(si_prefixes) - 1); + vald /= si_prefixes[index].bin_val; + prefix_string = si_prefixes[index].bin_str; + } else { + index = (int64_t) (log10(vald)) / 3; + index = av_clip(index, 0, FF_ARRAY_ELEMS(si_prefixes) - 1); + vald /= si_prefixes[index].dec_val; + prefix_string = si_prefixes[index].dec_str; + } + vali = vald; + } + + if (show_float || (wctx->use_value_prefix && vald != (int64_t)vald)) + snprintf(buf, buf_size, "%f", vald); + else + snprintf(buf, buf_size, "%"PRId64, vali); + av_strlcatf(buf, buf_size, "%s%s%s", *prefix_string || wctx->show_value_unit ? " " : "", + prefix_string, wctx->show_value_unit ? uv.unit : ""); + } + + return buf; +} + + +void avtext_print_unit_int(AVTextFormatContext *wctx, const char *key, int value, const char *unit) +{ + char val_str[128]; + struct unit_value uv; + uv.val.i = value; + uv.unit = unit; + avtext_print_string(wctx, key, value_string(wctx, val_str, sizeof(val_str), uv), 0); +} + + +int avtext_print_string(AVTextFormatContext *wctx, const char *key, const char *val, int flags) +{ + const struct AVTextFormatSection *section = wctx->section[wctx->level]; + int ret = 0; + + 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))) + return 0; + + if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) { + if (flags & PRINT_STRING_VALIDATE) { + char *key1 = NULL, *val1 = NULL; + ret = validate_string(wctx, &key1, key); + if (ret < 0) goto end; + ret = validate_string(wctx, &val1, val); + if (ret < 0) goto end; + wctx->writer->print_string(wctx, key1, val1); + end: + if (ret < 0) { + av_log(wctx, AV_LOG_ERROR, + "Invalid key=value string combination %s=%s in section %s\n", + key, val, section->unique_name); + } + av_free(key1); + av_free(val1); + } else { + wctx->writer->print_string(wctx, key, val); + } + + wctx->nb_item[wctx->level]++; + } + + return ret; +} + +void avtext_print_rational(AVTextFormatContext *wctx, + const char *key, AVRational q, char sep) +{ + AVBPrint buf; + av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC); + av_bprintf(&buf, "%d%c%d", q.num, sep, q.den); + avtext_print_string(wctx, key, buf.str, 0); +} + +void avtext_print_time(AVTextFormatContext *wctx, const char *key, + int64_t ts, const AVRational *time_base, int is_duration) +{ + char buf[128]; + + if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) { + avtext_print_string(wctx, key, "N/A", PRINT_STRING_OPT); + } else { + double d = ts * av_q2d(*time_base); + struct unit_value uv; + uv.val.d = d; + uv.unit = unit_second_str; + value_string(wctx, buf, sizeof(buf), uv); + avtext_print_string(wctx, key, buf, 0); + } +} + +void avtext_print_ts(AVTextFormatContext *wctx, const char *key, int64_t ts, int is_duration) +{ + if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) { + avtext_print_string(wctx, key, "N/A", PRINT_STRING_OPT); + } else { + avtext_print_integer(wctx, key, ts); + } +} + +void avtext_print_data(AVTextFormatContext *wctx, const char *name, + const uint8_t *data, int size) +{ + AVBPrint bp; + int offset = 0, l, i; + + av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED); + av_bprintf(&bp, "\n"); + while (size) { + av_bprintf(&bp, "%08x: ", offset); + l = FFMIN(size, 16); + for (i = 0; i < l; i++) { + av_bprintf(&bp, "%02x", data[i]); + if (i & 1) + av_bprintf(&bp, " "); + } + av_bprint_chars(&bp, ' ', 41 - 2 * i - i / 2); + for (i = 0; i < l; i++) + av_bprint_chars(&bp, data[i] - 32U < 95 ? data[i] : '.', 1); + av_bprintf(&bp, "\n"); + offset += l; + data += l; + size -= l; + } + avtext_print_string(wctx, name, bp.str, 0); + av_bprint_finalize(&bp, NULL); +} + +void avtext_print_data_hash(AVTextFormatContext *wctx, const char *name, + const uint8_t *data, int size) +{ + char *p, buf[AV_HASH_MAX_SIZE * 2 + 64] = { 0 }; + + if (!wctx->hash) + return; + av_hash_init(wctx->hash); + av_hash_update(wctx->hash, data, size); + snprintf(buf, sizeof(buf), "%s:", av_hash_get_name(wctx->hash)); + p = buf + strlen(buf); + av_hash_final_hex(wctx->hash, p, buf + sizeof(buf) - p); + avtext_print_string(wctx, name, buf, 0); +} + +void avtext_print_integers(AVTextFormatContext *wctx, const char *name, + uint8_t *data, int size, const char *format, + int columns, int bytes, int offset_add) +{ + AVBPrint bp; + int offset = 0, l, i; + + 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(wctx, name, bp.str, 0); + av_bprint_finalize(&bp, NULL); +} -- 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 ` softworkz [this message] 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=89d538cab47c517b35ecaccb563e14334c9f9927.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