FFmpeg
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 <limits.h>
22 #include <stdarg.h>
23 #include <stdint.h>
24 #include <stdio.h>
25 #include <string.h>
26 
27 #include "libavutil/mem.h"
28 #include "libavutil/avassert.h"
29 #include "libavutil/bprint.h"
30 #include "libavutil/error.h"
31 #include "libavutil/hash.h"
32 #include "libavutil/intreadwrite.h"
33 #include "libavutil/macros.h"
34 #include "libavutil/opt.h"
35 #include "avtextformat.h"
36 
37 #define SECTION_ID_NONE (-1)
38 
39 #define SHOW_OPTIONAL_FIELDS_AUTO (-1)
40 #define SHOW_OPTIONAL_FIELDS_NEVER 0
41 #define SHOW_OPTIONAL_FIELDS_ALWAYS 1
42 
43 static const struct {
44  double bin_val;
45  double dec_val;
46  char bin_str[4];
47  char dec_str[4];
48 } si_prefixes[] = {
49  { 1.0, 1.0, "", "" },
50  { 1.024e3, 1e3, "Ki", "K" },
51  { 1.048576e6, 1e6, "Mi", "M" },
52  { 1.073741824e9, 1e9, "Gi", "G" },
53  { 1.099511627776e12, 1e12, "Ti", "T" },
54  { 1.125899906842624e15, 1e15, "Pi", "P" },
55 };
56 
57 static const char *textcontext_get_formatter_name(void *p)
58 {
59  AVTextFormatContext *tctx = p;
60  return tctx->formatter->name;
61 }
62 
63 #define OFFSET(x) offsetof(AVTextFormatContext, x)
64 
65 static const AVOption textcontext_options[] = {
66  { "string_validation", "set string validation mode",
67  OFFSET(string_validation), AV_OPT_TYPE_INT, { .i64 = AV_TEXTFORMAT_STRING_VALIDATION_REPLACE }, 0, AV_TEXTFORMAT_STRING_VALIDATION_NB - 1, .unit = "sv" },
68  { "sv", "set string validation mode",
69  OFFSET(string_validation), AV_OPT_TYPE_INT, { .i64 = AV_TEXTFORMAT_STRING_VALIDATION_REPLACE }, 0, AV_TEXTFORMAT_STRING_VALIDATION_NB - 1, .unit = "sv" },
70  { "ignore", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_TEXTFORMAT_STRING_VALIDATION_IGNORE }, .unit = "sv" },
71  { "replace", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_TEXTFORMAT_STRING_VALIDATION_REPLACE }, .unit = "sv" },
72  { "fail", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_TEXTFORMAT_STRING_VALIDATION_FAIL }, .unit = "sv" },
73  { "string_validation_replacement", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, { .str = "" } },
74  { "svr", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, { .str = "\xEF\xBF\xBD" } },
75  { NULL }
76 };
77 
78 static void *textcontext_child_next(void *obj, void *prev)
79 {
80  AVTextFormatContext *ctx = obj;
81  if (!prev && ctx->formatter && ctx->formatter->priv_class && ctx->priv)
82  return ctx->priv;
83  return NULL;
84 }
85 
86 static const AVClass textcontext_class = {
87  .class_name = "AVTextContext",
88  .item_name = textcontext_get_formatter_name,
89  .option = textcontext_options,
90  .version = LIBAVUTIL_VERSION_INT,
91  .child_next = textcontext_child_next,
92 };
93 
94 static void bprint_bytes(AVBPrint *bp, const uint8_t *ubuf, size_t ubuf_size)
95 {
96  av_bprintf(bp, "0X");
97  for (unsigned i = 0; i < ubuf_size; i++)
98  av_bprintf(bp, "%02X", ubuf[i]);
99 }
100 
102 {
103  AVTextFormatContext *tctx = *ptctx;
104  int ret = 0;
105 
106  if (!tctx)
107  return AVERROR(EINVAL);
108 
109  av_hash_freep(&tctx->hash);
110 
111  if (tctx->formatter) {
112  if (tctx->formatter->uninit)
113  ret = tctx->formatter->uninit(tctx);
114  if (tctx->formatter->priv_class)
115  av_opt_free(tctx->priv);
116  }
117  for (int i = 0; i < SECTION_MAX_NB_LEVELS; i++)
119  av_freep(&tctx->priv);
120  av_opt_free(tctx);
121  av_freep(ptctx);
122  return ret;
123 }
124 
125 
126 int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *formatter, AVTextWriterContext *writer_context, const char *args,
128 {
129  AVTextFormatContext *tctx;
130  int ret = 0;
131 
132  av_assert0(ptctx && formatter);
133 
134  if (!(tctx = av_mallocz(sizeof(AVTextFormatContext)))) {
135  ret = AVERROR(ENOMEM);
136  goto fail;
137  }
138 
139  for (int i = 0; i < SECTION_MAX_NB_LEVELS; i++)
141 
142  tctx->class = &textcontext_class;
143  av_opt_set_defaults(tctx);
144 
145  if (!(tctx->priv = av_mallocz(formatter->priv_size))) {
146  ret = AVERROR(ENOMEM);
147  goto fail;
148  }
149 
150  tctx->show_value_unit = options.show_value_unit;
151  tctx->use_value_prefix = options.use_value_prefix;
152  tctx->use_byte_value_binary_prefix = options.use_byte_value_binary_prefix;
153  tctx->use_value_sexagesimal_format = options.use_value_sexagesimal_format;
154  tctx->show_optional_fields = options.show_optional_fields;
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);
181  av_dict_free(&opts);
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);
189  av_dict_free(&opts);
190  goto fail;
191  }
192  }
193 
194  av_dict_free(&opts);
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;
216  int32_t code;
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 
239 fail:
240  avtext_context_close(&tctx);
241  return ret;
242 }
243 
244 /* Temporary definitions during refactoring */
245 static const char unit_second_str[] = "s";
246 static const char unit_hertz_str[] = "Hz";
247 static const char unit_byte_str[] = "byte";
248 static const char unit_bit_per_second_str[] = "bit/s";
249 
250 
251 void avtext_print_section_header(AVTextFormatContext *tctx, const void *data, int section_id)
252 {
253  if (section_id < 0 || section_id >= tctx->nb_sections) {
254  av_log(tctx, AV_LOG_ERROR, "Invalid section_id for section_header: %d\n", section_id);
255  return;
256  }
257 
258  tctx->level++;
260 
261  tctx->nb_item[tctx->level] = 0;
262  memset(tctx->nb_item_type[tctx->level], 0, sizeof(tctx->nb_item_type[tctx->level]));
263  tctx->section[tctx->level] = &tctx->sections[section_id];
264 
265  if (tctx->formatter->print_section_header)
266  tctx->formatter->print_section_header(tctx, data);
267 }
268 
270 {
271  if (tctx->level < 0 || tctx->level >= SECTION_MAX_NB_LEVELS) {
272  av_log(tctx, AV_LOG_ERROR, "Invalid level for section_footer: %d\n", tctx->level);
273  return;
274  }
275 
276  int section_id = tctx->section[tctx->level]->id;
277  int parent_section_id = tctx->level ?
278  tctx->section[tctx->level - 1]->id : SECTION_ID_NONE;
279 
280  if (parent_section_id != SECTION_ID_NONE) {
281  tctx->nb_item[tctx->level - 1]++;
282  tctx->nb_item_type[tctx->level - 1][section_id]++;
283  }
284 
285  if (tctx->formatter->print_section_footer)
286  tctx->formatter->print_section_footer(tctx);
287  tctx->level--;
288 }
289 
291 {
292  const AVTextFormatSection *section;
293 
294  av_assert0(tctx);
295 
297  return;
298 
302  return;
303 
304  av_assert0(key && tctx->level >= 0 && tctx->level < SECTION_MAX_NB_LEVELS);
305 
306  section = tctx->section[tctx->level];
307 
308  if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) {
309  tctx->formatter->print_integer(tctx, key, val);
310  tctx->nb_item[tctx->level]++;
311  }
312 }
313 
314 static inline int validate_string(AVTextFormatContext *tctx, char **dstp, const char *src)
315 {
316  const uint8_t *p, *endp, *srcp = (const uint8_t *)src;
317  AVBPrint dstbuf;
318  AVBPrint invalid_seq;
319  int invalid_chars_nb = 0, ret = 0;
320 
321  *dstp = NULL;
323  av_bprint_init(&invalid_seq, 0, AV_BPRINT_SIZE_UNLIMITED);
324 
325  endp = srcp + strlen(src);
326  for (p = srcp; *p;) {
327  int32_t code;
328  int invalid = 0;
329  const uint8_t *p0 = p;
330 
331  if (av_utf8_decode(&code, &p, endp, tctx->string_validation_utf8_flags) < 0) {
332 
333  av_bprint_clear(&invalid_seq);
334 
335  bprint_bytes(&invalid_seq, p0, p - p0);
336 
337  av_log(tctx, AV_LOG_DEBUG, "Invalid UTF-8 sequence '%s' found in string '%s'\n", invalid_seq.str, src);
338  invalid = 1;
339  }
340 
341  if (invalid) {
342  invalid_chars_nb++;
343 
344  switch (tctx->string_validation) {
346  av_log(tctx, AV_LOG_ERROR, "Invalid UTF-8 sequence found in string '%s'\n", src);
348  goto end;
349 
351  av_bprintf(&dstbuf, "%s", tctx->string_validation_replacement);
352  break;
353  }
354  }
355 
357  av_bprint_append_data(&dstbuf, p0, p-p0);
358  }
359 
360  if (invalid_chars_nb && tctx->string_validation == AV_TEXTFORMAT_STRING_VALIDATION_REPLACE)
361  av_log(tctx, AV_LOG_WARNING,
362  "%d invalid UTF-8 sequence(s) found in string '%s', replaced with '%s'\n",
363  invalid_chars_nb, src, tctx->string_validation_replacement);
364 
365 end:
366  av_bprint_finalize(&dstbuf, dstp);
367  av_bprint_finalize(&invalid_seq, NULL);
368  return ret;
369 }
370 
371 struct unit_value {
372  union {
373  double d;
375  } val;
376 
377  const char *unit;
378 };
379 
380 static char *value_string(const AVTextFormatContext *tctx, char *buf, int buf_size, struct unit_value uv)
381 {
382  double vald;
383  int64_t vali = 0;
384  int show_float = 0;
385 
386  if (uv.unit == unit_second_str) {
387  vald = uv.val.d;
388  show_float = 1;
389  } else {
390  vald = (double)uv.val.i;
391  vali = uv.val.i;
392  }
393 
395  double secs;
396  int hours, mins;
397  secs = vald;
398  mins = (int)secs / 60;
399  secs = secs - mins * 60;
400  hours = mins / 60;
401  mins %= 60;
402  snprintf(buf, buf_size, "%d:%02d:%09.6f", hours, mins, secs);
403  } else {
404  const char *prefix_string = "";
405 
406  if (tctx->use_value_prefix && vald > 1) {
407  int64_t index;
408 
409  if (uv.unit == unit_byte_str && tctx->use_byte_value_binary_prefix) {
410  index = (int64_t)(log2(vald) / 10);
412  vald /= si_prefixes[index].bin_val;
413  prefix_string = si_prefixes[index].bin_str;
414  } else {
415  index = (int64_t)(log10(vald) / 3);
417  vald /= si_prefixes[index].dec_val;
418  prefix_string = si_prefixes[index].dec_str;
419  }
420  vali = (int64_t)vald;
421  }
422 
423  if (show_float || (tctx->use_value_prefix && vald != (int64_t)vald))
424  snprintf(buf, buf_size, "%f", vald);
425  else
426  snprintf(buf, buf_size, "%"PRId64, vali);
427 
428  av_strlcatf(buf, buf_size, "%s%s%s", *prefix_string || tctx->show_value_unit ? " " : "",
429  prefix_string, tctx->show_value_unit ? uv.unit : "");
430  }
431 
432  return buf;
433 }
434 
435 
436 void avtext_print_unit_integer(AVTextFormatContext *tctx, const char *key, int64_t val, const char *unit)
437 {
438  char val_str[128];
439  struct unit_value uv;
440  uv.val.i = val;
441  uv.unit = unit;
442  avtext_print_string(tctx, key, value_string(tctx, val_str, sizeof(val_str), uv), 0);
443 }
444 
445 
446 int avtext_print_string(AVTextFormatContext *tctx, const char *key, const char *val, int flags)
447 {
448  const AVTextFormatSection *section;
449  int ret = 0;
450 
451  av_assert0(key && val && tctx->level >= 0 && tctx->level < SECTION_MAX_NB_LEVELS);
452 
453  section = tctx->section[tctx->level];
454 
456  return 0;
457 
461  return 0;
462 
463  if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) {
465  char *key1 = NULL, *val1 = NULL;
466  ret = validate_string(tctx, &key1, key);
467  if (ret < 0) goto end;
468  ret = validate_string(tctx, &val1, val);
469  if (ret < 0) goto end;
470  tctx->formatter->print_string(tctx, key1, val1);
471  end:
472  if (ret < 0)
473  av_log(tctx, AV_LOG_ERROR,
474  "Invalid key=value string combination %s=%s in section %s\n",
475  key, val, section->unique_name);
476  av_free(key1);
477  av_free(val1);
478  } else {
479  tctx->formatter->print_string(tctx, key, val);
480  }
481 
482  tctx->nb_item[tctx->level]++;
483  }
484 
485  return ret;
486 }
487 
488 void avtext_print_rational(AVTextFormatContext *tctx, const char *key, AVRational q, char sep)
489 {
490  char buf[44];
491  snprintf(buf, sizeof(buf), "%d%c%d", q.num, sep, q.den);
492  avtext_print_string(tctx, key, buf, 0);
493 }
494 
495 void avtext_print_time(AVTextFormatContext *tctx, const char *key,
496  int64_t ts, const AVRational *time_base, int is_duration)
497 {
498  if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) {
500  } else {
501  char buf[128];
502  double d = av_q2d(*time_base) * ts;
503  struct unit_value uv;
504  uv.val.d = d;
505  uv.unit = unit_second_str;
506  value_string(tctx, buf, sizeof(buf), uv);
507  avtext_print_string(tctx, key, buf, 0);
508  }
509 }
510 
511 void avtext_print_ts(AVTextFormatContext *tctx, const char *key, int64_t ts, int is_duration)
512 {
513  if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0))
515  else
516  avtext_print_integer(tctx, key, ts, 0);
517 }
518 
519 void avtext_print_data(AVTextFormatContext *tctx, const char *key,
520  const uint8_t *data, int size)
521 {
522  AVBPrint bp;
523  unsigned offset = 0;
524  int i;
525 
527  av_bprintf(&bp, "\n");
528  while (size) {
529  av_bprintf(&bp, "%08x: ", offset);
530  int l = FFMIN(size, 16);
531  for (i = 0; i < l; i++) {
532  av_bprintf(&bp, "%02x", data[i]);
533  if (i & 1)
534  av_bprintf(&bp, " ");
535  }
536  av_bprint_chars(&bp, ' ', 41 - 2 * i - i / 2);
537  for (i = 0; i < l; i++)
538  av_bprint_chars(&bp, data[i] - 32U < 95 ? data[i] : '.', 1);
539  av_bprintf(&bp, "\n");
540  offset += l;
541  data += l;
542  size -= l;
543  }
544  avtext_print_string(tctx, key, bp.str, 0);
545  av_bprint_finalize(&bp, NULL);
546 }
547 
549  const uint8_t *data, int size)
550 {
551  char buf[AV_HASH_MAX_SIZE * 2 + 64] = { 0 };
552  int len;
553 
554  if (!tctx->hash)
555  return;
556 
557  av_hash_init(tctx->hash);
558  av_hash_update(tctx->hash, data, size);
559  len = snprintf(buf, sizeof(buf), "%s:", av_hash_get_name(tctx->hash));
560  av_hash_final_hex(tctx->hash, (uint8_t *)&buf[len], (int)sizeof(buf) - len);
561  avtext_print_string(tctx, key, buf, 0);
562 }
563 
565  uint8_t *data, int size, const char *format,
566  int columns, int bytes, int offset_add)
567 {
568  AVBPrint bp;
569  unsigned offset = 0;
570 
571  if (!key || !data || !format || columns <= 0 || bytes <= 0)
572  return;
573 
575  av_bprintf(&bp, "\n");
576  while (size) {
577  av_bprintf(&bp, "%08x: ", offset);
578  for (int i = 0, l = FFMIN(size, columns); i < l; i++) {
579  if (bytes == 1) av_bprintf(&bp, format, *data);
580  else if (bytes == 2) av_bprintf(&bp, format, AV_RN16(data));
581  else if (bytes == 4) av_bprintf(&bp, format, AV_RN32(data));
582  data += bytes;
583  size--;
584  }
585  av_bprintf(&bp, "\n");
586  offset += offset_add;
587  }
588  avtext_print_string(tctx, key, bp.str, 0);
589  av_bprint_finalize(&bp, NULL);
590 }
591 
592 static const char *writercontext_get_writer_name(void *p)
593 {
594  AVTextWriterContext *wctx = p;
595  return wctx->writer->name;
596 }
597 
598 static void *writercontext_child_next(void *obj, void *prev)
599 {
600  AVTextFormatContext *ctx = obj;
601  if (!prev && ctx->formatter && ctx->formatter->priv_class && ctx->priv)
602  return ctx->priv;
603  return NULL;
604 }
605 
606 static const AVClass textwriter_class = {
607  .class_name = "AVTextWriterContext",
608  .item_name = writercontext_get_writer_name,
609  .version = LIBAVUTIL_VERSION_INT,
610  .child_next = writercontext_child_next,
611 };
612 
613 
615 {
616  AVTextWriterContext *wctx = *pwctx;
617  int ret = 0;
618 
619  if (!wctx)
620  return AVERROR(EINVAL);
621 
622  if (wctx->writer) {
623  if (wctx->writer->uninit)
624  ret = wctx->writer->uninit(wctx);
625  if (wctx->writer->priv_class)
626  av_opt_free(wctx->priv);
627  }
628  av_freep(&wctx->priv);
629  av_freep(pwctx);
630  return ret;
631 }
632 
633 
635 {
636  AVTextWriterContext *wctx;
637  int ret = 0;
638 
639  if (!pwctx || !writer)
640  return AVERROR(EINVAL);
641 
642  if (!((wctx = av_mallocz(sizeof(AVTextWriterContext))))) {
643  ret = AVERROR(ENOMEM);
644  goto fail;
645  }
646 
647  if (writer->priv_size && !((wctx->priv = av_mallocz(writer->priv_size)))) {
648  ret = AVERROR(ENOMEM);
649  goto fail;
650  }
651 
652  if (writer->priv_class) {
653  void *priv_ctx = wctx->priv;
654  *(const AVClass **)priv_ctx = writer->priv_class;
655  av_opt_set_defaults(priv_ctx);
656  }
657 
658  wctx->class = &textwriter_class;
659  wctx->writer = writer;
660 
661  av_opt_set_defaults(wctx);
662 
663 
664  if (wctx->writer->init)
665  ret = wctx->writer->init(wctx);
666  if (ret < 0)
667  goto fail;
668 
669  *pwctx = wctx;
670 
671  return 0;
672 
673 fail:
675  return ret;
676 }
677 
678 static const AVTextFormatter *const registered_formatters[] =
679 {
689  NULL
690 };
691 
693 {
694  for (int i = 0; registered_formatters[i]; i++) {
695  const char *end;
696  if (av_strstart(name, registered_formatters[i]->name, &end) &&
697  (*end == '\0' || *end == '='))
698  return registered_formatters[i];
699  }
700 
701  return NULL;
702 }
AV_OPT_SEARCH_CHILDREN
#define AV_OPT_SEARCH_CHILDREN
Search in possible children of the given object first.
Definition: opt.h:605
avtext_print_integers
void avtext_print_integers(AVTextFormatContext *tctx, const char *key, uint8_t *data, int size, const char *format, int columns, int bytes, int offset_add)
Definition: avtextformat.c:564
flags
const SwsFlags flags[]
Definition: swscale.c:61
value_string
static char * value_string(const AVTextFormatContext *tctx, char *buf, int buf_size, struct unit_value uv)
Definition: avtextformat.c:380
validate_string
static int validate_string(AVTextFormatContext *tctx, char **dstp, const char *src)
Definition: avtextformat.c:314
avtext_print_time
void avtext_print_time(AVTextFormatContext *tctx, const char *key, int64_t ts, const AVRational *time_base, int is_duration)
Definition: avtextformat.c:495
AVTextWriter::init
int(* init)(AVTextWriterContext *wctx)
Definition: avtextwriters.h:35
av_utf8_decode
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:368
writercontext_get_writer_name
static const char * writercontext_get_writer_name(void *p)
Definition: avtextformat.c:592
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
AV_TEXTFORMAT_PRINT_STRING_OPTIONAL
#define AV_TEXTFORMAT_PRINT_STRING_OPTIONAL
Definition: avtextformat.h:155
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
avtext_print_ts
void avtext_print_ts(AVTextFormatContext *tctx, const char *key, int64_t ts, int is_duration)
Definition: avtextformat.c:511
av_opt_set_defaults
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
Definition: opt.c:1678
AVTextFormatSection::entries_to_show
AVDictionary * entries_to_show
Definition: avtextformat.h:60
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
unit_value::i
int64_t i
Definition: avtextformat.c:374
textcontext_options
static const AVOption textcontext_options[]
Definition: avtextformat.c:65
opt.h
AVTextWriter::priv_size
int priv_size
private size for the writer private class
Definition: avtextwriters.h:32
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
AV_HASH_MAX_SIZE
#define AV_HASH_MAX_SIZE
Maximum value that av_hash_get_size() will currently return.
Definition: hash.h:156
AVTextFormatContext::nb_item_type
unsigned int nb_item_type[SECTION_MAX_NB_LEVELS][SECTION_MAX_NB_SECTIONS]
Definition: avtextformat.h:127
int64_t
long long int64_t
Definition: coverity.c:34
avtext_print_integer
void avtext_print_integer(AVTextFormatContext *tctx, const char *key, int64_t val, int flags)
Definition: avtextformat.c:290
AV_RN16
#define AV_RN16(p)
Definition: intreadwrite.h:356
avtextformatter_compact
const AVTextFormatter avtextformatter_compact
Definition: tf_compact.c:239
AV_TEXTFORMAT_STRING_VALIDATION_NB
@ AV_TEXTFORMAT_STRING_VALIDATION_NB
Definition: avtextformat.h:79
AVOption
AVOption.
Definition: opt.h:429
data
const char data[16]
Definition: mxf.c:149
AVTextFormatContext::show_value_unit
int show_value_unit
Definition: avtextformat.h:135
AVTextWriterContext
Definition: avtextwriters.h:42
avtextformat.h
avtext_print_unit_integer
void avtext_print_unit_integer(AVTextFormatContext *tctx, const char *key, int64_t val, const char *unit)
Definition: avtextformat.c:436
AVTextFormatContext
Definition: avtextformat.h:112
dec_str
char dec_str[4]
Definition: avtextformat.c:47
AVTextWriterContext::priv
void * priv
private data for use by the writer
Definition: avtextwriters.h:46
AVDictionary
Definition: dict.c:32
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
textcontext_class
static const AVClass textcontext_class
Definition: avtextformat.c:86
AVTextFormatSection::id
int id
unique id identifying a section
Definition: avtextformat.h:42
avtextformatter_mermaid
const AVTextFormatter avtextformatter_mermaid
Definition: tf_mermaid.c:651
AVTextFormatContext::level
int level
current level, starting from 0
Definition: avtextformat.h:123
AVTextWriter::uninit
int(* uninit)(AVTextWriterContext *wctx)
Definition: avtextwriters.h:36
macros.h
fail
#define fail()
Definition: checkasm.h:196
av_hash_get_name
const char * av_hash_get_name(const AVHashContext *ctx)
Definition: hash.c:104
textcontext_get_formatter_name
static const char * textcontext_get_formatter_name(void *p)
Definition: avtextformat.c:57
av_opt_free
void av_opt_free(void *obj)
Free all allocated objects in obj.
Definition: opt.c:1949
AV_BPRINT_SIZE_AUTOMATIC
#define AV_BPRINT_SIZE_AUTOMATIC
val
static double val(void *priv, double ch)
Definition: aeval.c:77
si_prefixes
static const struct @11 si_prefixes[]
AVTextFormatSection::show_all_entries
int show_all_entries
Definition: avtextformat.h:62
av_opt_set
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition: opt.c:835
AV_TEXTFORMAT_PRINT_STRING_VALIDATE
#define AV_TEXTFORMAT_PRINT_STRING_VALIDATE
Definition: avtextformat.h:156
AVRational::num
int num
Numerator.
Definition: rational.h:59
av_clip64
#define av_clip64
Definition: common.h:103
AVTextFormatContext::writer
AVTextWriterContext * writer
the AVTextWriterContext
Definition: avtextformat.h:115
avassert.h
SECTION_ID_NONE
#define SECTION_ID_NONE
Definition: avtextformat.c:37
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
registered_formatters
static const AVTextFormatter *const registered_formatters[]
Definition: avtextformat.c:678
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:60
avtextformatter_default
const AVTextFormatter avtextformatter_default
Definition: tf_default.c:127
unit_bit_per_second_str
static const char unit_bit_per_second_str[]
Definition: avtextformat.c:248
AVTextFormatter::print_string
void(* print_string)(AVTextFormatContext *tctx, const char *, const char *)
Definition: avtextformat.h:105
textcontext_child_next
static void * textcontext_child_next(void *obj, void *prev)
Definition: avtextformat.c:78
intreadwrite.h
AVTextFormatter
Definition: avtextformat.h:94
SECTION_MAX_NB_SECTIONS
#define SECTION_MAX_NB_SECTIONS
Definition: avtextformat.h:110
avtext_print_data_hash
void avtext_print_data_hash(AVTextFormatContext *tctx, const char *key, const uint8_t *data, int size)
Definition: avtextformat.c:548
AVTextWriterContext::class
const AVClass * class
class of the writer
Definition: avtextwriters.h:43
AVDictionaryEntry::key
char * key
Definition: dict.h:91
avtextwriter_context_close
int avtextwriter_context_close(AVTextWriterContext **pwctx)
Definition: avtextformat.c:614
AVTextFormatSection
Definition: avtextformat.h:41
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
av_hash_alloc
int av_hash_alloc(AVHashContext **ctx, const char *name)
Allocate a hash context for the algorithm specified by name.
Definition: hash.c:114
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
AVFormatContext * ctx
Definition: movenc.c:49
bin_str
char bin_str[4]
Definition: avtextformat.c:46
avtextformatter_ini
const AVTextFormatter avtextformatter_ini
Definition: tf_ini.c:141
avtext_context_open
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)
Definition: avtextformat.c:126
limits.h
AVTextWriter::priv_class
const AVClass * priv_class
private class of the writer, if any
Definition: avtextwriters.h:31
AVTextFormatContext::priv
void * priv
private data for use by the filter
Definition: avtextformat.h:118
key
const char * key
Definition: hwcontext_opencl.c:189
AVTextFormatter::priv_size
int priv_size
private size for the formatter context
Definition: avtextformat.h:96
AVTextFormatContext::use_byte_value_binary_prefix
int use_byte_value_binary_prefix
Definition: avtextformat.h:137
dec_val
double dec_val
Definition: avtextformat.c:45
AVTextFormatSection::unique_name
const char * unique_name
unique section name, in case the name is ambiguous
Definition: avtextformat.h:59
opts
AVDictionary * opts
Definition: movenc.c:51
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
avtext_print_string
int avtext_print_string(AVTextFormatContext *tctx, const char *key, const char *val, int flags)
Definition: avtextformat.c:446
av_hash_names
const char * av_hash_names(int i)
Get the names of available hash algorithms.
Definition: hash.c:98
AVTextFormatContext::section
const AVTextFormatSection * section[SECTION_MAX_NB_LEVELS]
section per each level
Definition: avtextformat.h:130
unit_second_str
static const char unit_second_str[]
Definition: avtextformat.c:245
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
av_hash_init
void av_hash_init(AVHashContext *ctx)
Initialize or reset a hash context.
Definition: hash.c:151
SHOW_OPTIONAL_FIELDS_AUTO
#define SHOW_OPTIONAL_FIELDS_AUTO
Definition: avtextformat.c:39
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
bprint_bytes
static void bprint_bytes(AVBPrint *bp, const uint8_t *ubuf, size_t ubuf_size)
Definition: avtextformat.c:94
AV_RN32
#define AV_RN32(p)
Definition: intreadwrite.h:360
AVTextWriter::name
const char * name
Definition: avtextwriters.h:33
options
Definition: swscale.c:43
AVTextFormatter::print_section_header
void(* print_section_header)(AVTextFormatContext *tctx, const void *data)
Definition: avtextformat.h:102
AV_TEXTFORMAT_STRING_VALIDATION_IGNORE
@ AV_TEXTFORMAT_STRING_VALIDATION_IGNORE
Definition: avtextformat.h:78
double
double
Definition: af_crystalizer.c:132
AVTextFormatContext::formatter
const AVTextFormatter * formatter
the AVTextFormatter of which this is an instance
Definition: avtextformat.h:114
av_hash_update
void av_hash_update(AVHashContext *ctx, const uint8_t *src, size_t len)
Update a hash context with additional data.
Definition: hash.c:172
avtext_get_formatter_by_name
const AVTextFormatter * avtext_get_formatter_by_name(const char *name)
Definition: avtextformat.c:692
index
int index
Definition: gxfenc.c:90
SECTION_MAX_NB_LEVELS
#define SECTION_MAX_NB_LEVELS
Definition: avtextformat.h:109
av_hash_freep
void av_hash_freep(AVHashContext **ctx)
Free hash context and set hash context pointer to NULL.
Definition: hash.c:248
error.h
avtextformatter_flat
const AVTextFormatter avtextformatter_flat
Definition: tf_flat.c:151
avtextwriter_context_open
int avtextwriter_context_open(AVTextWriterContext **pwctx, const AVTextWriter *writer)
Definition: avtextformat.c:634
AVTextWriter
Definition: avtextwriters.h:30
unit_hertz_str
static const char unit_hertz_str[]
Definition: avtextformat.c:246
AV_TEXTFORMAT_STRING_VALIDATION_FAIL
@ AV_TEXTFORMAT_STRING_VALIDATION_FAIL
Definition: avtextformat.h:76
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:240
AVTextFormatter::name
const char * name
Definition: avtextformat.h:97
avtext_print_section_footer
void avtext_print_section_footer(AVTextFormatContext *tctx)
Definition: avtextformat.c:269
AVTextWriterContext::writer
const AVTextWriter * writer
Definition: avtextwriters.h:44
size
int size
Definition: twinvq_data.h:10344
AVTextFormatContext::use_value_sexagesimal_format
int use_value_sexagesimal_format
Definition: avtextformat.h:138
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
AVTextFormatContext::section_pbuf
AVBPrint section_pbuf[SECTION_MAX_NB_LEVELS]
generic print buffer dedicated to each section, used by various formatters
Definition: avtextformat.h:131
unit_value
Definition: avtextformat.c:371
SHOW_OPTIONAL_FIELDS_NEVER
#define SHOW_OPTIONAL_FIELDS_NEVER
Definition: avtextformat.c:40
AVTextFormatContext::show_optional_fields
int show_optional_fields
Definition: avtextformat.h:134
AVTextFormatter::flags
int flags
a combination or AV_TEXTFORMAT__FLAG_*
Definition: avtextformat.h:106
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:233
av_strstart
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
textwriter_class
static const AVClass textwriter_class
Definition: avtextformat.c:606
AVTextFormatContext::sections
const AVTextFormatSection * sections
array containing all sections
Definition: avtextformat.h:120
avtext_print_rational
void avtext_print_rational(AVTextFormatContext *tctx, const char *key, AVRational q, char sep)
Definition: avtextformat.c:488
unit_value::unit
const char * unit
Definition: avtextformat.c:377
AVTextFormatContext::class
const AVClass * class
class of the formatter
Definition: avtextformat.h:113
bprint.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
code
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
Definition: filter_design.txt:178
unit_value::val
union unit_value::@12 val
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
avtextformatter_xml
const AVTextFormatter avtextformatter_xml
Definition: tf_xml.c:202
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
AVTextFormatter::uninit
int(* uninit)(AVTextFormatContext *tctx)
Definition: avtextformat.h:100
AVTextFormatContext::string_validation_utf8_flags
unsigned int string_validation_utf8_flags
Definition: avtextformat.h:144
len
int len
Definition: vorbis_enc_data.h:426
writercontext_child_next
static void * writercontext_child_next(void *obj, void *prev)
Definition: avtextformat.c:598
avtextformatter_json
const AVTextFormatter avtextformatter_json
Definition: tf_json.c:203
log2
#define log2(x)
Definition: libm.h:406
AVTextFormatter::print_section_footer
void(* print_section_footer)(AVTextFormatContext *tctx)
Definition: avtextformat.h:103
sections
static struct AVTextFormatSection sections[]
Definition: ffprobe.c:249
ret
ret
Definition: filter_design.txt:187
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:99
U
#define U(x)
Definition: vpx_arith.h:37
hash.h
AVTextFormatter::priv_class
const AVClass * priv_class
private class of the formatter, if any
Definition: avtextformat.h:95
AVTextFormatter::print_integer
void(* print_integer)(AVTextFormatContext *tctx, const char *, int64_t)
Definition: avtextformat.h:104
AVTextFormatContext::string_validation
int string_validation
Definition: avtextformat.h:142
AVRational::den
int den
Denominator.
Definition: rational.h:60
AVTextFormatOptions
Definition: avtextformat.h:147
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
av_bprint_clear
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
Definition: bprint.c:232
av_dict_parse_string
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
AVTextFormatter::init
int(* init)(AVTextFormatContext *tctx)
Definition: avtextformat.h:99
unit_byte_str
static const char unit_byte_str[]
Definition: avtextformat.c:247
AVTextFormatContext::use_value_prefix
int use_value_prefix
Definition: avtextformat.h:136
mem.h
avtextformatter_csv
const AVTextFormatter avtextformatter_csv
Definition: tf_compact.c:270
av_hash_final_hex
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
AVTextFormatContext::nb_item
unsigned int nb_item[SECTION_MAX_NB_LEVELS]
number of the item printed in the given section, starting from 0
Definition: avtextformat.h:126
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:90
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
int32_t
int32_t
Definition: audioconvert.c:56
OFFSET
#define OFFSET(x)
Definition: avtextformat.c:63
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
avtext_print_data
void avtext_print_data(AVTextFormatContext *tctx, const char *key, const uint8_t *data, int size)
Definition: avtextformat.c:519
av_bprint_chars
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:145
AV_TEXTFORMAT_STRING_VALIDATION_REPLACE
@ AV_TEXTFORMAT_STRING_VALIDATION_REPLACE
Definition: avtextformat.h:77
AVDictionaryEntry::value
char * value
Definition: dict.h:92
show_data_hash
static char * show_data_hash
Definition: ffprobe.c:140
bin_val
double bin_val
Definition: avtextformat.c:44
AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS
#define AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS
Definition: avtextformat.h:71
AV_OPT_TYPE_STRING
@ 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:276
unit_value::d
double d
Definition: avtextformat.c:373
avtext_context_close
int avtext_context_close(AVTextFormatContext **ptctx)
Definition: avtextformat.c:101
av_bprint_append_data
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
Append data to a print buffer.
Definition: bprint.c:163
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
snprintf
#define snprintf
Definition: snprintf.h:34
avtextformatter_mermaidhtml
const AVTextFormatter avtextformatter_mermaidhtml
Definition: tf_mermaid.c:665
av_dict_iterate
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition: dict.c:42
src
#define src
Definition: vp8dsp.c:248
AVTextFormatContext::nb_sections
int nb_sections
number of sections
Definition: avtextformat.h:121
AVTextFormatContext::hash
struct AVHashContext * hash
Definition: avtextformat.h:140
avtext_print_section_header
void avtext_print_section_header(AVTextFormatContext *tctx, const void *data, int section_id)
Definition: avtextformat.c:251
AVTextFormatContext::string_validation_replacement
char * string_validation_replacement
Definition: avtextformat.h:143