FFmpeg
Loading...
Searching...
No Matches
avtextformat.c
Go to the documentation of this file.
1/*
2 * Copyright (c) The FFmpeg developers
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <inttypes.h>
22#include <limits.h>
23#include <math.h>
24#include <stdarg.h>
25#include <stdio.h>
26#include <string.h>
27
28#include "libavutil/mem.h"
29#include "libavutil/avassert.h"
30#include "libavutil/avutil.h"
31#include "libavutil/base64.h"
32#include "libavutil/bprint.h"
33#include "libavutil/common.h"
34#include "libavutil/error.h"
35#include "libavutil/hash.h"
36#include "libavutil/internal.h"
37#include "libavutil/macros.h"
38#include "libavutil/opt.h"
39#include "avtextformat.h"
40
41#define SECTION_ID_NONE (-1)
42
43#define SHOW_OPTIONAL_FIELDS_AUTO (-1)
44#define SHOW_OPTIONAL_FIELDS_NEVER 0
45#define SHOW_OPTIONAL_FIELDS_ALWAYS 1
46
47static const struct {
48 double bin_val;
49 double dec_val;
50 char bin_str[4];
51 char dec_str[4];
52} si_prefixes[] = {
53 { 1.0, 1.0, "", "" },
54 { 1.024e3, 1e3, "Ki", "K" },
55 { 1.048576e6, 1e6, "Mi", "M" },
56 { 1.073741824e9, 1e9, "Gi", "G" },
57 { 1.099511627776e12, 1e12, "Ti", "T" },
58 { 1.125899906842624e15, 1e15, "Pi", "P" },
59};
60
61static const char *textcontext_get_formatter_name(void *p)
62{
63 AVTextFormatContext *tctx = p;
64 return tctx->formatter->name;
65}
66
67#define OFFSET(x) offsetof(AVTextFormatContext, x)
68
69static const AVOption textcontext_options[] = {
70 { "string_validation", "set string validation mode",
71 OFFSET(string_validation), AV_OPT_TYPE_INT, { .i64 = AV_TEXTFORMAT_STRING_VALIDATION_REPLACE }, 0, AV_TEXTFORMAT_STRING_VALIDATION_NB - 1, .unit = "sv" },
72 { "sv", "set string validation mode",
73 OFFSET(string_validation), AV_OPT_TYPE_INT, { .i64 = AV_TEXTFORMAT_STRING_VALIDATION_REPLACE }, 0, AV_TEXTFORMAT_STRING_VALIDATION_NB - 1, .unit = "sv" },
74 { "ignore", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_TEXTFORMAT_STRING_VALIDATION_IGNORE }, .unit = "sv" },
75 { "replace", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_TEXTFORMAT_STRING_VALIDATION_REPLACE }, .unit = "sv" },
76 { "fail", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_TEXTFORMAT_STRING_VALIDATION_FAIL }, .unit = "sv" },
77 { "string_validation_replacement", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, { .str = "" } },
78 { "svr", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, { .str = "\xEF\xBF\xBD" } },
79 { NULL }
80};
81
82static void *textcontext_child_next(void *obj, void *prev)
83{
85 if (!prev && ctx->formatter && ctx->formatter->priv_class && ctx->priv)
86 return ctx->priv;
87 return NULL;
88}
89
90static const AVClass textcontext_class = {
91 .class_name = "AVTextContext",
93 .option = textcontext_options,
94 .version = LIBAVUTIL_VERSION_INT,
95 .child_next = textcontext_child_next,
96};
97
98static void bprint_bytes(AVBPrint *bp, const uint8_t *ubuf, size_t ubuf_size)
99{
100 av_bprintf(bp, "0X");
101 for (unsigned i = 0; i < ubuf_size; i++)
102 av_bprintf(bp, "%02X", ubuf[i]);
103}
104
106{
107 AVTextFormatContext *tctx = *ptctx;
108 int ret = 0;
109
110 if (!tctx)
111 return AVERROR(EINVAL);
112
113 av_hash_freep(&tctx->hash);
114
115 if (tctx->formatter) {
116 if (tctx->formatter->uninit)
117 ret = tctx->formatter->uninit(tctx);
118 if (tctx->formatter->priv_class)
119 av_opt_free(tctx->priv);
120 }
121 for (int i = 0; i < SECTION_MAX_NB_LEVELS; i++)
123 av_freep(&tctx->priv);
124 av_opt_free(tctx);
125 av_freep(ptctx);
126 return ret;
127}
128
129
130int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *formatter, AVTextWriterContext *writer_context, const char *args,
132{
134 int ret = 0;
135
136 av_assert0(ptctx && formatter);
137
138 if (!(tctx = av_mallocz(sizeof(AVTextFormatContext)))) {
139 ret = AVERROR(ENOMEM);
140 goto fail;
141 }
142
143 for (int i = 0; i < SECTION_MAX_NB_LEVELS; i++)
145
146 tctx->class = &textcontext_class;
148
149 if (!(tctx->priv = av_mallocz(formatter->priv_size))) {
150 ret = AVERROR(ENOMEM);
151 goto fail;
152 }
153
154 tctx->opts = options;
155
156 if (nb_sections > SECTION_MAX_NB_SECTIONS) {
157 av_log(tctx, AV_LOG_ERROR, "The number of section definitions (%d) is larger than the maximum allowed (%d)\n", nb_sections, SECTION_MAX_NB_SECTIONS);
158 ret = AVERROR(EINVAL);
159 goto fail;
160 }
161
162 tctx->formatter = formatter;
163 tctx->level = -1;
164 tctx->sections = sections;
165 tctx->nb_sections = nb_sections;
166 tctx->writer = writer_context;
167
168 if (formatter->priv_class) {
169 void *priv_ctx = tctx->priv;
170 *(const AVClass **)priv_ctx = formatter->priv_class;
171 av_opt_set_defaults(priv_ctx);
172 }
173
174 /* convert options to dictionary */
175 if (args) {
177 const AVDictionaryEntry *opt = NULL;
178
179 if ((ret = av_dict_parse_string(&opts, args, "=", ":", 0)) < 0) {
180 av_log(tctx, AV_LOG_ERROR, "Failed to parse option string '%s' provided to textformat context\n", args);
182 goto fail;
183 }
184
185 while ((opt = av_dict_iterate(opts, opt))) {
186 if ((ret = av_opt_set(tctx, opt->key, opt->value, AV_OPT_SEARCH_CHILDREN)) < 0) {
187 av_log(tctx, AV_LOG_ERROR, "Failed to set option '%s' with value '%s' provided to textformat context\n",
188 opt->key, opt->value);
190 goto fail;
191 }
192 }
193
195 }
196
197 if (show_data_hash) {
198 if ((ret = av_hash_alloc(&tctx->hash, show_data_hash)) < 0) {
199 if (ret == AVERROR(EINVAL)) {
200 const char *n;
201 av_log(NULL, AV_LOG_ERROR, "Unknown hash algorithm '%s'\nKnown algorithms:", show_data_hash);
202 for (unsigned i = 0; (n = av_hash_names(i)); i++)
203 av_log(NULL, AV_LOG_ERROR, " %s", n);
204 av_log(NULL, AV_LOG_ERROR, "\n");
205 }
206 goto fail;
207 }
208 }
209
210 /* validate replace string */
211 {
212 const uint8_t *p = (uint8_t *)tctx->string_validation_replacement;
213 const uint8_t *endp = p + strlen((const char *)p);
214 while (*p) {
215 const uint8_t *p0 = p;
217 ret = av_utf8_decode(&code, &p, endp, tctx->string_validation_utf8_flags);
218 if (ret < 0) {
219 AVBPrint bp;
221 bprint_bytes(&bp, p0, p - p0);
222 av_log(tctx, AV_LOG_ERROR,
223 "Invalid UTF8 sequence %s found in string validation replace '%s'\n",
224 bp.str, tctx->string_validation_replacement);
225 goto fail;
226 }
227 }
228 }
229
230 if (tctx->formatter->init)
231 ret = tctx->formatter->init(tctx);
232 if (ret < 0)
233 goto fail;
234
235 *ptctx = tctx;
236
237 return 0;
238
239fail:
241 return ret;
242}
243
244static const char unit_second_str[] = "s";
245
246void avtext_print_section_header(AVTextFormatContext *tctx, const void *data, int section_id)
247{
248 if (section_id < 0 || section_id >= tctx->nb_sections) {
249 av_log(tctx, AV_LOG_ERROR, "Invalid section_id for section_header: %d\n", section_id);
250 return;
251 }
252
253 tctx->level++;
255
256 tctx->nb_item[tctx->level] = 0;
257 memset(tctx->nb_item_type[tctx->level], 0, sizeof(tctx->nb_item_type[tctx->level]));
258 tctx->section[tctx->level] = &tctx->sections[section_id];
259
261 tctx->formatter->print_section_header(tctx, data);
262}
263
265{
266 if (tctx->level < 0 || tctx->level >= SECTION_MAX_NB_LEVELS) {
267 av_log(tctx, AV_LOG_ERROR, "Invalid level for section_footer: %d\n", tctx->level);
268 return;
269 }
270
271 int section_id = tctx->section[tctx->level]->id;
272 int parent_section_id = tctx->level ?
273 tctx->section[tctx->level - 1]->id : SECTION_ID_NONE;
274
275 if (parent_section_id != SECTION_ID_NONE) {
276 tctx->nb_item[tctx->level - 1]++;
277 tctx->nb_item_type[tctx->level - 1][section_id]++;
278 }
279
281 tctx->formatter->print_section_footer(tctx);
282 tctx->level--;
283}
284
286{
287 av_assert0(tctx);
288
290 return;
291
295 return;
296
297 av_assert0(key && tctx->level >= 0 && tctx->level < SECTION_MAX_NB_LEVELS);
298
299 if (!tctx->opts.is_key_selected || tctx->opts.is_key_selected(tctx, key)) {
300 tctx->formatter->print_integer(tctx, key, val);
301 tctx->nb_item[tctx->level]++;
302 }
303}
304
305static inline int validate_string(AVTextFormatContext *tctx, char **dstp, const char *src)
306{
307 const uint8_t *p, *endp, *srcp = (const uint8_t *)src;
308 AVBPrint dstbuf;
309 AVBPrint invalid_seq;
310 int invalid_chars_nb = 0, ret = 0;
311
312 *dstp = NULL;
315
316 endp = srcp + strlen(src);
317 for (p = srcp; *p;) {
319 int invalid = 0;
320 const uint8_t *p0 = p;
321
322 if (av_utf8_decode(&code, &p, endp, tctx->string_validation_utf8_flags) < 0) {
323
324 av_bprint_clear(&invalid_seq);
325
326 bprint_bytes(&invalid_seq, p0, p - p0);
327
328 av_log(tctx, AV_LOG_DEBUG, "Invalid UTF-8 sequence '%s' found in string '%s'\n", invalid_seq.str, src);
329 invalid = 1;
330 }
331
332 if (invalid) {
333 invalid_chars_nb++;
334
335 switch (tctx->string_validation) {
337 av_log(tctx, AV_LOG_ERROR, "Invalid UTF-8 sequence found in string '%s'\n", src);
339 goto end;
340
342 av_bprintf(&dstbuf, "%s", tctx->string_validation_replacement);
343 break;
344 }
345 }
346
348 av_bprint_append_data(&dstbuf, p0, p-p0);
349 }
350
351 if (invalid_chars_nb && tctx->string_validation == AV_TEXTFORMAT_STRING_VALIDATION_REPLACE)
353 "%d invalid UTF-8 sequence(s) found in string '%s', replaced with '%s'\n",
354 invalid_chars_nb, src, tctx->string_validation_replacement);
355
356end:
357 av_bprint_finalize(&dstbuf, dstp);
358 av_bprint_finalize(&invalid_seq, NULL);
359 return ret;
360}
361
363 union {
364 double d;
367
369 const char *unit;
370};
371
372static const char float_fmt_full[] = "%f";
373static const char float_fmt_singledigit[] = "%.1f";
374static char *value_string(const AVTextFormatContext *tctx, char *buf, int buf_size, struct unit_value uv)
375{
376 double vald;
377 int64_t vali = 0;
378 const char *float_fmt = 0;
379
381 vald = 20 * log10(uv.val.d);
382 float_fmt = float_fmt_singledigit;
383 } else if (uv.fmt >= AV_TEXTFORMAT_VALUE_FMT_DOUBLE) {
384 vald = uv.val.d;
385 float_fmt = float_fmt_full;
386 } else {
387 vald = (double)uv.val.i;
388 vali = uv.val.i;
389 }
390
392 double secs;
393 int hours, mins;
394 secs = vald;
395 mins = (int)secs / 60;
396 secs = secs - mins * 60;
397 hours = mins / 60;
398 mins %= 60;
399 snprintf(buf, buf_size, "%d:%02d:%09.6f", hours, mins, secs);
400 } else {
401 const char *prefix_string = "";
402
403 if (tctx->opts.use_value_prefix && vald > 1) {
405
407 index = (int64_t)(log2(vald) / 10);
409 vald /= si_prefixes[index].bin_val;
410 prefix_string = si_prefixes[index].bin_str;
411 } else {
412 index = (int64_t)(log10(vald) / 3);
414 vald /= si_prefixes[index].dec_val;
415 prefix_string = si_prefixes[index].dec_str;
416 }
417 vali = (int64_t)vald;
418 }
419
420 if (float_fmt || (tctx->opts.use_value_prefix && vald != (int64_t)vald))
421 snprintf(buf, buf_size, float_fmt ? float_fmt : "%f", vald);
422 else
423 snprintf(buf, buf_size, "%"PRId64, vali);
424
425 av_strlcatf(buf, buf_size, "%s%s%s", *prefix_string || tctx->opts.show_value_unit && uv.unit && *uv.unit ? " " : "",
426 prefix_string, tctx->opts.show_value_unit && uv.unit ? uv.unit : "");
427 }
428
429 return buf;
430}
431
432
434{
435 char val_str[128];
436 struct unit_value uv;
437
439
440 uv.val.i = val;
441 uv.fmt = fmt;
442 uv.unit = unit;
443 avtext_print_string(tctx, key, value_string(tctx, val_str, sizeof(val_str), uv), 0);
444}
445
446
448{
449 char val_str[128];
450 struct unit_value uv;
451
453
454 uv.val.d = val;
455 uv.fmt = fmt;
456 uv.unit = unit;
457 avtext_print_string(tctx, key, value_string(tctx, val_str, sizeof(val_str), uv), 0);
458}
459
460int avtext_print_string(AVTextFormatContext *tctx, const char *key, const char *val, int flags)
461{
462 const AVTextFormatSection *section;
463 int ret = 0;
464
465 av_assert0(key && val && tctx->level >= 0 && tctx->level < SECTION_MAX_NB_LEVELS);
466
467 section = tctx->section[tctx->level];
468
470 return 0;
471
475 return 0;
476
477 if (!tctx->opts.is_key_selected || tctx->opts.is_key_selected(tctx, key)) {
479 char *key1 = NULL, *val1 = NULL;
480 ret = validate_string(tctx, &key1, key);
481 if (ret < 0) goto end;
482 ret = validate_string(tctx, &val1, val);
483 if (ret < 0) goto end;
484 tctx->formatter->print_string(tctx, key1, val1);
485 end:
486 if (ret < 0)
487 av_log(tctx, AV_LOG_ERROR,
488 "Invalid key=value string combination %s=%s in section %s\n",
489 key, val, section->unique_name);
490 av_free(key1);
491 av_free(val1);
492 } else {
493 tctx->formatter->print_string(tctx, key, val);
494 }
495
496 tctx->nb_item[tctx->level]++;
497 }
498
499 return ret;
500}
501
502void avtext_print_rational(AVTextFormatContext *tctx, const char *key, AVRational q, char sep)
503{
504 char buf[44];
505 snprintf(buf, sizeof(buf), "%d%c%d", q.num, sep, q.den);
506 avtext_print_string(tctx, key, buf, 0);
507}
508
510 int64_t ts, const AVRational *time_base, int is_duration)
511{
512 if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) {
514 } else {
515 char buf[128];
516 double d = av_q2d(*time_base) * ts;
517 struct unit_value uv;
518 uv.val.d = d;
521 value_string(tctx, buf, sizeof(buf), uv);
522 avtext_print_string(tctx, key, buf, 0);
523 }
524}
525
526void avtext_print_ts(AVTextFormatContext *tctx, const char *key, int64_t ts, int is_duration)
527{
528 if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0))
530 else
531 avtext_print_integer(tctx, key, ts, 0);
532}
533
534static void print_data_xxd(AVBPrint *bp, const uint8_t *data, int size)
535{
536 unsigned offset = 0;
537 int i;
538
539 av_bprintf(bp, "\n");
540 while (size) {
541 av_bprintf(bp, "%08x: ", offset);
542 int l = FFMIN(size, 16);
543 for (i = 0; i < l; i++) {
544 av_bprintf(bp, "%02x", data[i]);
545 if (i & 1)
546 av_bprintf(bp, " ");
547 }
548 av_bprint_chars(bp, ' ', 41 - 2 * i - i / 2);
549 for (i = 0; i < l; i++)
550 av_bprint_chars(bp, data[i] - 32U < 95 ? data[i] : '.', 1);
551 av_bprintf(bp, "\n");
552 offset += l;
553 data += l;
554 size -= l;
555 }
556}
557
558static void print_data_base64(AVBPrint *bp, const uint8_t *data, int size)
559{
560 char buf[AV_BASE64_SIZE(60)];
561
562 av_bprintf(bp, "\n");
563 while (size) {
564 int l = FFMIN(size, 60);
565 av_base64_encode(buf, sizeof(buf), data, l);
566 av_bprintf(bp, "%s\n", buf);
567 data += l;
568 size -= l;
569 }
570}
572 const uint8_t *data, int size)
573{
574 AVBPrint bp;
576 switch (tctx->opts.data_dump_format) {
578 print_data_xxd(&bp, data, size);
579 break;
582 break;
583 default:
584 av_unreachable("Invalid data dump type");
585 }
586 avtext_print_string(tctx, key, bp.str, 0);
588}
589
591 const uint8_t *data, int size)
592{
593 char buf[AV_HASH_MAX_SIZE * 2 + 64] = { 0 };
594 int len;
595
596 if (!tctx->hash)
597 return;
598
599 av_hash_init(tctx->hash);
600 av_hash_update(tctx->hash, data, size);
601 len = snprintf(buf, sizeof(buf), "%s:", av_hash_get_name(tctx->hash));
602 av_hash_final_hex(tctx->hash, (uint8_t *)&buf[len], (int)sizeof(buf) - len);
603 avtext_print_string(tctx, key, buf, 0);
604}
605
606static const char *writercontext_get_writer_name(void *p)
607{
608 AVTextWriterContext *wctx = p;
609 return wctx->writer->name;
610}
611
612static void *writercontext_child_next(void *obj, void *prev)
613{
615 if (!prev && ctx->formatter && ctx->formatter->priv_class && ctx->priv)
616 return ctx->priv;
617 return NULL;
618}
619
620static const AVClass textwriter_class = {
621 .class_name = "AVTextWriterContext",
623 .version = LIBAVUTIL_VERSION_INT,
624 .child_next = writercontext_child_next,
625};
626
627
629{
630 AVTextWriterContext *wctx = *pwctx;
631 int ret = 0;
632
633 if (!wctx)
634 return AVERROR(EINVAL);
635
636 if (wctx->writer) {
637 if (wctx->writer->uninit)
638 ret = wctx->writer->uninit(wctx);
639 if (wctx->writer->priv_class)
640 av_opt_free(wctx->priv);
641 }
642 av_freep(&wctx->priv);
643 av_freep(pwctx);
644 return ret;
645}
646
647
649{
651 int ret = 0;
652
653 if (!pwctx || !writer)
654 return AVERROR(EINVAL);
655
656 if (!((wctx = av_mallocz(sizeof(AVTextWriterContext))))) {
657 ret = AVERROR(ENOMEM);
658 goto fail;
659 }
660
661 if (writer->priv_size && !((wctx->priv = av_mallocz(writer->priv_size)))) {
662 ret = AVERROR(ENOMEM);
663 goto fail;
664 }
665
666 if (writer->priv_class) {
667 void *priv_ctx = wctx->priv;
668 *(const AVClass **)priv_ctx = writer->priv_class;
669 av_opt_set_defaults(priv_ctx);
670 }
671
672 wctx->class = &textwriter_class;
673 wctx->writer = writer;
674
676
677
678 if (wctx->writer->init)
679 ret = wctx->writer->init(wctx);
680 if (ret < 0)
681 goto fail;
682
683 *pwctx = wctx;
684
685 return 0;
686
687fail:
689 return ret;
690}
691
705
707{
708 for (int i = 0; registered_formatters[i]; i++) {
709 const char *end;
711 (*end == '\0' || *end == '='))
712 return registered_formatters[i];
713 }
714
715 return NULL;
716}
static double val(void *priv, double ch)
Definition aeval.c:77
#define log2(x)
Definition math.h:26
static AVFormatContext * ctx
static AVDictionary * opts
int32_t
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
Definition avassert.h:109
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition avstring.c:103
static const AVClass textwriter_class
void avtext_print_integer(AVTextFormatContext *tctx, const char *key, int64_t val, int flags)
static void bprint_bytes(AVBPrint *bp, const uint8_t *ubuf, size_t ubuf_size)
char dec_str[4]
static const char unit_second_str[]
static char * value_string(const AVTextFormatContext *tctx, char *buf, int buf_size, struct unit_value uv)
void avtext_print_unit_integer(AVTextFormatContext *tctx, const char *key, int64_t val, AVTextFormatValueFormat fmt, const char *unit)
static const struct @105000147377261105311001355164026305374075040210 si_prefixes[]
static void * writercontext_child_next(void *obj, void *prev)
char bin_str[4]
double dec_val
static const char * writercontext_get_writer_name(void *p)
int avtextwriter_context_open(AVTextWriterContext **pwctx, const AVTextWriter *writer)
void avtext_print_unit_double(AVTextFormatContext *tctx, const char *key, double val, AVTextFormatValueFormat fmt, const char *unit)
int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *formatter, AVTextWriterContext *writer_context, const char *args, const AVTextFormatSection *sections, int nb_sections, AVTextFormatOptions options, char *show_data_hash)
void avtext_print_data(AVTextFormatContext *tctx, const char *key, const uint8_t *data, int size)
int avtext_print_string(AVTextFormatContext *tctx, const char *key, const char *val, int flags)
static const AVClass textcontext_class
static void * textcontext_child_next(void *obj, void *prev)
static void print_data_xxd(AVBPrint *bp, const uint8_t *data, int size)
static const char * textcontext_get_formatter_name(void *p)
int avtext_context_close(AVTextFormatContext **ptctx)
static const AVOption textcontext_options[]
static void print_data_base64(AVBPrint *bp, const uint8_t *data, int size)
void avtext_print_time(AVTextFormatContext *tctx, const char *key, int64_t ts, const AVRational *time_base, int is_duration)
void avtext_print_ts(AVTextFormatContext *tctx, const char *key, int64_t ts, int is_duration)
double bin_val
void avtext_print_data_hash(AVTextFormatContext *tctx, const char *key, const uint8_t *data, int size)
static const AVTextFormatter *const registered_formatters[]
void avtext_print_rational(AVTextFormatContext *tctx, const char *key, AVRational q, char sep)
static const char float_fmt_singledigit[]
void avtext_print_section_header(AVTextFormatContext *tctx, const void *data, int section_id)
#define OFFSET(x)
void avtext_print_section_footer(AVTextFormatContext *tctx)
const AVTextFormatter * avtext_get_formatter_by_name(const char *name)
static const char float_fmt_full[]
static int validate_string(AVTextFormatContext *tctx, char **dstp, const char *src)
int avtextwriter_context_close(AVTextWriterContext **pwctx)
#define SECTION_ID_NONE
const AVTextFormatter avtextformatter_compact
Definition tf_compact.c:257
@ AV_TEXTFORMAT_DATADUMP_BASE64
@ AV_TEXTFORMAT_DATADUMP_XXD
#define AV_TEXTFORMAT_PRINT_STRING_OPTIONAL
#define SECTION_MAX_NB_LEVELS
const AVTextFormatter avtextformatter_ini
Definition tf_ini.c:140
#define AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS
const AVTextFormatter avtextformatter_csv
Definition tf_compact.c:288
#define SECTION_MAX_NB_SECTIONS
AVTextFormatValueFormat
@ AV_TEXTFORMAT_VALUE_FMT_DOUBLE
@ AV_TEXTFORMAT_VALUE_FMT_DECIBEL
@ AV_TEXTFORMAT_VALUE_FMT_SECOND
@ AV_TEXTFORMAT_VALUE_FMT_BYTE
const AVTextFormatter avtextformatter_default
Definition tf_default.c:128
@ AV_TEXTFORMAT_STRING_VALIDATION_NB
@ AV_TEXTFORMAT_STRING_VALIDATION_FAIL
@ AV_TEXTFORMAT_STRING_VALIDATION_IGNORE
@ AV_TEXTFORMAT_STRING_VALIDATION_REPLACE
#define AV_TEXTFORMAT_PRINT_STRING_VALIDATE
const AVTextFormatter avtextformatter_mermaid
Definition tf_mermaid.c:650
const AVTextFormatter avtextformatter_json
Definition tf_json.c:202
const AVTextFormatter avtextformatter_flat
Definition tf_flat.c:150
const AVTextFormatter avtextformatter_mermaidhtml
Definition tf_mermaid.c:664
const AVTextFormatter avtextformatter_xml
Definition tf_xml.c:202
Convenience header that includes libavutil's core.
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition bprint.c:121
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:68
AVBPrint public header.
#define AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_AUTOMATIC
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
common internal and external API header
#define av_clip64
Definition common.h:103
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
error code definitions
const char * key
static char * show_data_hash
Definition ffprobe.c:147
#define SHOW_OPTIONAL_FIELDS_AUTO
Definition ffprobe.c:140
static const AVTextFormatSection sections[]
Definition ffprobe.c:259
#define SHOW_OPTIONAL_FIELDS_NEVER
Definition ffprobe.c:141
#define fail
Definition test.h:479
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition opt.h:275
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c:234
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
Append data to a print buffer.
Definition bprint.c:147
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition bprint.c:129
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
Definition bprint.c:226
char * av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size)
Encode data to base64 and null-terminate.
Definition base64.c:147
#define AV_BASE64_SIZE(x)
Calculate the output size needed to base64-encode x bytes to a null-terminated string.
Definition base64.h:66
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:233
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition dict.c:42
int av_dict_parse_string(AVDictionary **pm, const char *str, const char *key_val_sep, const char *pairs_sep, int flags)
Parse the key/value pairs list and add the parsed entries to a dictionary.
Definition dict.c:210
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
void av_hash_freep(AVHashContext **ctx)
Free hash context and set hash context pointer to NULL.
Definition hash.c:248
void av_hash_final_hex(struct AVHashContext *ctx, uint8_t *dst, int size)
Finalize a hash context and store the hexadecimal representation of the actual hash value as a string...
Definition hash.c:225
void av_hash_init(AVHashContext *ctx)
Initialize or reset a hash context.
Definition hash.c:151
void av_hash_update(AVHashContext *ctx, const uint8_t *src, size_t len)
Update a hash context with additional data.
Definition hash.c:172
int av_hash_alloc(AVHashContext **ctx, const char *name)
Allocate a hash context for the algorithm specified by name.
Definition hash.c:114
const char * av_hash_names(int i)
Get the names of available hash algorithms.
Definition hash.c:98
#define AV_HASH_MAX_SIZE
Maximum value that av_hash_get_size() will currently return.
Definition hash.h:156
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition avstring.c:36
int av_utf8_decode(int32_t *codep, const uint8_t **bufp, const uint8_t *buf_end, unsigned int flags)
Read and decode a single UTF-8 code point (character) from the buffer in *buf, and update *buf to poi...
Definition avstring.c:364
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
#define AV_OPT_SEARCH_CHILDREN
Search in possible children of the given object first.
Definition opt.h:604
void av_opt_free(void *obj)
Free all allocated objects in obj.
Definition opt.c:2029
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
Definition opt.c:1758
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition opt.c:891
int index
Definition gxfenc.c:90
const char * av_hash_get_name(const AVHashContext *ctx)
Definition hash.c:104
Generic hashing API.
unsigned offset
Definition libaomenc.c:763
common internal API header
Utility Preprocessor macros.
#define FFMIN(a, b)
Definition macros.h:49
Memory handling functions.
static const char * obj
Definition mscl.c:57
const char data[16]
Definition mxf.c:149
AVOptions.
const char * name
Definition qsvenc.c:142
#define FF_ARRAY_ELEMS(a)
const uint8_t * code
Definition spdifenc.c:433
Describe the class of an AVClass context structure.
Definition log.h:76
char * key
Definition dict.h:91
char * value
Definition dict.h:92
AVOption.
Definition opt.h:428
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
unsigned int nb_item_type[SECTION_MAX_NB_LEVELS][SECTION_MAX_NB_SECTIONS]
struct AVHashContext * hash
void * priv
private data for use by the filter
const AVClass * class
class of the formatter
const AVTextFormatSection * section[SECTION_MAX_NB_LEVELS]
section per each level
AVTextFormatOptions opts
char * string_validation_replacement
int level
current level, starting from 0
unsigned int nb_item[SECTION_MAX_NB_LEVELS]
number of the item printed in the given section, starting from 0
unsigned int string_validation_utf8_flags
AVTextWriterContext * writer
the AVTextWriterContext
AVBPrint section_pbuf[SECTION_MAX_NB_LEVELS]
generic print buffer dedicated to each section, used by various formatters
const AVTextFormatSection * sections
array containing all sections
const AVTextFormatter * formatter
the AVTextFormatter of which this is an instance
int nb_sections
number of sections
int(* is_key_selected)(struct AVTextFormatContext *tctx, const char *key)
Callback to discard certain elements based upon the key used.
AVTextFormatDataDump data_dump_format
const char * unique_name
unique section name, in case the name is ambiguous
int id
unique id identifying a section
int(* uninit)(AVTextFormatContext *tctx)
int priv_size
private size for the formatter context
int flags
a combination or AV_TEXTFORMAT__FLAG_*
void(* print_string)(AVTextFormatContext *tctx, const char *, const char *)
void(* print_section_header)(AVTextFormatContext *tctx, const void *data)
const AVClass * priv_class
private class of the formatter, if any
const char * name
void(* print_integer)(AVTextFormatContext *tctx, const char *, int64_t)
void(* print_section_footer)(AVTextFormatContext *tctx)
int(* init)(AVTextFormatContext *tctx)
void * priv
private data for use by the writer
const AVTextWriter * writer
const AVClass * class
class of the writer
const char * name
int priv_size
private size for the writer private class
int(* uninit)(AVTextWriterContext *wctx)
int(* init)(AVTextWriterContext *wctx)
const AVClass * priv_class
private class of the writer, if any
const char * unit
union unit_value::@153353126176234320255222000327105263006301132050 val
AVTextFormatValueFormat fmt
#define av_free(p)
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
int size
int len