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  const char *bin_str;
47  const char *dec_str;
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 i;
105  int ret = 0;
106 
107  if (!tctx)
108  return AVERROR(EINVAL);
109 
110  av_hash_freep(&tctx->hash);
111 
112  av_hash_freep(&tctx->hash);
113 
114  if (tctx->formatter) {
115  if (tctx->formatter->uninit)
116  ret = tctx->formatter->uninit(tctx);
117  if (tctx->formatter->priv_class)
118  av_opt_free(tctx->priv);
119  }
120  for (i = 0; i < SECTION_MAX_NB_LEVELS; i++)
122  av_freep(&tctx->priv);
123  av_opt_free(tctx);
124  av_freep(ptctx);
125  return ret;
126 }
127 
128 
129 int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *formatter, AVTextWriterContext *writer_context, const char *args,
131 {
132  AVTextFormatContext *tctx;
133  int i, ret = 0;
134 
135  av_assert0(ptctx && formatter);
136 
137  if (!(tctx = av_mallocz(sizeof(AVTextFormatContext)))) {
138  ret = AVERROR(ENOMEM);
139  goto fail;
140  }
141 
142  for (int i = 0; i < SECTION_MAX_NB_LEVELS; i++)
144 
145  tctx->class = &textcontext_class;
146  av_opt_set_defaults(tctx);
147 
148  if (!(tctx->priv = av_mallocz(formatter->priv_size))) {
149  ret = AVERROR(ENOMEM);
150  goto fail;
151  }
152 
153  tctx->show_value_unit = options.show_value_unit;
154  tctx->use_value_prefix = options.use_value_prefix;
155  tctx->use_byte_value_binary_prefix = options.use_byte_value_binary_prefix;
156  tctx->use_value_sexagesimal_format = options.use_value_sexagesimal_format;
157  tctx->show_optional_fields = options.show_optional_fields;
158 
159  if (nb_sections > SECTION_MAX_NB_SECTIONS) {
160  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);
161  ret = AVERROR(EINVAL);
162  goto fail;
163  }
164 
165  tctx->formatter = formatter;
166  tctx->level = -1;
167  tctx->sections = sections;
168  tctx->nb_sections = nb_sections;
169  tctx->writer = writer_context;
170 
171  if (formatter->priv_class) {
172  void *priv_ctx = tctx->priv;
173  *(const AVClass **)priv_ctx = formatter->priv_class;
174  av_opt_set_defaults(priv_ctx);
175  }
176 
177  /* convert options to dictionary */
178  if (args) {
180  const AVDictionaryEntry *opt = NULL;
181 
182  if ((ret = av_dict_parse_string(&opts, args, "=", ":", 0)) < 0) {
183  av_log(tctx, AV_LOG_ERROR, "Failed to parse option string '%s' provided to textformat context\n", args);
184  av_dict_free(&opts);
185  goto fail;
186  }
187 
188  while ((opt = av_dict_iterate(opts, opt))) {
189  if ((ret = av_opt_set(tctx, opt->key, opt->value, AV_OPT_SEARCH_CHILDREN)) < 0) {
190  av_log(tctx, AV_LOG_ERROR, "Failed to set option '%s' with value '%s' provided to textformat context\n",
191  opt->key, opt->value);
192  av_dict_free(&opts);
193  goto fail;
194  }
195  }
196 
197  av_dict_free(&opts);
198  }
199 
200  if (show_data_hash) {
201  if ((ret = av_hash_alloc(&tctx->hash, show_data_hash)) < 0) {
202  if (ret == AVERROR(EINVAL)) {
203  const char *n;
204  av_log(NULL, AV_LOG_ERROR, "Unknown hash algorithm '%s'\nKnown algorithms:", show_data_hash);
205  for (i = 0; (n = av_hash_names(i)); i++)
206  av_log(NULL, AV_LOG_ERROR, " %s", n);
207  av_log(NULL, AV_LOG_ERROR, "\n");
208  }
209  goto fail;
210  }
211  }
212 
213  /* validate replace string */
214  {
215  const uint8_t *p = (uint8_t *)tctx->string_validation_replacement;
216  const uint8_t *endp = p + strlen((const char *)p);
217  while (*p) {
218  const uint8_t *p0 = p;
219  int32_t code;
221  if (ret < 0) {
222  AVBPrint bp;
224  bprint_bytes(&bp, p0, p - p0);
225  av_log(tctx, AV_LOG_ERROR,
226  "Invalid UTF8 sequence %s found in string validation replace '%s'\n",
227  bp.str, tctx->string_validation_replacement);
228  return ret;
229  goto fail;
230  }
231  }
232  }
233 
234  if (tctx->formatter->init)
235  ret = tctx->formatter->init(tctx);
236  if (ret < 0)
237  goto fail;
238 
239  *ptctx = tctx;
240 
241  return 0;
242 
243 fail:
244  avtext_context_close(&tctx);
245  return ret;
246 }
247 
248 /* Temporary definitions during refactoring */
249 static const char unit_second_str[] = "s";
250 static const char unit_hertz_str[] = "Hz";
251 static const char unit_byte_str[] = "byte";
252 static const char unit_bit_per_second_str[] = "bit/s";
253 
254 
255 void avtext_print_section_header(AVTextFormatContext *tctx, const void *data, int section_id)
256 {
257  if (section_id < 0 || section_id >= tctx->nb_sections) {
258  av_log(tctx, AV_LOG_ERROR, "Invalid section_id for section_header: %d\n", section_id);
259  return;
260  }
261 
262  tctx->level++;
264 
265  tctx->nb_item[tctx->level] = 0;
266  memset(tctx->nb_item_type[tctx->level], 0, sizeof(tctx->nb_item_type[tctx->level]));
267  tctx->section[tctx->level] = &tctx->sections[section_id];
268 
269  if (tctx->formatter->print_section_header)
270  tctx->formatter->print_section_header(tctx, data);
271 }
272 
274 {
275  if (tctx->level < 0 || tctx->level >= SECTION_MAX_NB_LEVELS) {
276  av_log(tctx, AV_LOG_ERROR, "Invalid level for section_footer: %d\n", tctx->level);
277  return;
278  }
279 
280  int section_id = tctx->section[tctx->level]->id;
281  int parent_section_id = tctx->level ?
282  tctx->section[tctx->level - 1]->id : SECTION_ID_NONE;
283 
284  if (parent_section_id != SECTION_ID_NONE) {
285  tctx->nb_item[tctx->level - 1]++;
286  tctx->nb_item_type[tctx->level - 1][section_id]++;
287  }
288 
289  if (tctx->formatter->print_section_footer)
290  tctx->formatter->print_section_footer(tctx);
291  tctx->level--;
292 }
293 
295 {
296  const AVTextFormatSection *section;
297 
298  av_assert0(tctx);
299 
301  return;
302 
306  return;
307 
308  av_assert0(key && tctx->level >= 0 && tctx->level < SECTION_MAX_NB_LEVELS);
309 
310  section = tctx->section[tctx->level];
311 
312  if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) {
313  tctx->formatter->print_integer(tctx, key, val);
314  tctx->nb_item[tctx->level]++;
315  }
316 }
317 
318 static inline int validate_string(AVTextFormatContext *tctx, char **dstp, const char *src)
319 {
320  const uint8_t *p, *endp, *srcp = (const uint8_t *)src;
321  AVBPrint dstbuf;
322  AVBPrint invalid_seq;
323  int invalid_chars_nb = 0, ret = 0;
324 
325  *dstp = NULL;
327  av_bprint_init(&invalid_seq, 0, AV_BPRINT_SIZE_UNLIMITED);
328 
329  endp = srcp + strlen(src);
330  for (p = srcp; *p;) {
331  int32_t code;
332  int invalid = 0;
333  const uint8_t *p0 = p;
334 
335  if (av_utf8_decode(&code, &p, endp, tctx->string_validation_utf8_flags) < 0) {
336 
337  av_bprint_clear(&invalid_seq);
338 
339  bprint_bytes(&invalid_seq, p0, p - p0);
340 
341  av_log(tctx, AV_LOG_DEBUG, "Invalid UTF-8 sequence '%s' found in string '%s'\n", invalid_seq.str, src);
342  invalid = 1;
343  }
344 
345  if (invalid) {
346  invalid_chars_nb++;
347 
348  switch (tctx->string_validation) {
350  av_log(tctx, AV_LOG_ERROR, "Invalid UTF-8 sequence found in string '%s'\n", src);
352  goto end;
353 
355  av_bprintf(&dstbuf, "%s", tctx->string_validation_replacement);
356  break;
357  }
358  }
359 
361  av_bprint_append_data(&dstbuf, p0, p-p0);
362  }
363 
364  if (invalid_chars_nb && tctx->string_validation == AV_TEXTFORMAT_STRING_VALIDATION_REPLACE)
365  av_log(tctx, AV_LOG_WARNING,
366  "%d invalid UTF-8 sequence(s) found in string '%s', replaced with '%s'\n",
367  invalid_chars_nb, src, tctx->string_validation_replacement);
368 
369 end:
370  av_bprint_finalize(&dstbuf, dstp);
371  av_bprint_finalize(&invalid_seq, NULL);
372  return ret;
373 }
374 
375 struct unit_value {
376  union {
377  double d;
379  } val;
380 
381  const char *unit;
382 };
383 
384 static char *value_string(const AVTextFormatContext *tctx, char *buf, int buf_size, struct unit_value uv)
385 {
386  double vald;
387  int64_t vali = 0;
388  int show_float = 0;
389 
390  if (uv.unit == unit_second_str) {
391  vald = uv.val.d;
392  show_float = 1;
393  } else {
394  vald = (double)uv.val.i;
395  vali = uv.val.i;
396  }
397 
399  double secs;
400  int hours, mins;
401  secs = vald;
402  mins = (int)secs / 60;
403  secs = secs - mins * 60;
404  hours = mins / 60;
405  mins %= 60;
406  snprintf(buf, buf_size, "%d:%02d:%09.6f", hours, mins, secs);
407  } else {
408  const char *prefix_string = "";
409 
410  if (tctx->use_value_prefix && vald > 1) {
411  int64_t index;
412 
413  if (uv.unit == unit_byte_str && tctx->use_byte_value_binary_prefix) {
414  index = (int64_t)(log2(vald) / 10);
416  vald /= si_prefixes[index].bin_val;
417  prefix_string = si_prefixes[index].bin_str;
418  } else {
419  index = (int64_t)(log10(vald) / 3);
421  vald /= si_prefixes[index].dec_val;
422  prefix_string = si_prefixes[index].dec_str;
423  }
424  vali = (int64_t)vald;
425  }
426 
427  if (show_float || (tctx->use_value_prefix && vald != (int64_t)vald))
428  snprintf(buf, buf_size, "%f", vald);
429  else
430  snprintf(buf, buf_size, "%"PRId64, vali);
431 
432  av_strlcatf(buf, buf_size, "%s%s%s", *prefix_string || tctx->show_value_unit ? " " : "",
433  prefix_string, tctx->show_value_unit ? uv.unit : "");
434  }
435 
436  return buf;
437 }
438 
439 
440 void avtext_print_unit_int(AVTextFormatContext *tctx, const char *key, int value, const char *unit)
441 {
442  char val_str[128];
443  struct unit_value uv;
444  uv.val.i = value;
445  uv.unit = unit;
446  avtext_print_string(tctx, key, value_string(tctx, val_str, sizeof(val_str), uv), 0);
447 }
448 
449 
450 int avtext_print_string(AVTextFormatContext *tctx, const char *key, const char *val, int flags)
451 {
452  const AVTextFormatSection *section;
453  int ret = 0;
454 
455  av_assert0(key && val && tctx->level >= 0 && tctx->level < SECTION_MAX_NB_LEVELS);
456 
457  section = tctx->section[tctx->level];
458 
460  return 0;
461 
465  return 0;
466 
467  if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) {
469  char *key1 = NULL, *val1 = NULL;
470  ret = validate_string(tctx, &key1, key);
471  if (ret < 0) goto end;
472  ret = validate_string(tctx, &val1, val);
473  if (ret < 0) goto end;
474  tctx->formatter->print_string(tctx, key1, val1);
475  end:
476  if (ret < 0)
477  av_log(tctx, AV_LOG_ERROR,
478  "Invalid key=value string combination %s=%s in section %s\n",
479  key, val, section->unique_name);
480  av_free(key1);
481  av_free(val1);
482  } else {
483  tctx->formatter->print_string(tctx, key, val);
484  }
485 
486  tctx->nb_item[tctx->level]++;
487  }
488 
489  return ret;
490 }
491 
492 void avtext_print_rational(AVTextFormatContext *tctx, const char *key, AVRational q, char sep)
493 {
494  char buf[44];
495  snprintf(buf, sizeof(buf), "%d%c%d", q.num, sep, q.den);
496  avtext_print_string(tctx, key, buf, 0);
497 }
498 
499 void avtext_print_time(AVTextFormatContext *tctx, const char *key,
500  int64_t ts, const AVRational *time_base, int is_duration)
501 {
502  if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) {
504  } else {
505  char buf[128];
506  double d = av_q2d(*time_base) * ts;
507  struct unit_value uv;
508  uv.val.d = d;
509  uv.unit = unit_second_str;
510  value_string(tctx, buf, sizeof(buf), uv);
511  avtext_print_string(tctx, key, buf, 0);
512  }
513 }
514 
515 void avtext_print_ts(AVTextFormatContext *tctx, const char *key, int64_t ts, int is_duration)
516 {
517  if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0))
519  else
520  avtext_print_integer(tctx, key, ts, 0);
521 }
522 
523 void avtext_print_data(AVTextFormatContext *tctx, const char *key,
524  const uint8_t *data, int size)
525 {
526  AVBPrint bp;
527  unsigned offset = 0;
528  int l, i;
529 
531  av_bprintf(&bp, "\n");
532  while (size) {
533  av_bprintf(&bp, "%08x: ", offset);
534  l = FFMIN(size, 16);
535  for (i = 0; i < l; i++) {
536  av_bprintf(&bp, "%02x", data[i]);
537  if (i & 1)
538  av_bprintf(&bp, " ");
539  }
540  av_bprint_chars(&bp, ' ', 41 - 2 * i - i / 2);
541  for (i = 0; i < l; i++)
542  av_bprint_chars(&bp, data[i] - 32U < 95 ? data[i] : '.', 1);
543  av_bprintf(&bp, "\n");
544  offset += l;
545  data += l;
546  size -= l;
547  }
548  avtext_print_string(tctx, key, bp.str, 0);
549  av_bprint_finalize(&bp, NULL);
550 }
551 
553  const uint8_t *data, int size)
554 {
555  char buf[AV_HASH_MAX_SIZE * 2 + 64] = { 0 };
556  int len;
557 
558  if (!tctx->hash)
559  return;
560 
561  av_hash_init(tctx->hash);
562  av_hash_update(tctx->hash, data, size);
563  len = snprintf(buf, sizeof(buf), "%s:", av_hash_get_name(tctx->hash));
564  av_hash_final_hex(tctx->hash, (uint8_t *)&buf[len], (int)sizeof(buf) - len);
565  avtext_print_string(tctx, key, buf, 0);
566 }
567 
569  uint8_t *data, int size, const char *format,
570  int columns, int bytes, int offset_add)
571 {
572  AVBPrint bp;
573  unsigned offset = 0;
574  int l, i;
575 
576  if (!key || !data || !format || columns <= 0 || bytes <= 0)
577  return;
578 
580  av_bprintf(&bp, "\n");
581  while (size) {
582  av_bprintf(&bp, "%08x: ", offset);
583  l = FFMIN(size, columns);
584  for (i = 0; i < l; i++) {
585  if (bytes == 1) av_bprintf(&bp, format, *data);
586  else if (bytes == 2) av_bprintf(&bp, format, AV_RN16(data));
587  else if (bytes == 4) av_bprintf(&bp, format, AV_RN32(data));
588  data += bytes;
589  size--;
590  }
591  av_bprintf(&bp, "\n");
592  offset += offset_add;
593  }
594  avtext_print_string(tctx, key, bp.str, 0);
595  av_bprint_finalize(&bp, NULL);
596 }
597 
598 static const char *writercontext_get_writer_name(void *p)
599 {
600  AVTextWriterContext *wctx = p;
601  return wctx->writer->name;
602 }
603 
604 static void *writercontext_child_next(void *obj, void *prev)
605 {
606  AVTextFormatContext *ctx = obj;
607  if (!prev && ctx->formatter && ctx->formatter->priv_class && ctx->priv)
608  return ctx->priv;
609  return NULL;
610 }
611 
612 static const AVClass textwriter_class = {
613  .class_name = "AVTextWriterContext",
614  .item_name = writercontext_get_writer_name,
615  .version = LIBAVUTIL_VERSION_INT,
616  .child_next = writercontext_child_next,
617 };
618 
619 
621 {
622  AVTextWriterContext *wctx = *pwctx;
623  int ret = 0;
624 
625  if (!wctx)
626  return AVERROR(EINVAL);
627 
628  if (wctx->writer) {
629  if (wctx->writer->uninit)
630  ret = wctx->writer->uninit(wctx);
631  if (wctx->writer->priv_class)
632  av_opt_free(wctx->priv);
633  }
634  av_freep(&wctx->priv);
635  av_freep(pwctx);
636  return ret;
637 }
638 
639 
641 {
642  AVTextWriterContext *wctx;
643  int ret = 0;
644 
645  if (!pwctx || !writer)
646  return AVERROR(EINVAL);
647 
648  if (!((wctx = av_mallocz(sizeof(AVTextWriterContext))))) {
649  ret = AVERROR(ENOMEM);
650  goto fail;
651  }
652 
653  if (writer->priv_size && !((wctx->priv = av_mallocz(writer->priv_size)))) {
654  ret = AVERROR(ENOMEM);
655  goto fail;
656  }
657 
658  if (writer->priv_class) {
659  void *priv_ctx = wctx->priv;
660  *(const AVClass **)priv_ctx = writer->priv_class;
661  av_opt_set_defaults(priv_ctx);
662  }
663 
664  wctx->class = &textwriter_class;
665  wctx->writer = writer;
666 
667  av_opt_set_defaults(wctx);
668 
669 
670  if (wctx->writer->init)
671  ret = wctx->writer->init(wctx);
672  if (ret < 0)
673  goto fail;
674 
675  *pwctx = wctx;
676 
677  return 0;
678 
679 fail:
681  return ret;
682 }
683 
685 
686 static void formatters_register_all(void)
687 {
688  static int initialized;
689 
690  if (initialized)
691  return;
692  initialized = 1;
693 
703 }
704 
706 {
708 
709  for (int i = 0; registered_formatters[i]; i++)
710  if (!strcmp(registered_formatters[i]->name, name))
711  return registered_formatters[i];
712 
713  return NULL;
714 }
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:568
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:384
validate_string
static int validate_string(AVTextFormatContext *tctx, char **dstp, const char *src)
Definition: avtextformat.c:318
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:499
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:598
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:515
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:378
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:294
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
AVTextFormatContext
Definition: avtextformat.h:112
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:635
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
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:252
initialized
static int initialized
Definition: vaapi_transcode.c:43
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:552
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:620
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:40
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
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:129
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
bin_str
const char * bin_str
Definition: avtextformat.c:46
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:450
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:249
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:705
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
formatters_register_all
static void formatters_register_all(void)
Definition: avtextformat.c:686
dec_str
const char * dec_str
Definition: avtextformat.c:47
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:640
AVTextWriter
Definition: avtextwriters.h:30
unit_hertz_str
static const char unit_hertz_str[]
Definition: avtextformat.c:250
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:273
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:375
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
textwriter_class
static const AVClass textwriter_class
Definition: avtextformat.c:612
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:492
unit_value::unit
const char * unit
Definition: avtextformat.c:381
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
value
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 value
Definition: writing_filters.txt:86
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:604
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:251
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
registered_formatters
static const AVTextFormatter * registered_formatters[9+1]
Definition: avtextformat.c:684
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:523
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
avtext_print_unit_int
void avtext_print_unit_int(AVTextFormatContext *tctx, const char *key, int value, const char *unit)
Definition: avtextformat.c:440
unit_value::d
double d
Definition: avtextformat.c:377
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:648
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:255
AVTextFormatContext::string_validation_replacement
char * string_validation_replacement
Definition: avtextformat.h:143