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->is_key_selected = options.is_key_selected;
151  tctx->show_value_unit = options.show_value_unit;
152  tctx->use_value_prefix = options.use_value_prefix;
153  tctx->use_byte_value_binary_prefix = options.use_byte_value_binary_prefix;
154  tctx->use_value_sexagesimal_format = options.use_value_sexagesimal_format;
155  tctx->show_optional_fields = options.show_optional_fields;
156 
157  if (nb_sections > SECTION_MAX_NB_SECTIONS) {
158  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);
159  ret = AVERROR(EINVAL);
160  goto fail;
161  }
162 
163  tctx->formatter = formatter;
164  tctx->level = -1;
165  tctx->sections = sections;
166  tctx->nb_sections = nb_sections;
167  tctx->writer = writer_context;
168 
169  if (formatter->priv_class) {
170  void *priv_ctx = tctx->priv;
171  *(const AVClass **)priv_ctx = formatter->priv_class;
172  av_opt_set_defaults(priv_ctx);
173  }
174 
175  /* convert options to dictionary */
176  if (args) {
178  const AVDictionaryEntry *opt = NULL;
179 
180  if ((ret = av_dict_parse_string(&opts, args, "=", ":", 0)) < 0) {
181  av_log(tctx, AV_LOG_ERROR, "Failed to parse option string '%s' provided to textformat context\n", args);
182  av_dict_free(&opts);
183  goto fail;
184  }
185 
186  while ((opt = av_dict_iterate(opts, opt))) {
187  if ((ret = av_opt_set(tctx, opt->key, opt->value, AV_OPT_SEARCH_CHILDREN)) < 0) {
188  av_log(tctx, AV_LOG_ERROR, "Failed to set option '%s' with value '%s' provided to textformat context\n",
189  opt->key, opt->value);
190  av_dict_free(&opts);
191  goto fail;
192  }
193  }
194 
195  av_dict_free(&opts);
196  }
197 
198  if (show_data_hash) {
199  if ((ret = av_hash_alloc(&tctx->hash, show_data_hash)) < 0) {
200  if (ret == AVERROR(EINVAL)) {
201  const char *n;
202  av_log(NULL, AV_LOG_ERROR, "Unknown hash algorithm '%s'\nKnown algorithms:", show_data_hash);
203  for (unsigned i = 0; (n = av_hash_names(i)); i++)
204  av_log(NULL, AV_LOG_ERROR, " %s", n);
205  av_log(NULL, AV_LOG_ERROR, "\n");
206  }
207  goto fail;
208  }
209  }
210 
211  /* validate replace string */
212  {
213  const uint8_t *p = (uint8_t *)tctx->string_validation_replacement;
214  const uint8_t *endp = p + strlen((const char *)p);
215  while (*p) {
216  const uint8_t *p0 = p;
217  int32_t code;
219  if (ret < 0) {
220  AVBPrint bp;
222  bprint_bytes(&bp, p0, p - p0);
223  av_log(tctx, AV_LOG_ERROR,
224  "Invalid UTF8 sequence %s found in string validation replace '%s'\n",
225  bp.str, tctx->string_validation_replacement);
226  goto fail;
227  }
228  }
229  }
230 
231  if (tctx->formatter->init)
232  ret = tctx->formatter->init(tctx);
233  if (ret < 0)
234  goto fail;
235 
236  *ptctx = tctx;
237 
238  return 0;
239 
240 fail:
241  avtext_context_close(&tctx);
242  return ret;
243 }
244 
245 /* Temporary definitions during refactoring */
246 static const char unit_second_str[] = "s";
247 static const char unit_hertz_str[] = "Hz";
248 static const char unit_byte_str[] = "byte";
249 static const char unit_bit_per_second_str[] = "bit/s";
250 
251 
252 void avtext_print_section_header(AVTextFormatContext *tctx, const void *data, int section_id)
253 {
254  if (section_id < 0 || section_id >= tctx->nb_sections) {
255  av_log(tctx, AV_LOG_ERROR, "Invalid section_id for section_header: %d\n", section_id);
256  return;
257  }
258 
259  tctx->level++;
261 
262  tctx->nb_item[tctx->level] = 0;
263  memset(tctx->nb_item_type[tctx->level], 0, sizeof(tctx->nb_item_type[tctx->level]));
264  tctx->section[tctx->level] = &tctx->sections[section_id];
265 
266  if (tctx->formatter->print_section_header)
267  tctx->formatter->print_section_header(tctx, data);
268 }
269 
271 {
272  if (tctx->level < 0 || tctx->level >= SECTION_MAX_NB_LEVELS) {
273  av_log(tctx, AV_LOG_ERROR, "Invalid level for section_footer: %d\n", tctx->level);
274  return;
275  }
276 
277  int section_id = tctx->section[tctx->level]->id;
278  int parent_section_id = tctx->level ?
279  tctx->section[tctx->level - 1]->id : SECTION_ID_NONE;
280 
281  if (parent_section_id != SECTION_ID_NONE) {
282  tctx->nb_item[tctx->level - 1]++;
283  tctx->nb_item_type[tctx->level - 1][section_id]++;
284  }
285 
286  if (tctx->formatter->print_section_footer)
287  tctx->formatter->print_section_footer(tctx);
288  tctx->level--;
289 }
290 
292 {
293  av_assert0(tctx);
294 
296  return;
297 
301  return;
302 
303  av_assert0(key && tctx->level >= 0 && tctx->level < SECTION_MAX_NB_LEVELS);
304 
305  if (!tctx->is_key_selected || tctx->is_key_selected(tctx, key)) {
306  tctx->formatter->print_integer(tctx, key, val);
307  tctx->nb_item[tctx->level]++;
308  }
309 }
310 
311 static inline int validate_string(AVTextFormatContext *tctx, char **dstp, const char *src)
312 {
313  const uint8_t *p, *endp, *srcp = (const uint8_t *)src;
314  AVBPrint dstbuf;
315  AVBPrint invalid_seq;
316  int invalid_chars_nb = 0, ret = 0;
317 
318  *dstp = NULL;
320  av_bprint_init(&invalid_seq, 0, AV_BPRINT_SIZE_UNLIMITED);
321 
322  endp = srcp + strlen(src);
323  for (p = srcp; *p;) {
324  int32_t code;
325  int invalid = 0;
326  const uint8_t *p0 = p;
327 
328  if (av_utf8_decode(&code, &p, endp, tctx->string_validation_utf8_flags) < 0) {
329 
330  av_bprint_clear(&invalid_seq);
331 
332  bprint_bytes(&invalid_seq, p0, p - p0);
333 
334  av_log(tctx, AV_LOG_DEBUG, "Invalid UTF-8 sequence '%s' found in string '%s'\n", invalid_seq.str, src);
335  invalid = 1;
336  }
337 
338  if (invalid) {
339  invalid_chars_nb++;
340 
341  switch (tctx->string_validation) {
343  av_log(tctx, AV_LOG_ERROR, "Invalid UTF-8 sequence found in string '%s'\n", src);
345  goto end;
346 
348  av_bprintf(&dstbuf, "%s", tctx->string_validation_replacement);
349  break;
350  }
351  }
352 
354  av_bprint_append_data(&dstbuf, p0, p-p0);
355  }
356 
357  if (invalid_chars_nb && tctx->string_validation == AV_TEXTFORMAT_STRING_VALIDATION_REPLACE)
358  av_log(tctx, AV_LOG_WARNING,
359  "%d invalid UTF-8 sequence(s) found in string '%s', replaced with '%s'\n",
360  invalid_chars_nb, src, tctx->string_validation_replacement);
361 
362 end:
363  av_bprint_finalize(&dstbuf, dstp);
364  av_bprint_finalize(&invalid_seq, NULL);
365  return ret;
366 }
367 
368 struct unit_value {
369  union {
370  double d;
372  } val;
373 
374  const char *unit;
375 };
376 
377 static char *value_string(const AVTextFormatContext *tctx, char *buf, int buf_size, struct unit_value uv)
378 {
379  double vald;
380  int64_t vali = 0;
381  int show_float = 0;
382 
383  if (uv.unit == unit_second_str) {
384  vald = uv.val.d;
385  show_float = 1;
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->use_value_prefix && vald > 1) {
404  int64_t index;
405 
406  if (uv.unit == unit_byte_str && tctx->use_byte_value_binary_prefix) {
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 (show_float || (tctx->use_value_prefix && vald != (int64_t)vald))
421  snprintf(buf, buf_size, "%f", vald);
422  else
423  snprintf(buf, buf_size, "%"PRId64, vali);
424 
425  av_strlcatf(buf, buf_size, "%s%s%s", *prefix_string || tctx->show_value_unit ? " " : "",
426  prefix_string, tctx->show_value_unit ? uv.unit : "");
427  }
428 
429  return buf;
430 }
431 
432 
433 void avtext_print_unit_integer(AVTextFormatContext *tctx, const char *key, int64_t val, const char *unit)
434 {
435  char val_str[128];
436  struct unit_value uv;
437  uv.val.i = val;
438  uv.unit = unit;
439  avtext_print_string(tctx, key, value_string(tctx, val_str, sizeof(val_str), uv), 0);
440 }
441 
442 
443 int avtext_print_string(AVTextFormatContext *tctx, const char *key, const char *val, int flags)
444 {
445  const AVTextFormatSection *section;
446  int ret = 0;
447 
448  av_assert0(key && val && tctx->level >= 0 && tctx->level < SECTION_MAX_NB_LEVELS);
449 
450  section = tctx->section[tctx->level];
451 
453  return 0;
454 
458  return 0;
459 
460  if (!tctx->is_key_selected || tctx->is_key_selected(tctx, key)) {
462  char *key1 = NULL, *val1 = NULL;
463  ret = validate_string(tctx, &key1, key);
464  if (ret < 0) goto end;
465  ret = validate_string(tctx, &val1, val);
466  if (ret < 0) goto end;
467  tctx->formatter->print_string(tctx, key1, val1);
468  end:
469  if (ret < 0)
470  av_log(tctx, AV_LOG_ERROR,
471  "Invalid key=value string combination %s=%s in section %s\n",
472  key, val, section->unique_name);
473  av_free(key1);
474  av_free(val1);
475  } else {
476  tctx->formatter->print_string(tctx, key, val);
477  }
478 
479  tctx->nb_item[tctx->level]++;
480  }
481 
482  return ret;
483 }
484 
485 void avtext_print_rational(AVTextFormatContext *tctx, const char *key, AVRational q, char sep)
486 {
487  char buf[44];
488  snprintf(buf, sizeof(buf), "%d%c%d", q.num, sep, q.den);
489  avtext_print_string(tctx, key, buf, 0);
490 }
491 
492 void avtext_print_time(AVTextFormatContext *tctx, const char *key,
493  int64_t ts, const AVRational *time_base, int is_duration)
494 {
495  if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) {
497  } else {
498  char buf[128];
499  double d = av_q2d(*time_base) * ts;
500  struct unit_value uv;
501  uv.val.d = d;
502  uv.unit = unit_second_str;
503  value_string(tctx, buf, sizeof(buf), uv);
504  avtext_print_string(tctx, key, buf, 0);
505  }
506 }
507 
508 void avtext_print_ts(AVTextFormatContext *tctx, const char *key, int64_t ts, int is_duration)
509 {
510  if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0))
512  else
513  avtext_print_integer(tctx, key, ts, 0);
514 }
515 
516 void avtext_print_data(AVTextFormatContext *tctx, const char *key,
517  const uint8_t *data, int size)
518 {
519  AVBPrint bp;
520  unsigned offset = 0;
521  int i;
522 
524  av_bprintf(&bp, "\n");
525  while (size) {
526  av_bprintf(&bp, "%08x: ", offset);
527  int l = FFMIN(size, 16);
528  for (i = 0; i < l; i++) {
529  av_bprintf(&bp, "%02x", data[i]);
530  if (i & 1)
531  av_bprintf(&bp, " ");
532  }
533  av_bprint_chars(&bp, ' ', 41 - 2 * i - i / 2);
534  for (i = 0; i < l; i++)
535  av_bprint_chars(&bp, data[i] - 32U < 95 ? data[i] : '.', 1);
536  av_bprintf(&bp, "\n");
537  offset += l;
538  data += l;
539  size -= l;
540  }
541  avtext_print_string(tctx, key, bp.str, 0);
542  av_bprint_finalize(&bp, NULL);
543 }
544 
546  const uint8_t *data, int size)
547 {
548  char buf[AV_HASH_MAX_SIZE * 2 + 64] = { 0 };
549  int len;
550 
551  if (!tctx->hash)
552  return;
553 
554  av_hash_init(tctx->hash);
555  av_hash_update(tctx->hash, data, size);
556  len = snprintf(buf, sizeof(buf), "%s:", av_hash_get_name(tctx->hash));
557  av_hash_final_hex(tctx->hash, (uint8_t *)&buf[len], (int)sizeof(buf) - len);
558  avtext_print_string(tctx, key, buf, 0);
559 }
560 
561 static const char *writercontext_get_writer_name(void *p)
562 {
563  AVTextWriterContext *wctx = p;
564  return wctx->writer->name;
565 }
566 
567 static void *writercontext_child_next(void *obj, void *prev)
568 {
569  AVTextFormatContext *ctx = obj;
570  if (!prev && ctx->formatter && ctx->formatter->priv_class && ctx->priv)
571  return ctx->priv;
572  return NULL;
573 }
574 
575 static const AVClass textwriter_class = {
576  .class_name = "AVTextWriterContext",
577  .item_name = writercontext_get_writer_name,
578  .version = LIBAVUTIL_VERSION_INT,
579  .child_next = writercontext_child_next,
580 };
581 
582 
584 {
585  AVTextWriterContext *wctx = *pwctx;
586  int ret = 0;
587 
588  if (!wctx)
589  return AVERROR(EINVAL);
590 
591  if (wctx->writer) {
592  if (wctx->writer->uninit)
593  ret = wctx->writer->uninit(wctx);
594  if (wctx->writer->priv_class)
595  av_opt_free(wctx->priv);
596  }
597  av_freep(&wctx->priv);
598  av_freep(pwctx);
599  return ret;
600 }
601 
602 
604 {
605  AVTextWriterContext *wctx;
606  int ret = 0;
607 
608  if (!pwctx || !writer)
609  return AVERROR(EINVAL);
610 
611  if (!((wctx = av_mallocz(sizeof(AVTextWriterContext))))) {
612  ret = AVERROR(ENOMEM);
613  goto fail;
614  }
615 
616  if (writer->priv_size && !((wctx->priv = av_mallocz(writer->priv_size)))) {
617  ret = AVERROR(ENOMEM);
618  goto fail;
619  }
620 
621  if (writer->priv_class) {
622  void *priv_ctx = wctx->priv;
623  *(const AVClass **)priv_ctx = writer->priv_class;
624  av_opt_set_defaults(priv_ctx);
625  }
626 
627  wctx->class = &textwriter_class;
628  wctx->writer = writer;
629 
630  av_opt_set_defaults(wctx);
631 
632 
633  if (wctx->writer->init)
634  ret = wctx->writer->init(wctx);
635  if (ret < 0)
636  goto fail;
637 
638  *pwctx = wctx;
639 
640  return 0;
641 
642 fail:
644  return ret;
645 }
646 
647 static const AVTextFormatter *const registered_formatters[] =
648 {
658  NULL
659 };
660 
662 {
663  for (int i = 0; registered_formatters[i]; i++) {
664  const char *end;
665  if (av_strstart(name, registered_formatters[i]->name, &end) &&
666  (*end == '\0' || *end == '='))
667  return registered_formatters[i];
668  }
669 
670  return NULL;
671 }
AV_OPT_SEARCH_CHILDREN
#define AV_OPT_SEARCH_CHILDREN
Search in possible children of the given object first.
Definition: opt.h:605
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:377
validate_string
static int validate_string(AVTextFormatContext *tctx, char **dstp, const char *src)
Definition: avtextformat.c:311
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:492
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:369
writercontext_get_writer_name
static const char * writercontext_get_writer_name(void *p)
Definition: avtextformat.c:561
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:164
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:508
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
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:371
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:125
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:291
avtextformatter_compact
const AVTextFormatter avtextformatter_compact
Definition: tf_compact.c:239
AV_TEXTFORMAT_STRING_VALIDATION_NB
@ AV_TEXTFORMAT_STRING_VALIDATION_NB
Definition: avtextformat.h:77
AVTextFormatContext::is_key_selected
int(* is_key_selected)(struct AVTextFormatContext *tctx, const char *key)
Callback to discard certain elements based upon the key used.
Definition: avtextformat.h:140
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:143
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:433
AVTextFormatContext
Definition: avtextformat.h:110
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:121
AVTextWriter::uninit
int(* uninit)(AVTextWriterContext *wctx)
Definition: avtextwriters.h:36
macros.h
fail
#define fail()
Definition: checkasm.h:216
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[]
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:165
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:113
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:647
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:249
AVTextFormatter::print_string
void(* print_string)(AVTextFormatContext *tctx, const char *, const char *)
Definition: avtextformat.h:103
textcontext_child_next
static void * textcontext_child_next(void *obj, void *prev)
Definition: avtextformat.c:78
intreadwrite.h
AVTextFormatter
Definition: avtextformat.h:92
SECTION_MAX_NB_SECTIONS
#define SECTION_MAX_NB_SECTIONS
Definition: avtextformat.h:108
avtext_print_data_hash
void avtext_print_data_hash(AVTextFormatContext *tctx, const char *key, const uint8_t *data, int size)
Definition: avtextformat.c:545
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:583
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:116
key
const char * key
Definition: hwcontext_opencl.c:189
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
AVTextFormatter::priv_size
int priv_size
private size for the formatter context
Definition: avtextformat.h:94
AVTextFormatContext::use_byte_value_binary_prefix
int use_byte_value_binary_prefix
Definition: avtextformat.h:145
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:443
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:128
unit_second_str
static const char unit_second_str[]
Definition: avtextformat.c:246
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
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:100
AV_TEXTFORMAT_STRING_VALIDATION_IGNORE
@ AV_TEXTFORMAT_STRING_VALIDATION_IGNORE
Definition: avtextformat.h:76
double
double
Definition: af_crystalizer.c:132
AVTextFormatContext::formatter
const AVTextFormatter * formatter
the AVTextFormatter of which this is an instance
Definition: avtextformat.h:112
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:661
index
int index
Definition: gxfenc.c:90
SECTION_MAX_NB_LEVELS
#define SECTION_MAX_NB_LEVELS
Definition: avtextformat.h:107
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:603
AVTextWriter
Definition: avtextwriters.h:30
unit_hertz_str
static const char unit_hertz_str[]
Definition: avtextformat.c:247
AV_TEXTFORMAT_STRING_VALIDATION_FAIL
@ AV_TEXTFORMAT_STRING_VALIDATION_FAIL
Definition: avtextformat.h:74
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
AVTextFormatter::name
const char * name
Definition: avtextformat.h:95
avtext_print_section_footer
void avtext_print_section_footer(AVTextFormatContext *tctx)
Definition: avtextformat.c:270
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:146
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:129
unit_value
Definition: avtextformat.c:368
SHOW_OPTIONAL_FIELDS_NEVER
#define SHOW_OPTIONAL_FIELDS_NEVER
Definition: avtextformat.c:40
AVTextFormatContext::show_optional_fields
int show_optional_fields
Definition: avtextformat.h:142
AVTextFormatter::flags
int flags
a combination or AV_TEXTFORMAT__FLAG_*
Definition: avtextformat.h:104
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:575
AVTextFormatContext::sections
const AVTextFormatSection * sections
array containing all sections
Definition: avtextformat.h:118
avtext_print_rational
void avtext_print_rational(AVTextFormatContext *tctx, const char *key, AVRational q, char sep)
Definition: avtextformat.c:485
unit_value::unit
const char * unit
Definition: avtextformat.c:374
AVTextFormatContext::class
const AVClass * class
class of the formatter
Definition: avtextformat.h:111
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
AVTextFormatter::uninit
int(* uninit)(AVTextFormatContext *tctx)
Definition: avtextformat.h:98
AVTextFormatContext::string_validation_utf8_flags
unsigned int string_validation_utf8_flags
Definition: avtextformat.h:152
len
int len
Definition: vorbis_enc_data.h:426
writercontext_child_next
static void * writercontext_child_next(void *obj, void *prev)
Definition: avtextformat.c:567
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:101
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:122
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:93
AVTextFormatter::print_integer
void(* print_integer)(AVTextFormatContext *tctx, const char *, int64_t)
Definition: avtextformat.h:102
AVTextFormatContext::string_validation
int string_validation
Definition: avtextformat.h:150
AVRational::den
int den
Denominator.
Definition: rational.h:60
AVTextFormatOptions
Definition: avtextformat.h:155
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:227
sections
static const AVTextFormatSection sections[]
Definition: ffprobe.c:255
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:97
unit_byte_str
static const char unit_byte_str[]
Definition: avtextformat.c:248
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
AVTextFormatContext::use_value_prefix
int use_value_prefix
Definition: avtextformat.h:144
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:124
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:516
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:130
AV_TEXTFORMAT_STRING_VALIDATION_REPLACE
@ AV_TEXTFORMAT_STRING_VALIDATION_REPLACE
Definition: avtextformat.h:75
AVDictionaryEntry::value
char * value
Definition: dict.h:92
show_data_hash
static char * show_data_hash
Definition: ffprobe.c:146
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:69
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:370
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:148
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:119
AVTextFormatContext::hash
struct AVHashContext * hash
Definition: avtextformat.h:148
avtext_print_section_header
void avtext_print_section_header(AVTextFormatContext *tctx, const void *data, int section_id)
Definition: avtextformat.c:252
AVTextFormatContext::string_validation_replacement
char * string_validation_replacement
Definition: avtextformat.h:151