FFmpegKit Linux API  4.5.1
fftools_ffprobe.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007-2010 Stefano Sabatini
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 
26 /*
27  * CHANGES 01.2020
28  * - ffprobe support changes
29  * - Concurrent execution support
30  * - main() function renamed as ffprobe_execute()
31  */
32 
33 #include "config.h"
34 #include "libavutil/ffversion.h"
35 
36 #include <string.h>
37 
38 #include "libavformat/avformat.h"
39 #include "libavcodec/avcodec.h"
40 #include "libavutil/avassert.h"
41 #include "libavutil/avstring.h"
42 #include "libavutil/bprint.h"
43 #include "libavutil/channel_layout.h"
44 #include "libavutil/display.h"
45 #include "libavutil/hash.h"
46 #include "libavutil/hdr_dynamic_metadata.h"
47 #include "libavutil/mastering_display_metadata.h"
48 #include "libavutil/dovi_meta.h"
49 #include "libavutil/opt.h"
50 #include "libavutil/pixdesc.h"
51 #include "libavutil/spherical.h"
52 #include "libavutil/stereo3d.h"
53 #include "libavutil/dict.h"
54 #include "libavutil/intreadwrite.h"
55 #include "libavutil/libm.h"
56 #include "libavutil/parseutils.h"
57 #include "libavutil/timecode.h"
58 #include "libavutil/timestamp.h"
59 #include "libavdevice/avdevice.h"
60 #include "libswscale/swscale.h"
61 #include "libswresample/swresample.h"
62 #include "fftools_cmdutils.h"
63 
64 #include "libavutil/thread.h"
65 
66 #include "ffmpegkit_exception.h"
67 
68 #if !HAVE_THREADS
69 # ifdef pthread_mutex_lock
70 # undef pthread_mutex_lock
71 # endif
72 # define pthread_mutex_lock(a) do{}while(0)
73 # ifdef pthread_mutex_unlock
74 # undef pthread_mutex_unlock
75 # endif
76 # define pthread_mutex_unlock(a) do{}while(0)
77 #endif
78 
79 typedef struct InputStream {
80  AVStream *st;
81 
82  AVCodecContext *dec_ctx;
83 } InputStream;
84 
85 typedef struct InputFile {
86  AVFormatContext *fmt_ctx;
87 
89  int nb_streams;
90 } InputFile;
91 
92 __thread int do_bitexact = 0;
93 __thread int do_count_frames = 0;
94 __thread int do_count_packets = 0;
95 __thread int do_read_frames = 0;
96 __thread int do_read_packets = 0;
97 __thread int do_show_chapters = 0;
98 __thread int do_show_error = 0;
99 __thread int do_show_format = 0;
100 __thread int do_show_frames = 0;
101 __thread int do_show_packets = 0;
102 __thread int do_show_programs = 0;
103 __thread int do_show_streams = 0;
104 __thread int do_show_stream_disposition = 0;
105 __thread int do_show_data = 0;
106 __thread int do_show_program_version = 0;
107 __thread int do_show_library_versions = 0;
108 __thread int do_show_pixel_formats = 0;
109 __thread int do_show_pixel_format_flags = 0;
111 __thread int do_show_log = 0;
112 
113 __thread int do_show_chapter_tags = 0;
114 __thread int do_show_format_tags = 0;
115 __thread int do_show_frame_tags = 0;
116 __thread int do_show_program_tags = 0;
117 __thread int do_show_stream_tags = 0;
118 __thread int do_show_packet_tags = 0;
119 
120 __thread int show_value_unit = 0;
121 __thread int use_value_prefix = 0;
124 __thread int show_private_data = 1;
125 
126 #define SHOW_OPTIONAL_FIELDS_AUTO -1
127 #define SHOW_OPTIONAL_FIELDS_NEVER 0
128 #define SHOW_OPTIONAL_FIELDS_ALWAYS 1
130 
131 __thread char *print_format;
132 __thread char *stream_specifier;
133 __thread char *show_data_hash;
134 
135 typedef struct ReadInterval {
136  int id;
137  int64_t start, end;
141 } ReadInterval;
142 
144 __thread int read_intervals_nb = 0;
145 
146 /* section structure definition */
147 
148 #define SECTION_MAX_NB_CHILDREN 10
149 
150 struct section {
151  int id;
152  const char *name;
153 
154 #define SECTION_FLAG_IS_WRAPPER 1
155 #define SECTION_FLAG_IS_ARRAY 2
156 #define SECTION_FLAG_HAS_VARIABLE_FIELDS 4
157  int flags;
160  const char *element_name;
161  const char *unique_name;
162  AVDictionary *entries_to_show;
164 };
165 
166 typedef enum {
212 } SectionID;
213 
214 static struct section sections[] = {
216  [SECTION_ID_CHAPTER] = { SECTION_ID_CHAPTER, "chapter", 0, { SECTION_ID_CHAPTER_TAGS, -1 } },
217  [SECTION_ID_CHAPTER_TAGS] = { SECTION_ID_CHAPTER_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "chapter_tags" },
218  [SECTION_ID_ERROR] = { SECTION_ID_ERROR, "error", 0, { -1 } },
219  [SECTION_ID_FORMAT] = { SECTION_ID_FORMAT, "format", 0, { SECTION_ID_FORMAT_TAGS, -1 } },
220  [SECTION_ID_FORMAT_TAGS] = { SECTION_ID_FORMAT_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "format_tags" },
223  [SECTION_ID_FRAME_TAGS] = { SECTION_ID_FRAME_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "frame_tags" },
224  [SECTION_ID_FRAME_SIDE_DATA_LIST] ={ SECTION_ID_FRAME_SIDE_DATA_LIST, "side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "frame_side_data_list" },
229  [SECTION_ID_FRAME_LOG] = { SECTION_ID_FRAME_LOG, "log", 0, { -1 }, },
231  [SECTION_ID_LIBRARY_VERSION] = { SECTION_ID_LIBRARY_VERSION, "library_version", 0, { -1 } },
235  [SECTION_ID_PACKET_TAGS] = { SECTION_ID_PACKET_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "packet_tags" },
236  [SECTION_ID_PACKET_SIDE_DATA_LIST] ={ SECTION_ID_PACKET_SIDE_DATA_LIST, "side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "packet_side_data_list" },
237  [SECTION_ID_PACKET_SIDE_DATA] = { SECTION_ID_PACKET_SIDE_DATA, "side_data", 0, { -1 } },
240  [SECTION_ID_PIXEL_FORMAT_FLAGS] = { SECTION_ID_PIXEL_FORMAT_FLAGS, "flags", 0, { -1 }, .unique_name = "pixel_format_flags" },
241  [SECTION_ID_PIXEL_FORMAT_COMPONENTS] = { SECTION_ID_PIXEL_FORMAT_COMPONENTS, "components", SECTION_FLAG_IS_ARRAY, {SECTION_ID_PIXEL_FORMAT_COMPONENT, -1 }, .unique_name = "pixel_format_components" },
243  [SECTION_ID_PROGRAM_STREAM_DISPOSITION] = { SECTION_ID_PROGRAM_STREAM_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "program_stream_disposition" },
244  [SECTION_ID_PROGRAM_STREAM_TAGS] = { SECTION_ID_PROGRAM_STREAM_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "program_stream_tags" },
246  [SECTION_ID_PROGRAM_STREAMS] = { SECTION_ID_PROGRAM_STREAMS, "streams", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PROGRAM_STREAM, -1 }, .unique_name = "program_streams" },
248  [SECTION_ID_PROGRAM_TAGS] = { SECTION_ID_PROGRAM_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "program_tags" },
249  [SECTION_ID_PROGRAM_VERSION] = { SECTION_ID_PROGRAM_VERSION, "program_version", 0, { -1 } },
257  [SECTION_ID_STREAM_DISPOSITION] = { SECTION_ID_STREAM_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "stream_disposition" },
258  [SECTION_ID_STREAM_TAGS] = { SECTION_ID_STREAM_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "stream_tags" },
259  [SECTION_ID_STREAM_SIDE_DATA_LIST] ={ SECTION_ID_STREAM_SIDE_DATA_LIST, "side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "stream_side_data_list" },
260  [SECTION_ID_STREAM_SIDE_DATA] = { SECTION_ID_STREAM_SIDE_DATA, "side_data", 0, { -1 } },
261  [SECTION_ID_SUBTITLE] = { SECTION_ID_SUBTITLE, "subtitle", 0, { -1 } },
262 };
263 
264 __thread OptionDef *ffprobe_options = NULL;
265 
266 /* FFprobe context */
267 __thread const char *input_filename;
268 __thread const char *print_input_filename;
269 __thread const AVInputFormat *iformat = NULL;
270 
271 __thread struct AVHashContext *hash;
272 
273 __thread volatile int main_ffprobe_return_code = 0;
274 extern __thread volatile int longjmp_value;
275 
276 static const struct {
277  double bin_val;
278  double dec_val;
279  const char *bin_str;
280  const char *dec_str;
281 } si_prefixes[] = {
282  { 1.0, 1.0, "", "" },
283  { 1.024e3, 1e3, "Ki", "K" },
284  { 1.048576e6, 1e6, "Mi", "M" },
285  { 1.073741824e9, 1e9, "Gi", "G" },
286  { 1.099511627776e12, 1e12, "Ti", "T" },
287  { 1.125899906842624e15, 1e15, "Pi", "P" },
288 };
289 
290 static const char unit_second_str[] = "s" ;
291 static const char unit_hertz_str[] = "Hz" ;
292 static const char unit_byte_str[] = "byte" ;
293 static const char unit_bit_per_second_str[] = "bit/s";
294 
295 __thread int nb_streams;
296 __thread uint64_t *nb_streams_packets;
297 __thread uint64_t *nb_streams_frames;
298 __thread int *selected_streams;
299 
300 #if HAVE_THREADS
301 __thread pthread_mutex_t log_mutex;
302 #endif
303 typedef struct LogBuffer {
306  char *log_message;
307  AVClassCategory category;
308  char *parent_name;
309  AVClassCategory parent_category;
310 }LogBuffer;
311 
313 __thread int log_buffer_size;
314 
315 static void log_callback(void *ptr, int level, const char *fmt, va_list vl)
316 {
317  AVClass* avc = ptr ? *(AVClass **) ptr : NULL;
318  va_list vl2;
319  char line[1024];
320  static int print_prefix = 1;
321  void *new_log_buffer;
322 
323  va_copy(vl2, vl);
324  av_log_default_callback(ptr, level, fmt, vl);
325  av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix);
326  va_end(vl2);
327 
328 #if HAVE_THREADS
329  pthread_mutex_lock(&log_mutex);
330 
331  new_log_buffer = av_realloc_array(log_buffer, log_buffer_size + 1, sizeof(*log_buffer));
332  if (new_log_buffer) {
333  char *msg;
334  int i;
335 
336  log_buffer = new_log_buffer;
337  memset(&log_buffer[log_buffer_size], 0, sizeof(log_buffer[log_buffer_size]));
338  log_buffer[log_buffer_size].context_name= avc ? av_strdup(avc->item_name(ptr)) : NULL;
339  if (avc) {
340  if (avc->get_category) log_buffer[log_buffer_size].category = avc->get_category(ptr);
341  else log_buffer[log_buffer_size].category = avc->category;
342  }
344  msg = log_buffer[log_buffer_size].log_message = av_strdup(line);
345  for (i=strlen(msg) - 1; i>=0 && msg[i] == '\n'; i--) {
346  msg[i] = 0;
347  }
348  if (avc && avc->parent_log_context_offset) {
349  AVClass** parent = *(AVClass ***) (((uint8_t *) ptr) +
350  avc->parent_log_context_offset);
351  if (parent && *parent) {
352  log_buffer[log_buffer_size].parent_name = av_strdup((*parent)->item_name(parent));
354  (*parent)->get_category ? (*parent)->get_category(parent) :(*parent)->category;
355  }
356  }
357  log_buffer_size ++;
358  }
359 
360  pthread_mutex_unlock(&log_mutex);
361 #endif
362 }
363 
364 static void ffprobe_cleanup(int ret)
365 {
366  int i;
367  for (i = 0; i < FF_ARRAY_ELEMS(sections); i++)
368  av_dict_free(&(sections[i].entries_to_show));
369 
370 #if HAVE_THREADS
371  pthread_mutex_destroy(&log_mutex);
372 #endif
373 }
374 
375 struct unit_value {
376  union { double d; long long int i; } val;
377  const char *unit;
378 };
379 
380 static char *value_string(char *buf, int buf_size, struct unit_value uv)
381 {
382  double vald;
383  long long int vali;
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 = vali = uv.val.i;
391  }
392 
394  double secs;
395  int hours, mins;
396  secs = vald;
397  mins = (int)secs / 60;
398  secs = secs - mins * 60;
399  hours = mins / 60;
400  mins %= 60;
401  snprintf(buf, buf_size, "%d:%02d:%09.6f", hours, mins, secs);
402  } else {
403  const char *prefix_string = "";
404 
405  if (use_value_prefix && vald > 1) {
406  long long int index;
407 
409  index = (long long int) (log2(vald)) / 10;
410  index = av_clip(index, 0, FF_ARRAY_ELEMS(si_prefixes) - 1);
411  vald /= si_prefixes[index].bin_val;
412  prefix_string = si_prefixes[index].bin_str;
413  } else {
414  index = (long long int) (log10(vald)) / 3;
415  index = av_clip(index, 0, FF_ARRAY_ELEMS(si_prefixes) - 1);
416  vald /= si_prefixes[index].dec_val;
417  prefix_string = si_prefixes[index].dec_str;
418  }
419  vali = vald;
420  }
421 
422  if (show_float || (use_value_prefix && vald != (long long int)vald))
423  snprintf(buf, buf_size, "%f", vald);
424  else
425  snprintf(buf, buf_size, "%lld", vali);
426  av_strlcatf(buf, buf_size, "%s%s%s", *prefix_string || show_value_unit ? " " : "",
427  prefix_string, show_value_unit ? uv.unit : "");
428  }
429 
430  return buf;
431 }
432 
433 /* WRITERS API */
434 
436 
437 #define WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS 1
438 #define WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER 2
439 
440 typedef enum {
446 
447 typedef struct Writer {
448  const AVClass *priv_class;
449  int priv_size;
450  const char *name;
451 
452  int (*init) (WriterContext *wctx);
453  void (*uninit)(WriterContext *wctx);
454 
457  void (*print_integer) (WriterContext *wctx, const char *, long long int);
458  void (*print_rational) (WriterContext *wctx, AVRational *q, char *sep);
459  void (*print_string) (WriterContext *wctx, const char *, const char *);
460  int flags;
461 } Writer;
462 
463 #define SECTION_MAX_NB_LEVELS 10
464 
466  const AVClass *class;
467  const Writer *writer;
468  char *name;
469  void *priv;
470 
471  const struct section *sections;
473 
474  int level;
475 
478 
482 
484  unsigned int nb_section_packet;
485  unsigned int nb_section_frame;
486  unsigned int nb_section_packet_frame;
487 
491 };
492 
493 static const char *writer_get_name(void *p)
494 {
495  WriterContext *wctx = p;
496  return wctx->writer->name;
497 }
498 
499 #define OFFSET(x) offsetof(WriterContext, x)
500 
501 static const AVOption writer_options[] = {
502  { "string_validation", "set string validation mode",
503  OFFSET(string_validation), AV_OPT_TYPE_INT, {.i64=WRITER_STRING_VALIDATION_REPLACE}, 0, WRITER_STRING_VALIDATION_NB-1, .unit = "sv" },
504  { "sv", "set string validation mode",
505  OFFSET(string_validation), AV_OPT_TYPE_INT, {.i64=WRITER_STRING_VALIDATION_REPLACE}, 0, WRITER_STRING_VALIDATION_NB-1, .unit = "sv" },
506  { "ignore", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = WRITER_STRING_VALIDATION_IGNORE}, .unit = "sv" },
507  { "replace", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = WRITER_STRING_VALIDATION_REPLACE}, .unit = "sv" },
508  { "fail", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = WRITER_STRING_VALIDATION_FAIL}, .unit = "sv" },
509  { "string_validation_replacement", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, {.str=""}},
510  { "svr", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, {.str="\xEF\xBF\xBD"}},
511  { NULL }
512 };
513 
514 static void *writer_child_next(void *obj, void *prev)
515 {
516  WriterContext *ctx = obj;
517  if (!prev && ctx->writer && ctx->writer->priv_class && ctx->priv)
518  return ctx->priv;
519  return NULL;
520 }
521 
522 static const AVClass writer_class = {
523  .class_name = "Writer",
524  .item_name = writer_get_name,
525  .option = writer_options,
526  .version = LIBAVUTIL_VERSION_INT,
527  .child_next = writer_child_next,
528 };
529 
530 static void writer_close(WriterContext **wctx)
531 {
532  int i;
533 
534  if (!*wctx)
535  return;
536 
537  if ((*wctx)->writer->uninit)
538  (*wctx)->writer->uninit(*wctx);
539  for (i = 0; i < SECTION_MAX_NB_LEVELS; i++)
540  av_bprint_finalize(&(*wctx)->section_pbuf[i], NULL);
541  if ((*wctx)->writer->priv_class)
542  av_opt_free((*wctx)->priv);
543  av_freep(&((*wctx)->priv));
544  av_opt_free(*wctx);
545  av_freep(wctx);
546 }
547 
548 static void bprint_bytes(AVBPrint *bp, const uint8_t *ubuf, size_t ubuf_size)
549 {
550  int i;
551  av_bprintf(bp, "0X");
552  for (i = 0; i < ubuf_size; i++)
553  av_bprintf(bp, "%02X", ubuf[i]);
554 }
555 
556 
557 static int writer_open(WriterContext **wctx, const Writer *writer, const char *args,
558  const struct section *sections, int nb_sections)
559 {
560  int i, ret = 0;
561 
562  if (!(*wctx = av_mallocz(sizeof(WriterContext)))) {
563  ret = AVERROR(ENOMEM);
564  goto fail;
565  }
566 
567  if (!((*wctx)->priv = av_mallocz(writer->priv_size))) {
568  ret = AVERROR(ENOMEM);
569  goto fail;
570  }
571 
572  (*wctx)->class = &writer_class;
573  (*wctx)->writer = writer;
574  (*wctx)->level = -1;
575  (*wctx)->sections = sections;
576  (*wctx)->nb_sections = nb_sections;
577 
578  av_opt_set_defaults(*wctx);
579 
580  if (writer->priv_class) {
581  void *priv_ctx = (*wctx)->priv;
582  *((const AVClass **)priv_ctx) = writer->priv_class;
583  av_opt_set_defaults(priv_ctx);
584  }
585 
586  /* convert options to dictionary */
587  if (args) {
588  AVDictionary *opts = NULL;
589  AVDictionaryEntry *opt = NULL;
590 
591  if ((ret = av_dict_parse_string(&opts, args, "=", ":", 0)) < 0) {
592  av_log(*wctx, AV_LOG_ERROR, "Failed to parse option string '%s' provided to writer context\n", args);
593  av_dict_free(&opts);
594  goto fail;
595  }
596 
597  while ((opt = av_dict_get(opts, "", opt, AV_DICT_IGNORE_SUFFIX))) {
598  if ((ret = av_opt_set(*wctx, opt->key, opt->value, AV_OPT_SEARCH_CHILDREN)) < 0) {
599  av_log(*wctx, AV_LOG_ERROR, "Failed to set option '%s' with value '%s' provided to writer context\n",
600  opt->key, opt->value);
601  av_dict_free(&opts);
602  goto fail;
603  }
604  }
605 
606  av_dict_free(&opts);
607  }
608 
609  /* validate replace string */
610  {
611  const uint8_t *p = (*wctx)->string_validation_replacement;
612  const uint8_t *endp = p + strlen(p);
613  while (*p) {
614  const uint8_t *p0 = p;
615  int32_t code;
616  ret = av_utf8_decode(&code, &p, endp, (*wctx)->string_validation_utf8_flags);
617  if (ret < 0) {
618  AVBPrint bp;
619  av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
620  bprint_bytes(&bp, p0, p-p0),
621  av_log(wctx, AV_LOG_ERROR,
622  "Invalid UTF8 sequence %s found in string validation replace '%s'\n",
623  bp.str, (*wctx)->string_validation_replacement);
624  return ret;
625  }
626  }
627  }
628 
629  for (i = 0; i < SECTION_MAX_NB_LEVELS; i++)
630  av_bprint_init(&(*wctx)->section_pbuf[i], 1, AV_BPRINT_SIZE_UNLIMITED);
631 
632  if ((*wctx)->writer->init)
633  ret = (*wctx)->writer->init(*wctx);
634  if (ret < 0)
635  goto fail;
636 
637  return 0;
638 
639 fail:
640  writer_close(wctx);
641  return ret;
642 }
643 
645  int section_id)
646 {
647  int parent_section_id;
648  wctx->level++;
649  av_assert0(wctx->level < SECTION_MAX_NB_LEVELS);
650  parent_section_id = wctx->level ?
651  (wctx->section[wctx->level-1])->id : SECTION_ID_NONE;
652 
653  wctx->nb_item[wctx->level] = 0;
654  wctx->section[wctx->level] = &wctx->sections[section_id];
655 
656  if (section_id == SECTION_ID_PACKETS_AND_FRAMES) {
657  wctx->nb_section_packet = wctx->nb_section_frame =
658  wctx->nb_section_packet_frame = 0;
659  } else if (parent_section_id == SECTION_ID_PACKETS_AND_FRAMES) {
660  wctx->nb_section_packet_frame = section_id == SECTION_ID_PACKET ?
661  wctx->nb_section_packet : wctx->nb_section_frame;
662  }
663 
664  if (wctx->writer->print_section_header)
665  wctx->writer->print_section_header(wctx);
666 }
667 
669 {
670  int section_id = wctx->section[wctx->level]->id;
671  int parent_section_id = wctx->level ?
672  wctx->section[wctx->level-1]->id : SECTION_ID_NONE;
673 
674  if (parent_section_id != SECTION_ID_NONE)
675  wctx->nb_item[wctx->level-1]++;
676  if (parent_section_id == SECTION_ID_PACKETS_AND_FRAMES) {
677  if (section_id == SECTION_ID_PACKET) wctx->nb_section_packet++;
678  else wctx->nb_section_frame++;
679  }
680  if (wctx->writer->print_section_footer)
681  wctx->writer->print_section_footer(wctx);
682  wctx->level--;
683 }
684 
685 static inline void writer_print_integer(WriterContext *wctx,
686  const char *key, long long int val)
687 {
688  const struct section *section = wctx->section[wctx->level];
689 
690  if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) {
691  wctx->writer->print_integer(wctx, key, val);
692  wctx->nb_item[wctx->level]++;
693  }
694 }
695 
696 static inline int validate_string(WriterContext *wctx, char **dstp, const char *src)
697 {
698  const uint8_t *p, *endp;
699  AVBPrint dstbuf;
700  int invalid_chars_nb = 0, ret = 0;
701 
702  av_bprint_init(&dstbuf, 0, AV_BPRINT_SIZE_UNLIMITED);
703 
704  endp = src + strlen(src);
705  for (p = (uint8_t *)src; *p;) {
706  uint32_t code;
707  int invalid = 0;
708  const uint8_t *p0 = p;
709 
710  if (av_utf8_decode(&code, &p, endp, wctx->string_validation_utf8_flags) < 0) {
711  AVBPrint bp;
712  av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
713  bprint_bytes(&bp, p0, p-p0);
714  av_log(wctx, AV_LOG_DEBUG,
715  "Invalid UTF-8 sequence %s found in string '%s'\n", bp.str, src);
716  invalid = 1;
717  }
718 
719  if (invalid) {
720  invalid_chars_nb++;
721 
722  switch (wctx->string_validation) {
724  av_log(wctx, AV_LOG_ERROR,
725  "Invalid UTF-8 sequence found in string '%s'\n", src);
726  ret = AVERROR_INVALIDDATA;
727  goto end;
728  break;
729 
731  av_bprintf(&dstbuf, "%s", wctx->string_validation_replacement);
732  break;
733  }
734  }
735 
736  if (!invalid || wctx->string_validation == WRITER_STRING_VALIDATION_IGNORE)
737  av_bprint_append_data(&dstbuf, p0, p-p0);
738  }
739 
740  if (invalid_chars_nb && wctx->string_validation == WRITER_STRING_VALIDATION_REPLACE) {
741  av_log(wctx, AV_LOG_WARNING,
742  "%d invalid UTF-8 sequence(s) found in string '%s', replaced with '%s'\n",
743  invalid_chars_nb, src, wctx->string_validation_replacement);
744  }
745 
746 end:
747  av_bprint_finalize(&dstbuf, dstp);
748  return ret;
749 }
750 
751 #define PRINT_STRING_OPT 1
752 #define PRINT_STRING_VALIDATE 2
753 
754 static inline int writer_print_string(WriterContext *wctx,
755  const char *key, const char *val, int flags)
756 {
757  const struct section *section = wctx->section[wctx->level];
758  int ret = 0;
759 
762  && (flags & PRINT_STRING_OPT)
764  return 0;
765 
766  if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) {
768  char *key1 = NULL, *val1 = NULL;
769  ret = validate_string(wctx, &key1, key);
770  if (ret < 0) goto end;
771  ret = validate_string(wctx, &val1, val);
772  if (ret < 0) goto end;
773  wctx->writer->print_string(wctx, key1, val1);
774  end:
775  if (ret < 0) {
776  av_log(wctx, AV_LOG_ERROR,
777  "Invalid key=value string combination %s=%s in section %s\n",
778  key, val, section->unique_name);
779  }
780  av_free(key1);
781  av_free(val1);
782  } else {
783  wctx->writer->print_string(wctx, key, val);
784  }
785 
786  wctx->nb_item[wctx->level]++;
787  }
788 
789  return ret;
790 }
791 
792 static inline void writer_print_rational(WriterContext *wctx,
793  const char *key, AVRational q, char sep)
794 {
795  AVBPrint buf;
796  av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
797  av_bprintf(&buf, "%d%c%d", q.num, sep, q.den);
798  writer_print_string(wctx, key, buf.str, 0);
799 }
800 
801 static void writer_print_time(WriterContext *wctx, const char *key,
802  int64_t ts, const AVRational *time_base, int is_duration)
803 {
804  char buf[128];
805 
806  if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) {
807  writer_print_string(wctx, key, "N/A", PRINT_STRING_OPT);
808  } else {
809  double d = ts * av_q2d(*time_base);
810  struct unit_value uv;
811  uv.val.d = d;
812  uv.unit = unit_second_str;
813  value_string(buf, sizeof(buf), uv);
814  writer_print_string(wctx, key, buf, 0);
815  }
816 }
817 
818 static void writer_print_ts(WriterContext *wctx, const char *key, int64_t ts, int is_duration)
819 {
820  if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) {
821  writer_print_string(wctx, key, "N/A", PRINT_STRING_OPT);
822  } else {
823  writer_print_integer(wctx, key, ts);
824  }
825 }
826 
827 static void writer_print_data(WriterContext *wctx, const char *name,
828  uint8_t *data, int size)
829 {
830  AVBPrint bp;
831  int offset = 0, l, i;
832 
833  av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
834  av_bprintf(&bp, "\n");
835  while (size) {
836  av_bprintf(&bp, "%08x: ", offset);
837  l = FFMIN(size, 16);
838  for (i = 0; i < l; i++) {
839  av_bprintf(&bp, "%02x", data[i]);
840  if (i & 1)
841  av_bprintf(&bp, " ");
842  }
843  av_bprint_chars(&bp, ' ', 41 - 2 * i - i / 2);
844  for (i = 0; i < l; i++)
845  av_bprint_chars(&bp, data[i] - 32U < 95 ? data[i] : '.', 1);
846  av_bprintf(&bp, "\n");
847  offset += l;
848  data += l;
849  size -= l;
850  }
851  writer_print_string(wctx, name, bp.str, 0);
852  av_bprint_finalize(&bp, NULL);
853 }
854 
855 static void writer_print_data_hash(WriterContext *wctx, const char *name,
856  uint8_t *data, int size)
857 {
858  char *p, buf[AV_HASH_MAX_SIZE * 2 + 64] = { 0 };
859 
860  if (!hash)
861  return;
862  av_hash_init(hash);
863  av_hash_update(hash, data, size);
864  snprintf(buf, sizeof(buf), "%s:", av_hash_get_name(hash));
865  p = buf + strlen(buf);
866  av_hash_final_hex(hash, p, buf + sizeof(buf) - p);
867  writer_print_string(wctx, name, buf, 0);
868 }
869 
870 static void writer_print_integers(WriterContext *wctx, const char *name,
871  uint8_t *data, int size, const char *format,
872  int columns, int bytes, int offset_add)
873 {
874  AVBPrint bp;
875  int offset = 0, l, i;
876 
877  av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
878  av_bprintf(&bp, "\n");
879  while (size) {
880  av_bprintf(&bp, "%08x: ", offset);
881  l = FFMIN(size, columns);
882  for (i = 0; i < l; i++) {
883  if (bytes == 1) av_bprintf(&bp, format, *data);
884  else if (bytes == 2) av_bprintf(&bp, format, AV_RN16(data));
885  else if (bytes == 4) av_bprintf(&bp, format, AV_RN32(data));
886  data += bytes;
887  size --;
888  }
889  av_bprintf(&bp, "\n");
890  offset += offset_add;
891  }
892  writer_print_string(wctx, name, bp.str, 0);
893  av_bprint_finalize(&bp, NULL);
894 }
895 
896 #define MAX_REGISTERED_WRITERS_NB 64
897 
899 
900 __thread int next_registered_writer_idx = 0;
901 
902 static int writer_register(const Writer *writer)
903 {
905  return AVERROR(ENOMEM);
906 
908  return 0;
909 }
910 
911 static const Writer *writer_get_by_name(const char *name)
912 {
913  int i;
914 
915  for (i = 0; registered_writers[i]; i++)
916  if (!strcmp(registered_writers[i]->name, name))
917  return registered_writers[i];
918 
919  return NULL;
920 }
921 
922 
923 /* WRITERS */
924 
925 #define DEFINE_WRITER_CLASS(name) \
926 static const char *name##_get_name(void *ctx) \
927 { \
928  return #name ; \
929 } \
930 static const AVClass name##_class = { \
931  .class_name = #name, \
932  .item_name = name##_get_name, \
933  .option = name##_options \
934 }
935 
936 /* Default output */
937 
938 typedef struct DefaultContext {
939  const AVClass *class;
940  int nokey;
944 
945 #undef OFFSET
946 #define OFFSET(x) offsetof(DefaultContext, x)
947 
948 static const AVOption default_options[] = {
949  { "noprint_wrappers", "do not print headers and footers", OFFSET(noprint_wrappers), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
950  { "nw", "do not print headers and footers", OFFSET(noprint_wrappers), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
951  { "nokey", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
952  { "nk", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
953  {NULL},
954 };
955 
956 DEFINE_WRITER_CLASS(default);
957 
958 /* lame uppercasing routine, assumes the string is lower case ASCII */
959 static inline char *upcase_string(char *dst, size_t dst_size, const char *src)
960 {
961  int i;
962  for (i = 0; src[i] && i < dst_size-1; i++)
963  dst[i] = av_toupper(src[i]);
964  dst[i] = 0;
965  return dst;
966 }
967 
969 {
970  DefaultContext *def = wctx->priv;
971  char buf[32];
972  const struct section *section = wctx->section[wctx->level];
973  const struct section *parent_section = wctx->level ?
974  wctx->section[wctx->level-1] : NULL;
975 
976  av_bprint_clear(&wctx->section_pbuf[wctx->level]);
977  if (parent_section &&
978  !(parent_section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY))) {
979  def->nested_section[wctx->level] = 1;
980  av_bprintf(&wctx->section_pbuf[wctx->level], "%s%s:",
981  wctx->section_pbuf[wctx->level-1].str,
982  upcase_string(buf, sizeof(buf),
983  av_x_if_null(section->element_name, section->name)));
984  }
985 
986  if (def->noprint_wrappers || def->nested_section[wctx->level])
987  return;
988 
990  av_log(NULL, AV_LOG_STDERR, "[%s]\n", upcase_string(buf, sizeof(buf), section->name));
991 }
992 
994 {
995  DefaultContext *def = wctx->priv;
996  const struct section *section = wctx->section[wctx->level];
997  char buf[32];
998 
999  if (def->noprint_wrappers || def->nested_section[wctx->level])
1000  return;
1001 
1003  av_log(NULL, AV_LOG_STDERR, "[/%s]\n", upcase_string(buf, sizeof(buf), section->name));
1004 }
1005 
1006 static void default_print_str(WriterContext *wctx, const char *key, const char *value)
1007 {
1008  DefaultContext *def = wctx->priv;
1009 
1010  if (!def->nokey)
1011  av_log(NULL, AV_LOG_STDERR, "%s%s=", wctx->section_pbuf[wctx->level].str, key);
1012  av_log(NULL, AV_LOG_STDERR, "%s\n", value);
1013 }
1014 
1015 static void default_print_int(WriterContext *wctx, const char *key, long long int value)
1016 {
1017  DefaultContext *def = wctx->priv;
1018 
1019  if (!def->nokey)
1020  av_log(NULL, AV_LOG_STDERR, "%s%s=", wctx->section_pbuf[wctx->level].str, key);
1021  av_log(NULL, AV_LOG_STDERR, "%lld\n", value);
1022 }
1023 
1024 static const Writer default_writer = {
1025  .name = "default",
1026  .priv_size = sizeof(DefaultContext),
1029  .print_integer = default_print_int,
1030  .print_string = default_print_str,
1032  .priv_class = &default_class,
1033 };
1034 
1035 /* Compact output */
1036 
1040 static const char *c_escape_str(AVBPrint *dst, const char *src, const char sep, void *log_ctx)
1041 {
1042  const char *p;
1043 
1044  for (p = src; *p; p++) {
1045  switch (*p) {
1046  case '\b': av_bprintf(dst, "%s", "\\b"); break;
1047  case '\f': av_bprintf(dst, "%s", "\\f"); break;
1048  case '\n': av_bprintf(dst, "%s", "\\n"); break;
1049  case '\r': av_bprintf(dst, "%s", "\\r"); break;
1050  case '\\': av_bprintf(dst, "%s", "\\\\"); break;
1051  default:
1052  if (*p == sep)
1053  av_bprint_chars(dst, '\\', 1);
1054  av_bprint_chars(dst, *p, 1);
1055  }
1056  }
1057  return dst->str;
1058 }
1059 
1063 static const char *csv_escape_str(AVBPrint *dst, const char *src, const char sep, void *log_ctx)
1064 {
1065  char meta_chars[] = { sep, '"', '\n', '\r', '\0' };
1066  int needs_quoting = !!src[strcspn(src, meta_chars)];
1067 
1068  if (needs_quoting)
1069  av_bprint_chars(dst, '"', 1);
1070 
1071  for (; *src; src++) {
1072  if (*src == '"')
1073  av_bprint_chars(dst, '"', 1);
1074  av_bprint_chars(dst, *src, 1);
1075  }
1076  if (needs_quoting)
1077  av_bprint_chars(dst, '"', 1);
1078  return dst->str;
1079 }
1080 
1081 static const char *none_escape_str(AVBPrint *dst, const char *src, const char sep, void *log_ctx)
1082 {
1083  return src;
1084 }
1085 
1086 typedef struct CompactContext {
1087  const AVClass *class;
1089  char item_sep;
1090  int nokey;
1093  const char * (*escape_str)(AVBPrint *dst, const char *src, const char sep, void *log_ctx);
1097 } CompactContext;
1098 
1099 #undef OFFSET
1100 #define OFFSET(x) offsetof(CompactContext, x)
1101 
1102 static const AVOption compact_options[]= {
1103  {"item_sep", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str="|"}, 0, 0 },
1104  {"s", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str="|"}, 0, 0 },
1105  {"nokey", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
1106  {"nk", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
1107  {"escape", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="c"}, 0, 0 },
1108  {"e", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="c"}, 0, 0 },
1109  {"print_section", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
1110  {"p", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
1111  {NULL},
1112 };
1113 
1114 DEFINE_WRITER_CLASS(compact);
1115 
1116 static av_cold int compact_init(WriterContext *wctx)
1117 {
1118  CompactContext *compact = wctx->priv;
1119 
1120  if (strlen(compact->item_sep_str) != 1) {
1121  av_log(wctx, AV_LOG_ERROR, "Item separator '%s' specified, but must contain a single character\n",
1122  compact->item_sep_str);
1123  return AVERROR(EINVAL);
1124  }
1125  compact->item_sep = compact->item_sep_str[0];
1126 
1127  if (!strcmp(compact->escape_mode_str, "none")) compact->escape_str = none_escape_str;
1128  else if (!strcmp(compact->escape_mode_str, "c" )) compact->escape_str = c_escape_str;
1129  else if (!strcmp(compact->escape_mode_str, "csv" )) compact->escape_str = csv_escape_str;
1130  else {
1131  av_log(wctx, AV_LOG_ERROR, "Unknown escape mode '%s'\n", compact->escape_mode_str);
1132  return AVERROR(EINVAL);
1133  }
1134 
1135  return 0;
1136 }
1137 
1139 {
1140  CompactContext *compact = wctx->priv;
1141  const struct section *section = wctx->section[wctx->level];
1142  const struct section *parent_section = wctx->level ?
1143  wctx->section[wctx->level-1] : NULL;
1144  compact->terminate_line[wctx->level] = 1;
1145  compact->has_nested_elems[wctx->level] = 0;
1146 
1147  av_bprint_clear(&wctx->section_pbuf[wctx->level]);
1148  if (!(section->flags & SECTION_FLAG_IS_ARRAY) && parent_section &&
1149  !(parent_section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY))) {
1150  compact->nested_section[wctx->level] = 1;
1151  compact->has_nested_elems[wctx->level-1] = 1;
1152  av_bprintf(&wctx->section_pbuf[wctx->level], "%s%s:",
1153  wctx->section_pbuf[wctx->level-1].str,
1154  (char *)av_x_if_null(section->element_name, section->name));
1155  wctx->nb_item[wctx->level] = wctx->nb_item[wctx->level-1];
1156  } else {
1157  if (parent_section && compact->has_nested_elems[wctx->level-1] &&
1159  compact->terminate_line[wctx->level-1] = 0;
1160  av_log(NULL, AV_LOG_STDERR, "\n");
1161  }
1162  if (compact->print_section &&
1164  av_log(NULL, AV_LOG_STDERR, "%s%c", section->name, compact->item_sep);
1165  }
1166 }
1167 
1169 {
1170  CompactContext *compact = wctx->priv;
1171 
1172  if (!compact->nested_section[wctx->level] &&
1173  compact->terminate_line[wctx->level] &&
1175  av_log(NULL, AV_LOG_STDERR, "\n");
1176 }
1177 
1178 static void compact_print_str(WriterContext *wctx, const char *key, const char *value)
1179 {
1180  CompactContext *compact = wctx->priv;
1181  AVBPrint buf;
1182 
1183  if (wctx->nb_item[wctx->level]) av_log(NULL, AV_LOG_STDERR, "%c", compact->item_sep);
1184  if (!compact->nokey)
1185  av_log(NULL, AV_LOG_STDERR, "%s%s=", wctx->section_pbuf[wctx->level].str, key);
1186  av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
1187  av_log(NULL, AV_LOG_STDERR, "%s", compact->escape_str(&buf, value, compact->item_sep, wctx));
1188  av_bprint_finalize(&buf, NULL);
1189 }
1190 
1191 static void compact_print_int(WriterContext *wctx, const char *key, long long int value)
1192 {
1193  CompactContext *compact = wctx->priv;
1194 
1195  if (wctx->nb_item[wctx->level]) av_log(NULL, AV_LOG_STDERR, "%c", compact->item_sep);
1196  if (!compact->nokey)
1197  av_log(NULL, AV_LOG_STDERR, "%s%s=", wctx->section_pbuf[wctx->level].str, key);
1198  av_log(NULL, AV_LOG_STDERR, "%lld", value);
1199 }
1200 
1201 static const Writer compact_writer = {
1202  .name = "compact",
1203  .priv_size = sizeof(CompactContext),
1204  .init = compact_init,
1207  .print_integer = compact_print_int,
1208  .print_string = compact_print_str,
1210  .priv_class = &compact_class,
1211 };
1212 
1213 /* CSV output */
1214 
1215 #undef OFFSET
1216 #define OFFSET(x) offsetof(CompactContext, x)
1217 
1218 static const AVOption csv_options[] = {
1219  {"item_sep", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str=","}, 0, 0 },
1220  {"s", "set item separator", OFFSET(item_sep_str), AV_OPT_TYPE_STRING, {.str=","}, 0, 0 },
1221  {"nokey", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
1222  {"nk", "force no key printing", OFFSET(nokey), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
1223  {"escape", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="csv"}, 0, 0 },
1224  {"e", "set escape mode", OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="csv"}, 0, 0 },
1225  {"print_section", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
1226  {"p", "print section name", OFFSET(print_section), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
1227  {NULL},
1228 };
1229 
1230 DEFINE_WRITER_CLASS(csv);
1231 
1232 static const Writer csv_writer = {
1233  .name = "csv",
1234  .priv_size = sizeof(CompactContext),
1235  .init = compact_init,
1238  .print_integer = compact_print_int,
1239  .print_string = compact_print_str,
1241  .priv_class = &csv_class,
1242 };
1243 
1244 /* Flat output */
1245 
1246 typedef struct FlatContext {
1247  const AVClass *class;
1248  const char *sep_str;
1249  char sep;
1251 } FlatContext;
1252 
1253 #undef OFFSET
1254 #define OFFSET(x) offsetof(FlatContext, x)
1255 
1256 static const AVOption flat_options[]= {
1257  {"sep_char", "set separator", OFFSET(sep_str), AV_OPT_TYPE_STRING, {.str="."}, 0, 0 },
1258  {"s", "set separator", OFFSET(sep_str), AV_OPT_TYPE_STRING, {.str="."}, 0, 0 },
1259  {"hierarchical", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
1260  {"h", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
1261  {NULL},
1262 };
1263 
1264 DEFINE_WRITER_CLASS(flat);
1265 
1266 static av_cold int flat_init(WriterContext *wctx)
1267 {
1268  FlatContext *flat = wctx->priv;
1269 
1270  if (strlen(flat->sep_str) != 1) {
1271  av_log(wctx, AV_LOG_ERROR, "Item separator '%s' specified, but must contain a single character\n",
1272  flat->sep_str);
1273  return AVERROR(EINVAL);
1274  }
1275  flat->sep = flat->sep_str[0];
1276 
1277  return 0;
1278 }
1279 
1280 static const char *flat_escape_key_str(AVBPrint *dst, const char *src, const char sep)
1281 {
1282  const char *p;
1283 
1284  for (p = src; *p; p++) {
1285  if (!((*p >= '0' && *p <= '9') ||
1286  (*p >= 'a' && *p <= 'z') ||
1287  (*p >= 'A' && *p <= 'Z')))
1288  av_bprint_chars(dst, '_', 1);
1289  else
1290  av_bprint_chars(dst, *p, 1);
1291  }
1292  return dst->str;
1293 }
1294 
1295 static const char *flat_escape_value_str(AVBPrint *dst, const char *src)
1296 {
1297  const char *p;
1298 
1299  for (p = src; *p; p++) {
1300  switch (*p) {
1301  case '\n': av_bprintf(dst, "%s", "\\n"); break;
1302  case '\r': av_bprintf(dst, "%s", "\\r"); break;
1303  case '\\': av_bprintf(dst, "%s", "\\\\"); break;
1304  case '"': av_bprintf(dst, "%s", "\\\""); break;
1305  case '`': av_bprintf(dst, "%s", "\\`"); break;
1306  case '$': av_bprintf(dst, "%s", "\\$"); break;
1307  default: av_bprint_chars(dst, *p, 1); break;
1308  }
1309  }
1310  return dst->str;
1311 }
1312 
1314 {
1315  FlatContext *flat = wctx->priv;
1316  AVBPrint *buf = &wctx->section_pbuf[wctx->level];
1317  const struct section *section = wctx->section[wctx->level];
1318  const struct section *parent_section = wctx->level ?
1319  wctx->section[wctx->level-1] : NULL;
1320 
1321  /* build section header */
1322  av_bprint_clear(buf);
1323  if (!parent_section)
1324  return;
1325  av_bprintf(buf, "%s", wctx->section_pbuf[wctx->level-1].str);
1326 
1327  if (flat->hierarchical ||
1329  av_bprintf(buf, "%s%s", wctx->section[wctx->level]->name, flat->sep_str);
1330 
1331  if (parent_section->flags & SECTION_FLAG_IS_ARRAY) {
1332  int n = parent_section->id == SECTION_ID_PACKETS_AND_FRAMES ?
1333  wctx->nb_section_packet_frame : wctx->nb_item[wctx->level-1];
1334  av_bprintf(buf, "%d%s", n, flat->sep_str);
1335  }
1336  }
1337 }
1338 
1339 static void flat_print_int(WriterContext *wctx, const char *key, long long int value)
1340 {
1341  av_log(NULL, AV_LOG_STDERR, "%s%s=%lld\n", wctx->section_pbuf[wctx->level].str, key, value);
1342 }
1343 
1344 static void flat_print_str(WriterContext *wctx, const char *key, const char *value)
1345 {
1346  FlatContext *flat = wctx->priv;
1347  AVBPrint buf;
1348 
1349  av_log(NULL, AV_LOG_STDERR, "%s", wctx->section_pbuf[wctx->level].str);
1350  av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
1351  av_log(NULL, AV_LOG_STDERR, "%s=", flat_escape_key_str(&buf, key, flat->sep));
1352  av_bprint_clear(&buf);
1353  av_log(NULL, AV_LOG_STDERR, "\"%s\"\n", flat_escape_value_str(&buf, value));
1354  av_bprint_finalize(&buf, NULL);
1355 }
1356 
1357 static const Writer flat_writer = {
1358  .name = "flat",
1359  .priv_size = sizeof(FlatContext),
1360  .init = flat_init,
1362  .print_integer = flat_print_int,
1363  .print_string = flat_print_str,
1365  .priv_class = &flat_class,
1366 };
1367 
1368 /* INI format output */
1369 
1370 typedef struct INIContext {
1371  const AVClass *class;
1373 } INIContext;
1374 
1375 #undef OFFSET
1376 #define OFFSET(x) offsetof(INIContext, x)
1377 
1378 static const AVOption ini_options[] = {
1379  {"hierarchical", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
1380  {"h", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
1381  {NULL},
1382 };
1383 
1384 DEFINE_WRITER_CLASS(ini);
1385 
1386 static char *ini_escape_str(AVBPrint *dst, const char *src)
1387 {
1388  int i = 0;
1389  char c = 0;
1390 
1391  while ((c = src[i++])) {
1392  switch (c) {
1393  case '\b': av_bprintf(dst, "%s", "\\b"); break;
1394  case '\f': av_bprintf(dst, "%s", "\\f"); break;
1395  case '\n': av_bprintf(dst, "%s", "\\n"); break;
1396  case '\r': av_bprintf(dst, "%s", "\\r"); break;
1397  case '\t': av_bprintf(dst, "%s", "\\t"); break;
1398  case '\\':
1399  case '#' :
1400  case '=' :
1401  case ':' : av_bprint_chars(dst, '\\', 1);
1402  default:
1403  if ((unsigned char)c < 32)
1404  av_bprintf(dst, "\\x00%02x", c & 0xff);
1405  else
1406  av_bprint_chars(dst, c, 1);
1407  break;
1408  }
1409  }
1410  return dst->str;
1411 }
1412 
1414 {
1415  INIContext *ini = wctx->priv;
1416  AVBPrint *buf = &wctx->section_pbuf[wctx->level];
1417  const struct section *section = wctx->section[wctx->level];
1418  const struct section *parent_section = wctx->level ?
1419  wctx->section[wctx->level-1] : NULL;
1420 
1421  av_bprint_clear(buf);
1422  if (!parent_section) {
1423  av_log(NULL, AV_LOG_STDERR, "# ffprobe output\n\n");
1424  return;
1425  }
1426 
1427  if (wctx->nb_item[wctx->level-1])
1428  av_log(NULL, AV_LOG_STDERR, "\n");
1429 
1430  av_bprintf(buf, "%s", wctx->section_pbuf[wctx->level-1].str);
1431  if (ini->hierarchical ||
1433  av_bprintf(buf, "%s%s", buf->str[0] ? "." : "", wctx->section[wctx->level]->name);
1434 
1435  if (parent_section->flags & SECTION_FLAG_IS_ARRAY) {
1436  int n = parent_section->id == SECTION_ID_PACKETS_AND_FRAMES ?
1437  wctx->nb_section_packet_frame : wctx->nb_item[wctx->level-1];
1438  av_bprintf(buf, ".%d", n);
1439  }
1440  }
1441 
1443  av_log(NULL, AV_LOG_STDERR, "[%s]\n", buf->str);
1444 }
1445 
1446 static void ini_print_str(WriterContext *wctx, const char *key, const char *value)
1447 {
1448  AVBPrint buf;
1449 
1450  av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
1451  av_log(NULL, AV_LOG_STDERR, "%s=", ini_escape_str(&buf, key));
1452  av_bprint_clear(&buf);
1453  av_log(NULL, AV_LOG_STDERR, "%s\n", ini_escape_str(&buf, value));
1454  av_bprint_finalize(&buf, NULL);
1455 }
1456 
1457 static void ini_print_int(WriterContext *wctx, const char *key, long long int value)
1458 {
1459  av_log(NULL, AV_LOG_STDERR, "%s=%lld\n", key, value);
1460 }
1461 
1462 static const Writer ini_writer = {
1463  .name = "ini",
1464  .priv_size = sizeof(INIContext),
1466  .print_integer = ini_print_int,
1467  .print_string = ini_print_str,
1469  .priv_class = &ini_class,
1470 };
1471 
1472 /* JSON output */
1473 
1474 typedef struct JSONContext {
1475  const AVClass *class;
1477  int compact;
1478  const char *item_sep, *item_start_end;
1479 } JSONContext;
1480 
1481 #undef OFFSET
1482 #define OFFSET(x) offsetof(JSONContext, x)
1483 
1484 static const AVOption json_options[]= {
1485  { "compact", "enable compact output", OFFSET(compact), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
1486  { "c", "enable compact output", OFFSET(compact), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
1487  { NULL }
1488 };
1489 
1490 DEFINE_WRITER_CLASS(json);
1491 
1492 static av_cold int json_init(WriterContext *wctx)
1493 {
1494  JSONContext *json = wctx->priv;
1495 
1496  json->item_sep = json->compact ? ", " : ",\n";
1497  json->item_start_end = json->compact ? " " : "\n";
1498 
1499  return 0;
1500 }
1501 
1502 static const char *json_escape_str(AVBPrint *dst, const char *src, void *log_ctx)
1503 {
1504  static const char json_escape[] = {'"', '\\', '\b', '\f', '\n', '\r', '\t', 0};
1505  static const char json_subst[] = {'"', '\\', 'b', 'f', 'n', 'r', 't', 0};
1506  const char *p;
1507 
1508  for (p = src; *p; p++) {
1509  char *s = strchr(json_escape, *p);
1510  if (s) {
1511  av_bprint_chars(dst, '\\', 1);
1512  av_bprint_chars(dst, json_subst[s - json_escape], 1);
1513  } else if ((unsigned char)*p < 32) {
1514  av_bprintf(dst, "\\u00%02x", *p & 0xff);
1515  } else {
1516  av_bprint_chars(dst, *p, 1);
1517  }
1518  }
1519  return dst->str;
1520 }
1521 
1522 #define JSON_INDENT() av_log(NULL, AV_LOG_STDERR, "%*c", json->indent_level * 4, ' ')
1523 
1525 {
1526  JSONContext *json = wctx->priv;
1527  AVBPrint buf;
1528  const struct section *section = wctx->section[wctx->level];
1529  const struct section *parent_section = wctx->level ?
1530  wctx->section[wctx->level-1] : NULL;
1531 
1532  if (wctx->level && wctx->nb_item[wctx->level-1])
1533  av_log(NULL, AV_LOG_STDERR, ",\n");
1534 
1536  av_log(NULL, AV_LOG_STDERR, "{\n");
1537  json->indent_level++;
1538  } else {
1539  av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
1540  json_escape_str(&buf, section->name, wctx);
1541  JSON_INDENT();
1542 
1543  json->indent_level++;
1545  av_log(NULL, AV_LOG_STDERR, "\"%s\": [\n", buf.str);
1546  } else if (parent_section && !(parent_section->flags & SECTION_FLAG_IS_ARRAY)) {
1547  av_log(NULL, AV_LOG_STDERR, "\"%s\": {%s", buf.str, json->item_start_end);
1548  } else {
1549  av_log(NULL, AV_LOG_STDERR, "{%s", json->item_start_end);
1550 
1551  /* this is required so the parser can distinguish between packets and frames */
1552  if (parent_section && parent_section->id == SECTION_ID_PACKETS_AND_FRAMES) {
1553  if (!json->compact)
1554  JSON_INDENT();
1555  av_log(NULL, AV_LOG_STDERR, "\"type\": \"%s\"", section->name);
1556  }
1557  }
1558  av_bprint_finalize(&buf, NULL);
1559  }
1560 }
1561 
1563 {
1564  JSONContext *json = wctx->priv;
1565  const struct section *section = wctx->section[wctx->level];
1566 
1567  if (wctx->level == 0) {
1568  json->indent_level--;
1569  av_log(NULL, AV_LOG_STDERR, "\n}\n");
1570  } else if (section->flags & SECTION_FLAG_IS_ARRAY) {
1571  av_log(NULL, AV_LOG_STDERR, "\n");
1572  json->indent_level--;
1573  JSON_INDENT();
1574  av_log(NULL, AV_LOG_STDERR, "]");
1575  } else {
1576  av_log(NULL, AV_LOG_STDERR, "%s", json->item_start_end);
1577  json->indent_level--;
1578  if (!json->compact)
1579  JSON_INDENT();
1580  av_log(NULL, AV_LOG_STDERR, "}");
1581  }
1582 }
1583 
1584 static inline void json_print_item_str(WriterContext *wctx,
1585  const char *key, const char *value)
1586 {
1587  AVBPrint buf;
1588 
1589  av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
1590  av_log(NULL, AV_LOG_STDERR, "\"%s\":", json_escape_str(&buf, key, wctx));
1591  av_bprint_clear(&buf);
1592  av_log(NULL, AV_LOG_STDERR, " \"%s\"", json_escape_str(&buf, value, wctx));
1593  av_bprint_finalize(&buf, NULL);
1594 }
1595 
1596 static void json_print_str(WriterContext *wctx, const char *key, const char *value)
1597 {
1598  JSONContext *json = wctx->priv;
1599  const struct section *parent_section = wctx->level ?
1600  wctx->section[wctx->level-1] : NULL;
1601 
1602  if (wctx->nb_item[wctx->level] || (parent_section && parent_section->id == SECTION_ID_PACKETS_AND_FRAMES))
1603  av_log(NULL, AV_LOG_STDERR, "%s", json->item_sep);
1604  if (!json->compact)
1605  JSON_INDENT();
1606  json_print_item_str(wctx, key, value);
1607 }
1608 
1609 static void json_print_int(WriterContext *wctx, const char *key, long long int value)
1610 {
1611  JSONContext *json = wctx->priv;
1612  const struct section *parent_section = wctx->level ?
1613  wctx->section[wctx->level-1] : NULL;
1614  AVBPrint buf;
1615 
1616  if (wctx->nb_item[wctx->level] || (parent_section && parent_section->id == SECTION_ID_PACKETS_AND_FRAMES))
1617  av_log(NULL, AV_LOG_STDERR, "%s", json->item_sep);
1618  if (!json->compact)
1619  JSON_INDENT();
1620 
1621  av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
1622  av_log(NULL, AV_LOG_STDERR, "\"%s\": %lld", json_escape_str(&buf, key, wctx), value);
1623  av_bprint_finalize(&buf, NULL);
1624 }
1625 
1626 static const Writer json_writer = {
1627  .name = "json",
1628  .priv_size = sizeof(JSONContext),
1629  .init = json_init,
1632  .print_integer = json_print_int,
1633  .print_string = json_print_str,
1635  .priv_class = &json_class,
1636 };
1637 
1638 /* XML output */
1639 
1640 typedef struct XMLContext {
1641  const AVClass *class;
1646 } XMLContext;
1647 
1648 #undef OFFSET
1649 #define OFFSET(x) offsetof(XMLContext, x)
1650 
1651 static const AVOption xml_options[] = {
1652  {"fully_qualified", "specify if the output should be fully qualified", OFFSET(fully_qualified), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
1653  {"q", "specify if the output should be fully qualified", OFFSET(fully_qualified), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
1654  {"xsd_strict", "ensure that the output is XSD compliant", OFFSET(xsd_strict), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
1655  {"x", "ensure that the output is XSD compliant", OFFSET(xsd_strict), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
1656  {NULL},
1657 };
1658 
1659 DEFINE_WRITER_CLASS(xml);
1660 
1661 static av_cold int xml_init(WriterContext *wctx)
1662 {
1663  XMLContext *xml = wctx->priv;
1664 
1665  if (xml->xsd_strict) {
1666  xml->fully_qualified = 1;
1667 #define CHECK_COMPLIANCE(opt, opt_name) \
1668  if (opt) { \
1669  av_log(wctx, AV_LOG_ERROR, \
1670  "XSD-compliant output selected but option '%s' was selected, XML output may be non-compliant.\n" \
1671  "You need to disable such option with '-no%s'\n", opt_name, opt_name); \
1672  return AVERROR(EINVAL); \
1673  }
1674  CHECK_COMPLIANCE(show_private_data, "private");
1677  }
1678 
1679  return 0;
1680 }
1681 
1682 #define XML_INDENT() av_log(NULL, AV_LOG_STDERR, "%*c", xml->indent_level * 4, ' ')
1683 
1685 {
1686  XMLContext *xml = wctx->priv;
1687  const struct section *section = wctx->section[wctx->level];
1688  const struct section *parent_section = wctx->level ?
1689  wctx->section[wctx->level-1] : NULL;
1690 
1691  if (wctx->level == 0) {
1692  const char *qual = " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
1693  "xmlns:ffprobe=\"http://www.ffmpeg.org/schema/ffprobe\" "
1694  "xsi:schemaLocation=\"http://www.ffmpeg.org/schema/ffprobe ffprobe.xsd\"";
1695 
1696  av_log(NULL, AV_LOG_STDERR, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1697  av_log(NULL, AV_LOG_STDERR, "<%sffprobe%s>\n",
1698  xml->fully_qualified ? "ffprobe:" : "",
1699  xml->fully_qualified ? qual : "");
1700  return;
1701  }
1702 
1703  if (xml->within_tag) {
1704  xml->within_tag = 0;
1705  av_log(NULL, AV_LOG_STDERR, ">\n");
1706  }
1708  xml->indent_level++;
1709  } else {
1710  if (parent_section && (parent_section->flags & SECTION_FLAG_IS_WRAPPER) &&
1711  wctx->level && wctx->nb_item[wctx->level-1])
1712  av_log(NULL, AV_LOG_STDERR, "\n");
1713  xml->indent_level++;
1714 
1716  XML_INDENT(); av_log(NULL, AV_LOG_STDERR, "<%s>\n", section->name);
1717  } else {
1718  XML_INDENT(); av_log(NULL, AV_LOG_STDERR, "<%s ", section->name);
1719  xml->within_tag = 1;
1720  }
1721  }
1722 }
1723 
1725 {
1726  XMLContext *xml = wctx->priv;
1727  const struct section *section = wctx->section[wctx->level];
1728 
1729  if (wctx->level == 0) {
1730  av_log(NULL, AV_LOG_STDERR, "</%sffprobe>\n", xml->fully_qualified ? "ffprobe:" : "");
1731  } else if (xml->within_tag) {
1732  xml->within_tag = 0;
1733  av_log(NULL, AV_LOG_STDERR, "/>\n");
1734  xml->indent_level--;
1736  xml->indent_level--;
1737  } else {
1738  XML_INDENT(); av_log(NULL, AV_LOG_STDERR, "</%s>\n", section->name);
1739  xml->indent_level--;
1740  }
1741 }
1742 
1743 static void xml_print_str(WriterContext *wctx, const char *key, const char *value)
1744 {
1745  AVBPrint buf;
1746  XMLContext *xml = wctx->priv;
1747  const struct section *section = wctx->section[wctx->level];
1748 
1749  av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
1750 
1752  XML_INDENT();
1753  av_bprint_escape(&buf, key, NULL,
1754  AV_ESCAPE_MODE_XML, AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
1755  av_log(NULL, AV_LOG_STDERR, "<%s key=\"%s\"",
1756  section->element_name, buf.str);
1757  av_bprint_clear(&buf);
1758 
1759  av_bprint_escape(&buf, value, NULL,
1760  AV_ESCAPE_MODE_XML, AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
1761  av_log(NULL, AV_LOG_STDERR, " value=\"%s\"/>\n", buf.str);
1762  } else {
1763  if (wctx->nb_item[wctx->level])
1764  av_log(NULL, AV_LOG_STDERR, " ");
1765 
1766  av_bprint_escape(&buf, value, NULL,
1767  AV_ESCAPE_MODE_XML, AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
1768  av_log(NULL, AV_LOG_STDERR, "%s=\"%s\"", key, buf.str);
1769  }
1770 
1771  av_bprint_finalize(&buf, NULL);
1772 }
1773 
1774 static void xml_print_int(WriterContext *wctx, const char *key, long long int value)
1775 {
1776  if (wctx->nb_item[wctx->level])
1777  av_log(NULL, AV_LOG_STDERR, " ");
1778  av_log(NULL, AV_LOG_STDERR, "%s=\"%lld\"", key, value);
1779 }
1780 
1781 static Writer xml_writer = {
1782  .name = "xml",
1783  .priv_size = sizeof(XMLContext),
1784  .init = xml_init,
1787  .print_integer = xml_print_int,
1788  .print_string = xml_print_str,
1790  .priv_class = &xml_class,
1791 };
1792 
1793 static void writer_register_all(void)
1794 {
1795 
1803 }
1804 
1805 #define print_fmt(k, f, ...) do { \
1806  av_bprint_clear(&pbuf); \
1807  av_bprintf(&pbuf, f, __VA_ARGS__); \
1808  writer_print_string(w, k, pbuf.str, 0); \
1809 } while (0)
1810 
1811 #define print_int(k, v) writer_print_integer(w, k, v)
1812 #define print_q(k, v, s) writer_print_rational(w, k, v, s)
1813 #define print_str(k, v) writer_print_string(w, k, v, 0)
1814 #define print_str_opt(k, v) writer_print_string(w, k, v, PRINT_STRING_OPT)
1815 #define print_str_validate(k, v) writer_print_string(w, k, v, PRINT_STRING_VALIDATE)
1816 #define print_time(k, v, tb) writer_print_time(w, k, v, tb, 0)
1817 #define print_ts(k, v) writer_print_ts(w, k, v, 0)
1818 #define print_duration_time(k, v, tb) writer_print_time(w, k, v, tb, 1)
1819 #define print_duration_ts(k, v) writer_print_ts(w, k, v, 1)
1820 #define print_val(k, v, u) do { \
1821  struct unit_value uv; \
1822  uv.val.i = v; \
1823  uv.unit = u; \
1824  writer_print_string(w, k, value_string(val_str, sizeof(val_str), uv), 0); \
1825 } while (0)
1826 
1827 #define print_section_header(s) writer_print_section_header(w, s)
1828 #define print_section_footer(s) writer_print_section_footer(w, s)
1829 
1830 #define REALLOCZ_ARRAY_STREAM(ptr, cur_n, new_n) \
1831 { \
1832  ret = av_reallocp_array(&(ptr), (new_n), sizeof(*(ptr))); \
1833  if (ret < 0) \
1834  goto end; \
1835  memset( (ptr) + (cur_n), 0, ((new_n) - (cur_n)) * sizeof(*(ptr)) ); \
1836 }
1837 
1838 static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id)
1839 {
1840  AVDictionaryEntry *tag = NULL;
1841  int ret = 0;
1842 
1843  if (!tags)
1844  return 0;
1845  writer_print_section_header(w, section_id);
1846 
1847  while ((tag = av_dict_get(tags, "", tag, AV_DICT_IGNORE_SUFFIX))) {
1848  if ((ret = print_str_validate(tag->key, tag->value)) < 0)
1849  break;
1850  }
1852 
1853  return ret;
1854 }
1855 
1856 static void print_dynamic_hdr10_plus(WriterContext *w, const AVDynamicHDRPlus *metadata)
1857 {
1858  if (!metadata)
1859  return;
1860  print_int("application version", metadata->application_version);
1861  print_int("num_windows", metadata->num_windows);
1862  for (int n = 1; n < metadata->num_windows; n++) {
1863  const AVHDRPlusColorTransformParams *params = &metadata->params[n];
1864  print_q("window_upper_left_corner_x",
1865  params->window_upper_left_corner_x,'/');
1866  print_q("window_upper_left_corner_y",
1867  params->window_upper_left_corner_y,'/');
1868  print_q("window_lower_right_corner_x",
1869  params->window_lower_right_corner_x,'/');
1870  print_q("window_lower_right_corner_y",
1871  params->window_lower_right_corner_y,'/');
1872  print_q("window_upper_left_corner_x",
1873  params->window_upper_left_corner_x,'/');
1874  print_q("window_upper_left_corner_y",
1875  params->window_upper_left_corner_y,'/');
1876  print_int("center_of_ellipse_x",
1877  params->center_of_ellipse_x ) ;
1878  print_int("center_of_ellipse_y",
1879  params->center_of_ellipse_y );
1880  print_int("rotation_angle",
1881  params->rotation_angle);
1882  print_int("semimajor_axis_internal_ellipse",
1883  params->semimajor_axis_internal_ellipse);
1884  print_int("semimajor_axis_external_ellipse",
1885  params->semimajor_axis_external_ellipse);
1886  print_int("semiminor_axis_external_ellipse",
1887  params->semiminor_axis_external_ellipse);
1888  print_int("overlap_process_option",
1889  params->overlap_process_option);
1890  }
1891  print_q("targeted_system_display_maximum_luminance",
1892  metadata->targeted_system_display_maximum_luminance,'/');
1893  if (metadata->targeted_system_display_actual_peak_luminance_flag) {
1894  print_int("num_rows_targeted_system_display_actual_peak_luminance",
1895  metadata->num_rows_targeted_system_display_actual_peak_luminance);
1896  print_int("num_cols_targeted_system_display_actual_peak_luminance",
1897  metadata->num_cols_targeted_system_display_actual_peak_luminance);
1898  for (int i = 0; i < metadata->num_rows_targeted_system_display_actual_peak_luminance; i++) {
1899  for (int j = 0; j < metadata->num_cols_targeted_system_display_actual_peak_luminance; j++) {
1900  print_q("targeted_system_display_actual_peak_luminance",
1901  metadata->targeted_system_display_actual_peak_luminance[i][j],'/');
1902  }
1903  }
1904  }
1905  for (int n = 0; n < metadata->num_windows; n++) {
1906  const AVHDRPlusColorTransformParams *params = &metadata->params[n];
1907  for (int i = 0; i < 3; i++) {
1908  print_q("maxscl",params->maxscl[i],'/');
1909  }
1910  print_q("average_maxrgb",
1911  params->average_maxrgb,'/');
1912  print_int("num_distribution_maxrgb_percentiles",
1913  params->num_distribution_maxrgb_percentiles);
1914  for (int i = 0; i < params->num_distribution_maxrgb_percentiles; i++) {
1915  print_int("distribution_maxrgb_percentage",
1916  params->distribution_maxrgb[i].percentage);
1917  print_q("distribution_maxrgb_percentile",
1918  params->distribution_maxrgb[i].percentile,'/');
1919  }
1920  print_q("fraction_bright_pixels",
1921  params->fraction_bright_pixels,'/');
1922  }
1923  if (metadata->mastering_display_actual_peak_luminance_flag) {
1924  print_int("num_rows_mastering_display_actual_peak_luminance",
1925  metadata->num_rows_mastering_display_actual_peak_luminance);
1926  print_int("num_cols_mastering_display_actual_peak_luminance",
1927  metadata->num_cols_mastering_display_actual_peak_luminance);
1928  for (int i = 0; i < metadata->num_rows_mastering_display_actual_peak_luminance; i++) {
1929  for (int j = 0; j < metadata->num_cols_mastering_display_actual_peak_luminance; j++) {
1930  print_q("mastering_display_actual_peak_luminance",
1931  metadata->mastering_display_actual_peak_luminance[i][j],'/');
1932  }
1933  }
1934  }
1935 
1936  for (int n = 0; n < metadata->num_windows; n++) {
1937  const AVHDRPlusColorTransformParams *params = &metadata->params[n];
1938  if (params->tone_mapping_flag) {
1939  print_q("knee_point_x", params->knee_point_x,'/');
1940  print_q("knee_point_y", params->knee_point_y,'/');
1941  print_int("num_bezier_curve_anchors",
1942  params->num_bezier_curve_anchors );
1943  for (int i = 0; i < params->num_bezier_curve_anchors; i++) {
1944  print_q("bezier_curve_anchors",
1945  params->bezier_curve_anchors[i],'/');
1946  }
1947  }
1948  if (params->color_saturation_mapping_flag) {
1949  print_q("color_saturation_weight",
1950  params->color_saturation_weight,'/');
1951  }
1952  }
1953 }
1954 
1956  AVCodecParameters *par,
1957  const AVPacketSideData *side_data,
1958  int nb_side_data,
1959  SectionID id_data_list,
1960  SectionID id_data)
1961 {
1962  int i;
1963 
1964  writer_print_section_header(w, id_data_list);
1965  for (i = 0; i < nb_side_data; i++) {
1966  const AVPacketSideData *sd = &side_data[i];
1967  const char *name = av_packet_side_data_name(sd->type);
1968 
1969  writer_print_section_header(w, id_data);
1970  print_str("side_data_type", name ? name : "unknown");
1971  if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9*4) {
1972  writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1);
1973  print_int("rotation", av_display_rotation_get((int32_t *)sd->data));
1974  } else if (sd->type == AV_PKT_DATA_STEREO3D) {
1975  const AVStereo3D *stereo = (AVStereo3D *)sd->data;
1976  print_str("type", av_stereo3d_type_name(stereo->type));
1977  print_int("inverted", !!(stereo->flags & AV_STEREO3D_FLAG_INVERT));
1978  } else if (sd->type == AV_PKT_DATA_SPHERICAL) {
1979  const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data;
1980  print_str("projection", av_spherical_projection_name(spherical->projection));
1981  if (spherical->projection == AV_SPHERICAL_CUBEMAP) {
1982  print_int("padding", spherical->padding);
1983  } else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) {
1984  size_t l, t, r, b;
1985  av_spherical_tile_bounds(spherical, par->width, par->height,
1986  &l, &t, &r, &b);
1987  print_int("bound_left", l);
1988  print_int("bound_top", t);
1989  print_int("bound_right", r);
1990  print_int("bound_bottom", b);
1991  }
1992 
1993  print_int("yaw", (double) spherical->yaw / (1 << 16));
1994  print_int("pitch", (double) spherical->pitch / (1 << 16));
1995  print_int("roll", (double) spherical->roll / (1 << 16));
1996  } else if (sd->type == AV_PKT_DATA_SKIP_SAMPLES && sd->size == 10) {
1997  print_int("skip_samples", AV_RL32(sd->data));
1998  print_int("discard_padding", AV_RL32(sd->data + 4));
1999  print_int("skip_reason", AV_RL8(sd->data + 8));
2000  print_int("discard_reason", AV_RL8(sd->data + 9));
2001  } else if (sd->type == AV_PKT_DATA_MASTERING_DISPLAY_METADATA) {
2002  AVMasteringDisplayMetadata *metadata = (AVMasteringDisplayMetadata *)sd->data;
2003 
2004  if (metadata->has_primaries) {
2005  print_q("red_x", metadata->display_primaries[0][0], '/');
2006  print_q("red_y", metadata->display_primaries[0][1], '/');
2007  print_q("green_x", metadata->display_primaries[1][0], '/');
2008  print_q("green_y", metadata->display_primaries[1][1], '/');
2009  print_q("blue_x", metadata->display_primaries[2][0], '/');
2010  print_q("blue_y", metadata->display_primaries[2][1], '/');
2011 
2012  print_q("white_point_x", metadata->white_point[0], '/');
2013  print_q("white_point_y", metadata->white_point[1], '/');
2014  }
2015 
2016  if (metadata->has_luminance) {
2017  print_q("min_luminance", metadata->min_luminance, '/');
2018  print_q("max_luminance", metadata->max_luminance, '/');
2019  }
2020  } else if (sd->type == AV_PKT_DATA_CONTENT_LIGHT_LEVEL) {
2021  AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data;
2022  print_int("max_content", metadata->MaxCLL);
2023  print_int("max_average", metadata->MaxFALL);
2024  } else if (sd->type == AV_PKT_DATA_DOVI_CONF) {
2025  AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *)sd->data;
2026  print_int("dv_version_major", dovi->dv_version_major);
2027  print_int("dv_version_minor", dovi->dv_version_minor);
2028  print_int("dv_profile", dovi->dv_profile);
2029  print_int("dv_level", dovi->dv_level);
2030  print_int("rpu_present_flag", dovi->rpu_present_flag);
2031  print_int("el_present_flag", dovi->el_present_flag);
2032  print_int("bl_present_flag", dovi->bl_present_flag);
2033  print_int("dv_bl_signal_compatibility_id", dovi->dv_bl_signal_compatibility_id);
2034  } else if (sd->type == AV_PKT_DATA_AUDIO_SERVICE_TYPE) {
2035  enum AVAudioServiceType *t = (enum AVAudioServiceType *)sd->data;
2036  print_int("service_type", *t);
2037  } else if (sd->type == AV_PKT_DATA_MPEGTS_STREAM_ID) {
2038  print_int("id", *sd->data);
2039  } else if (sd->type == AV_PKT_DATA_CPB_PROPERTIES) {
2040  const AVCPBProperties *prop = (AVCPBProperties *)sd->data;
2041  print_int("max_bitrate", prop->max_bitrate);
2042  print_int("min_bitrate", prop->min_bitrate);
2043  print_int("avg_bitrate", prop->avg_bitrate);
2044  print_int("buffer_size", prop->buffer_size);
2045  print_int("vbv_delay", prop->vbv_delay);
2046  } else if (sd->type == AV_PKT_DATA_WEBVTT_IDENTIFIER ||
2047  sd->type == AV_PKT_DATA_WEBVTT_SETTINGS) {
2048  if (do_show_data)
2049  writer_print_data(w, "data", sd->data, sd->size);
2050  writer_print_data_hash(w, "data_hash", sd->data, sd->size);
2051  }
2053  }
2055 }
2056 
2057 static void print_color_range(WriterContext *w, enum AVColorRange color_range)
2058 {
2059  const char *val = av_color_range_name(color_range);
2060  if (!val || color_range == AVCOL_RANGE_UNSPECIFIED) {
2061  print_str_opt("color_range", "unknown");
2062  } else {
2063  print_str("color_range", val);
2064  }
2065 }
2066 
2067 static void print_color_space(WriterContext *w, enum AVColorSpace color_space)
2068 {
2069  const char *val = av_color_space_name(color_space);
2070  if (!val || color_space == AVCOL_SPC_UNSPECIFIED) {
2071  print_str_opt("color_space", "unknown");
2072  } else {
2073  print_str("color_space", val);
2074  }
2075 }
2076 
2077 static void print_primaries(WriterContext *w, enum AVColorPrimaries color_primaries)
2078 {
2079  const char *val = av_color_primaries_name(color_primaries);
2080  if (!val || color_primaries == AVCOL_PRI_UNSPECIFIED) {
2081  print_str_opt("color_primaries", "unknown");
2082  } else {
2083  print_str("color_primaries", val);
2084  }
2085 }
2086 
2087 static void print_color_trc(WriterContext *w, enum AVColorTransferCharacteristic color_trc)
2088 {
2089  const char *val = av_color_transfer_name(color_trc);
2090  if (!val || color_trc == AVCOL_TRC_UNSPECIFIED) {
2091  print_str_opt("color_transfer", "unknown");
2092  } else {
2093  print_str("color_transfer", val);
2094  }
2095 }
2096 
2097 static void print_chroma_location(WriterContext *w, enum AVChromaLocation chroma_location)
2098 {
2099  const char *val = av_chroma_location_name(chroma_location);
2100  if (!val || chroma_location == AVCHROMA_LOC_UNSPECIFIED) {
2101  print_str_opt("chroma_location", "unspecified");
2102  } else {
2103  print_str("chroma_location", val);
2104  }
2105 }
2106 
2107 
2108 static void clear_log(int need_lock)
2109 {
2110  int i;
2111 
2112  if (need_lock)
2113  pthread_mutex_lock(&log_mutex);
2114  for (i=0; i<log_buffer_size; i++) {
2115  av_freep(&log_buffer[i].context_name);
2116  av_freep(&log_buffer[i].parent_name);
2117  av_freep(&log_buffer[i].log_message);
2118  }
2119  log_buffer_size = 0;
2120  if(need_lock)
2121  pthread_mutex_unlock(&log_mutex);
2122 }
2123 
2124 static int show_log(WriterContext *w, int section_ids, int section_id, int log_level)
2125 {
2126  int i;
2127  pthread_mutex_lock(&log_mutex);
2128  if (!log_buffer_size) {
2129  pthread_mutex_unlock(&log_mutex);
2130  return 0;
2131  }
2132  writer_print_section_header(w, section_ids);
2133 
2134  for (i=0; i<log_buffer_size; i++) {
2135  if (log_buffer[i].log_level <= log_level) {
2136  writer_print_section_header(w, section_id);
2137  print_str("context", log_buffer[i].context_name);
2138  print_int("level", log_buffer[i].log_level);
2139  print_int("category", log_buffer[i].category);
2140  if (log_buffer[i].parent_name) {
2141  print_str("parent_context", log_buffer[i].parent_name);
2142  print_int("parent_category", log_buffer[i].parent_category);
2143  } else {
2144  print_str_opt("parent_context", "N/A");
2145  print_str_opt("parent_category", "N/A");
2146  }
2147  print_str("message", log_buffer[i].log_message);
2149  }
2150  }
2151  clear_log(0);
2152  pthread_mutex_unlock(&log_mutex);
2153 
2155 
2156  return 0;
2157 }
2158 
2159 static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int packet_idx)
2160 {
2161  char val_str[128];
2162  AVStream *st = ifile->streams[pkt->stream_index].st;
2163  AVBPrint pbuf;
2164  const char *s;
2165 
2166  av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
2167 
2169 
2170  s = av_get_media_type_string(st->codecpar->codec_type);
2171  if (s) print_str ("codec_type", s);
2172  else print_str_opt("codec_type", "unknown");
2173  print_int("stream_index", pkt->stream_index);
2174  print_ts ("pts", pkt->pts);
2175  print_time("pts_time", pkt->pts, &st->time_base);
2176  print_ts ("dts", pkt->dts);
2177  print_time("dts_time", pkt->dts, &st->time_base);
2178  print_duration_ts("duration", pkt->duration);
2179  print_duration_time("duration_time", pkt->duration, &st->time_base);
2180  print_val("size", pkt->size, unit_byte_str);
2181  if (pkt->pos != -1) print_fmt ("pos", "%"PRId64, pkt->pos);
2182  else print_str_opt("pos", "N/A");
2183  print_fmt("flags", "%c%c", pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_',
2184  pkt->flags & AV_PKT_FLAG_DISCARD ? 'D' : '_');
2185 
2186  if (pkt->side_data_elems) {
2187  size_t size;
2188  const uint8_t *side_metadata;
2189 
2190  side_metadata = av_packet_get_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, &size);
2191  if (side_metadata && size && do_show_packet_tags) {
2192  AVDictionary *dict = NULL;
2193  if (av_packet_unpack_dictionary(side_metadata, size, &dict) >= 0)
2195  av_dict_free(&dict);
2196  }
2197 
2198  print_pkt_side_data(w, st->codecpar, pkt->side_data, pkt->side_data_elems,
2201  }
2202 
2203  if (do_show_data)
2204  writer_print_data(w, "data", pkt->data, pkt->size);
2205  writer_print_data_hash(w, "data_hash", pkt->data, pkt->size);
2207 
2208  av_bprint_finalize(&pbuf, NULL);
2209  fflush(stdout);
2210 }
2211 
2212 static void show_subtitle(WriterContext *w, AVSubtitle *sub, AVStream *stream,
2213  AVFormatContext *fmt_ctx)
2214 {
2215  AVBPrint pbuf;
2216 
2217  av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
2218 
2220 
2221  print_str ("media_type", "subtitle");
2222  print_ts ("pts", sub->pts);
2223  print_time("pts_time", sub->pts, &AV_TIME_BASE_Q);
2224  print_int ("format", sub->format);
2225  print_int ("start_display_time", sub->start_display_time);
2226  print_int ("end_display_time", sub->end_display_time);
2227  print_int ("num_rects", sub->num_rects);
2228 
2230 
2231  av_bprint_finalize(&pbuf, NULL);
2232  fflush(stdout);
2233 }
2234 
2235 static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
2236  AVFormatContext *fmt_ctx)
2237 {
2238  AVBPrint pbuf;
2239  char val_str[128];
2240  const char *s;
2241  int i;
2242 
2243  av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
2244 
2246 
2247  s = av_get_media_type_string(stream->codecpar->codec_type);
2248  if (s) print_str ("media_type", s);
2249  else print_str_opt("media_type", "unknown");
2250  print_int("stream_index", stream->index);
2251  print_int("key_frame", frame->key_frame);
2252  print_ts ("pts", frame->pts);
2253  print_time("pts_time", frame->pts, &stream->time_base);
2254  print_ts ("pkt_dts", frame->pkt_dts);
2255  print_time("pkt_dts_time", frame->pkt_dts, &stream->time_base);
2256  print_ts ("best_effort_timestamp", frame->best_effort_timestamp);
2257  print_time("best_effort_timestamp_time", frame->best_effort_timestamp, &stream->time_base);
2258  print_duration_ts ("pkt_duration", frame->pkt_duration);
2259  print_duration_time("pkt_duration_time", frame->pkt_duration, &stream->time_base);
2260  if (frame->pkt_pos != -1) print_fmt ("pkt_pos", "%"PRId64, frame->pkt_pos);
2261  else print_str_opt("pkt_pos", "N/A");
2262  if (frame->pkt_size != -1) print_val ("pkt_size", frame->pkt_size, unit_byte_str);
2263  else print_str_opt("pkt_size", "N/A");
2264 
2265  switch (stream->codecpar->codec_type) {
2266  AVRational sar;
2267 
2268  case AVMEDIA_TYPE_VIDEO:
2269  print_int("width", frame->width);
2270  print_int("height", frame->height);
2271  s = av_get_pix_fmt_name(frame->format);
2272  if (s) print_str ("pix_fmt", s);
2273  else print_str_opt("pix_fmt", "unknown");
2274  sar = av_guess_sample_aspect_ratio(fmt_ctx, stream, frame);
2275  if (sar.num) {
2276  print_q("sample_aspect_ratio", sar, ':');
2277  } else {
2278  print_str_opt("sample_aspect_ratio", "N/A");
2279  }
2280  print_fmt("pict_type", "%c", av_get_picture_type_char(frame->pict_type));
2281  print_int("coded_picture_number", frame->coded_picture_number);
2282  print_int("display_picture_number", frame->display_picture_number);
2283  print_int("interlaced_frame", frame->interlaced_frame);
2284  print_int("top_field_first", frame->top_field_first);
2285  print_int("repeat_pict", frame->repeat_pict);
2286 
2287  print_color_range(w, frame->color_range);
2288  print_color_space(w, frame->colorspace);
2289  print_primaries(w, frame->color_primaries);
2290  print_color_trc(w, frame->color_trc);
2291  print_chroma_location(w, frame->chroma_location);
2292  break;
2293 
2294  case AVMEDIA_TYPE_AUDIO:
2295  s = av_get_sample_fmt_name(frame->format);
2296  if (s) print_str ("sample_fmt", s);
2297  else print_str_opt("sample_fmt", "unknown");
2298  print_int("nb_samples", frame->nb_samples);
2299  print_int("channels", frame->channels);
2300  if (frame->channel_layout) {
2301  av_bprint_clear(&pbuf);
2302  av_bprint_channel_layout(&pbuf, frame->channels,
2303  frame->channel_layout);
2304  print_str ("channel_layout", pbuf.str);
2305  } else
2306  print_str_opt("channel_layout", "unknown");
2307  break;
2308  }
2309  if (do_show_frame_tags)
2310  show_tags(w, frame->metadata, SECTION_ID_FRAME_TAGS);
2311  if (do_show_log)
2313  if (frame->nb_side_data) {
2315  for (i = 0; i < frame->nb_side_data; i++) {
2316  AVFrameSideData *sd = frame->side_data[i];
2317  const char *name;
2318 
2320  name = av_frame_side_data_name(sd->type);
2321  print_str("side_data_type", name ? name : "unknown");
2322  if (sd->type == AV_FRAME_DATA_DISPLAYMATRIX && sd->size >= 9*4) {
2323  writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1);
2324  print_int("rotation", av_display_rotation_get((int32_t *)sd->data));
2325  } else if (sd->type == AV_FRAME_DATA_GOP_TIMECODE && sd->size >= 8) {
2326  char tcbuf[AV_TIMECODE_STR_SIZE];
2327  av_timecode_make_mpeg_tc_string(tcbuf, *(int64_t *)(sd->data));
2328  print_str("timecode", tcbuf);
2329  } else if (sd->type == AV_FRAME_DATA_S12M_TIMECODE && sd->size == 16) {
2330  uint32_t *tc = (uint32_t*)sd->data;
2331  int m = FFMIN(tc[0],3);
2333  for (int j = 1; j <= m ; j++) {
2334  char tcbuf[AV_TIMECODE_STR_SIZE];
2335  av_timecode_make_smpte_tc_string2(tcbuf, stream->avg_frame_rate, tc[j], 0, 0);
2337  print_str("value", tcbuf);
2339  }
2341  } else if (sd->type == AV_FRAME_DATA_MASTERING_DISPLAY_METADATA) {
2342  AVMasteringDisplayMetadata *metadata = (AVMasteringDisplayMetadata *)sd->data;
2343 
2344  if (metadata->has_primaries) {
2345  print_q("red_x", metadata->display_primaries[0][0], '/');
2346  print_q("red_y", metadata->display_primaries[0][1], '/');
2347  print_q("green_x", metadata->display_primaries[1][0], '/');
2348  print_q("green_y", metadata->display_primaries[1][1], '/');
2349  print_q("blue_x", metadata->display_primaries[2][0], '/');
2350  print_q("blue_y", metadata->display_primaries[2][1], '/');
2351 
2352  print_q("white_point_x", metadata->white_point[0], '/');
2353  print_q("white_point_y", metadata->white_point[1], '/');
2354  }
2355 
2356  if (metadata->has_luminance) {
2357  print_q("min_luminance", metadata->min_luminance, '/');
2358  print_q("max_luminance", metadata->max_luminance, '/');
2359  }
2360  } else if (sd->type == AV_FRAME_DATA_DYNAMIC_HDR_PLUS) {
2361  AVDynamicHDRPlus *metadata = (AVDynamicHDRPlus *)sd->data;
2362  print_dynamic_hdr10_plus(w, metadata);
2363  } else if (sd->type == AV_FRAME_DATA_CONTENT_LIGHT_LEVEL) {
2364  AVContentLightMetadata *metadata = (AVContentLightMetadata *)sd->data;
2365  print_int("max_content", metadata->MaxCLL);
2366  print_int("max_average", metadata->MaxFALL);
2367  } else if (sd->type == AV_FRAME_DATA_ICC_PROFILE) {
2368  AVDictionaryEntry *tag = av_dict_get(sd->metadata, "name", NULL, AV_DICT_MATCH_CASE);
2369  if (tag)
2370  print_str(tag->key, tag->value);
2371  print_int("size", sd->size);
2372  }
2374  }
2376  }
2377 
2379 
2380  av_bprint_finalize(&pbuf, NULL);
2381  fflush(stdout);
2382 }
2383 
2384 static av_always_inline int process_frame(WriterContext *w,
2385  InputFile *ifile,
2386  AVFrame *frame, AVPacket *pkt,
2387  int *packet_new)
2388 {
2389  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2390  AVCodecContext *dec_ctx = ifile->streams[pkt->stream_index].dec_ctx;
2391  AVCodecParameters *par = ifile->streams[pkt->stream_index].st->codecpar;
2392  AVSubtitle sub;
2393  int ret = 0, got_frame = 0;
2394 
2395  clear_log(1);
2396  if (dec_ctx && dec_ctx->codec) {
2397  switch (par->codec_type) {
2398  case AVMEDIA_TYPE_VIDEO:
2399  case AVMEDIA_TYPE_AUDIO:
2400  if (*packet_new) {
2401  ret = avcodec_send_packet(dec_ctx, pkt);
2402  if (ret == AVERROR(EAGAIN)) {
2403  ret = 0;
2404  } else if (ret >= 0 || ret == AVERROR_EOF) {
2405  ret = 0;
2406  *packet_new = 0;
2407  }
2408  }
2409  if (ret >= 0) {
2410  ret = avcodec_receive_frame(dec_ctx, frame);
2411  if (ret >= 0) {
2412  got_frame = 1;
2413  } else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2414  ret = 0;
2415  }
2416  }
2417  break;
2418 
2419  case AVMEDIA_TYPE_SUBTITLE:
2420  if (*packet_new)
2421  ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_frame, pkt);
2422  *packet_new = 0;
2423  break;
2424  default:
2425  *packet_new = 0;
2426  }
2427  } else {
2428  *packet_new = 0;
2429  }
2430 
2431  if (ret < 0)
2432  return ret;
2433  if (got_frame) {
2434  int is_sub = (par->codec_type == AVMEDIA_TYPE_SUBTITLE);
2435  nb_streams_frames[pkt->stream_index]++;
2436  if (do_show_frames) {
2437  if (is_sub) {
2438  show_subtitle(w, &sub, ifile->streams[pkt->stream_index].st, fmt_ctx);
2439  } else {
2440  show_frame(w, frame, ifile->streams[pkt->stream_index].st, fmt_ctx);
2441  }
2442  }
2443  if (is_sub) {
2444  avsubtitle_free(&sub);
2445  }
2446  }
2447  return got_frame || *packet_new;
2448 }
2449 
2450 static void log_read_interval(const ReadInterval *interval, void *log_ctx, int log_level)
2451 {
2452  av_log(log_ctx, log_level, "id:%d", interval->id);
2453 
2454  if (interval->has_start) {
2455  av_log(log_ctx, log_level, " start:%s%s", interval->start_is_offset ? "+" : "",
2456  av_ts2timestr(interval->start, &AV_TIME_BASE_Q));
2457  } else {
2458  av_log(log_ctx, log_level, " start:N/A");
2459  }
2460 
2461  if (interval->has_end) {
2462  av_log(log_ctx, log_level, " end:%s", interval->end_is_offset ? "+" : "");
2463  if (interval->duration_frames)
2464  av_log(log_ctx, log_level, "#%"PRId64, interval->end);
2465  else
2466  av_log(log_ctx, log_level, "%s", av_ts2timestr(interval->end, &AV_TIME_BASE_Q));
2467  } else {
2468  av_log(log_ctx, log_level, " end:N/A");
2469  }
2470 
2471  av_log(log_ctx, log_level, "\n");
2472 }
2473 
2475  const ReadInterval *interval, int64_t *cur_ts)
2476 {
2477  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2478  AVPacket *pkt = NULL;
2479  AVFrame *frame = NULL;
2480  int ret = 0, i = 0, frame_count = 0;
2481  int64_t start = -INT64_MAX, end = interval->end;
2482  int has_start = 0, has_end = interval->has_end && !interval->end_is_offset;
2483 
2484  av_log(NULL, AV_LOG_VERBOSE, "Processing read interval ");
2485  log_read_interval(interval, NULL, AV_LOG_VERBOSE);
2486 
2487  if (interval->has_start) {
2488  int64_t target;
2489  if (interval->start_is_offset) {
2490  if (*cur_ts == AV_NOPTS_VALUE) {
2491  av_log(NULL, AV_LOG_ERROR,
2492  "Could not seek to relative position since current "
2493  "timestamp is not defined\n");
2494  ret = AVERROR(EINVAL);
2495  goto end;
2496  }
2497  target = *cur_ts + interval->start;
2498  } else {
2499  target = interval->start;
2500  }
2501 
2502  av_log(NULL, AV_LOG_VERBOSE, "Seeking to read interval start point %s\n",
2503  av_ts2timestr(target, &AV_TIME_BASE_Q));
2504  if ((ret = avformat_seek_file(fmt_ctx, -1, -INT64_MAX, target, INT64_MAX, 0)) < 0) {
2505  av_log(NULL, AV_LOG_ERROR, "Could not seek to position %"PRId64": %s\n",
2506  interval->start, av_err2str(ret));
2507  goto end;
2508  }
2509  }
2510 
2511  frame = av_frame_alloc();
2512  if (!frame) {
2513  ret = AVERROR(ENOMEM);
2514  goto end;
2515  }
2516  pkt = av_packet_alloc();
2517  if (!pkt) {
2518  ret = AVERROR(ENOMEM);
2519  goto end;
2520  }
2521  while (!av_read_frame(fmt_ctx, pkt)) {
2522  if (fmt_ctx->nb_streams > nb_streams) {
2523  REALLOCZ_ARRAY_STREAM(nb_streams_frames, nb_streams, fmt_ctx->nb_streams);
2524  REALLOCZ_ARRAY_STREAM(nb_streams_packets, nb_streams, fmt_ctx->nb_streams);
2525  REALLOCZ_ARRAY_STREAM(selected_streams, nb_streams, fmt_ctx->nb_streams);
2526  nb_streams = fmt_ctx->nb_streams;
2527  }
2528  if (selected_streams[pkt->stream_index]) {
2529  AVRational tb = ifile->streams[pkt->stream_index].st->time_base;
2530 
2531  if (pkt->pts != AV_NOPTS_VALUE)
2532  *cur_ts = av_rescale_q(pkt->pts, tb, AV_TIME_BASE_Q);
2533 
2534  if (!has_start && *cur_ts != AV_NOPTS_VALUE) {
2535  start = *cur_ts;
2536  has_start = 1;
2537  }
2538 
2539  if (has_start && !has_end && interval->end_is_offset) {
2540  end = start + interval->end;
2541  has_end = 1;
2542  }
2543 
2544  if (interval->end_is_offset && interval->duration_frames) {
2545  if (frame_count >= interval->end)
2546  break;
2547  } else if (has_end && *cur_ts != AV_NOPTS_VALUE && *cur_ts >= end) {
2548  break;
2549  }
2550 
2551  frame_count++;
2552  if (do_read_packets) {
2553  if (do_show_packets)
2554  show_packet(w, ifile, pkt, i++);
2555  nb_streams_packets[pkt->stream_index]++;
2556  }
2557  if (do_read_frames) {
2558  int packet_new = 1;
2559  while (process_frame(w, ifile, frame, pkt, &packet_new) > 0);
2560  }
2561  }
2562  av_packet_unref(pkt);
2563  }
2564  av_packet_unref(pkt);
2565  //Flush remaining frames that are cached in the decoder
2566  for (i = 0; i < fmt_ctx->nb_streams; i++) {
2567  pkt->stream_index = i;
2568  if (do_read_frames)
2569  while (process_frame(w, ifile, frame, pkt, &(int){1}) > 0);
2570  }
2571 
2572 end:
2573  av_frame_free(&frame);
2574  av_packet_free(&pkt);
2575  if (ret < 0) {
2576  av_log(NULL, AV_LOG_ERROR, "Could not read packets in interval ");
2577  log_read_interval(interval, NULL, AV_LOG_ERROR);
2578  }
2579  return ret;
2580 }
2581 
2582 static int read_packets(WriterContext *w, InputFile *ifile)
2583 {
2584  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2585  int i, ret = 0;
2586  int64_t cur_ts = fmt_ctx->start_time;
2587 
2588  if (read_intervals_nb == 0) {
2589  ReadInterval interval = (ReadInterval) { .has_start = 0, .has_end = 0 };
2590  ret = read_interval_packets(w, ifile, &interval, &cur_ts);
2591  } else {
2592  for (i = 0; i < read_intervals_nb; i++) {
2593  ret = read_interval_packets(w, ifile, &read_intervals[i], &cur_ts);
2594  if (ret < 0)
2595  break;
2596  }
2597  }
2598 
2599  return ret;
2600 }
2601 
2602 static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx, InputStream *ist, int in_program)
2603 {
2604  AVStream *stream = ist->st;
2605  AVCodecParameters *par;
2606  AVCodecContext *dec_ctx;
2607  char val_str[128];
2608  const char *s;
2609  AVRational sar, dar;
2610  AVBPrint pbuf;
2611  const AVCodecDescriptor *cd;
2612  int ret = 0;
2613  const char *profile = NULL;
2614 
2615  av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
2616 
2618 
2619  print_int("index", stream->index);
2620 
2621  par = stream->codecpar;
2622  dec_ctx = ist->dec_ctx;
2623  if ((cd = avcodec_descriptor_get(par->codec_id))) {
2624  print_str("codec_name", cd->name);
2625  if (!do_bitexact) {
2626  print_str("codec_long_name",
2627  cd->long_name ? cd->long_name : "unknown");
2628  }
2629  } else {
2630  print_str_opt("codec_name", "unknown");
2631  if (!do_bitexact) {
2632  print_str_opt("codec_long_name", "unknown");
2633  }
2634  }
2635 
2636  if (!do_bitexact && (profile = avcodec_profile_name(par->codec_id, par->profile)))
2637  print_str("profile", profile);
2638  else {
2639  if (par->profile != FF_PROFILE_UNKNOWN) {
2640  char profile_num[12];
2641  snprintf(profile_num, sizeof(profile_num), "%d", par->profile);
2642  print_str("profile", profile_num);
2643  } else
2644  print_str_opt("profile", "unknown");
2645  }
2646 
2647  s = av_get_media_type_string(par->codec_type);
2648  if (s) print_str ("codec_type", s);
2649  else print_str_opt("codec_type", "unknown");
2650 
2651  /* print AVI/FourCC tag */
2652  print_str("codec_tag_string", av_fourcc2str(par->codec_tag));
2653  print_fmt("codec_tag", "0x%04"PRIx32, par->codec_tag);
2654 
2655  switch (par->codec_type) {
2656  case AVMEDIA_TYPE_VIDEO:
2657  print_int("width", par->width);
2658  print_int("height", par->height);
2659  if (dec_ctx) {
2660  print_int("coded_width", dec_ctx->coded_width);
2661  print_int("coded_height", dec_ctx->coded_height);
2662  print_int("closed_captions", !!(dec_ctx->properties & FF_CODEC_PROPERTY_CLOSED_CAPTIONS));
2663  }
2664  print_int("has_b_frames", par->video_delay);
2665  sar = av_guess_sample_aspect_ratio(fmt_ctx, stream, NULL);
2666  if (sar.num) {
2667  print_q("sample_aspect_ratio", sar, ':');
2668  av_reduce(&dar.num, &dar.den,
2669  par->width * sar.num,
2670  par->height * sar.den,
2671  1024*1024);
2672  print_q("display_aspect_ratio", dar, ':');
2673  } else {
2674  print_str_opt("sample_aspect_ratio", "N/A");
2675  print_str_opt("display_aspect_ratio", "N/A");
2676  }
2677  s = av_get_pix_fmt_name(par->format);
2678  if (s) print_str ("pix_fmt", s);
2679  else print_str_opt("pix_fmt", "unknown");
2680  print_int("level", par->level);
2681 
2682  print_color_range(w, par->color_range);
2683  print_color_space(w, par->color_space);
2684  print_color_trc(w, par->color_trc);
2685  print_primaries(w, par->color_primaries);
2686  print_chroma_location(w, par->chroma_location);
2687 
2688  if (par->field_order == AV_FIELD_PROGRESSIVE)
2689  print_str("field_order", "progressive");
2690  else if (par->field_order == AV_FIELD_TT)
2691  print_str("field_order", "tt");
2692  else if (par->field_order == AV_FIELD_BB)
2693  print_str("field_order", "bb");
2694  else if (par->field_order == AV_FIELD_TB)
2695  print_str("field_order", "tb");
2696  else if (par->field_order == AV_FIELD_BT)
2697  print_str("field_order", "bt");
2698  else
2699  print_str_opt("field_order", "unknown");
2700 
2701  if (dec_ctx)
2702  print_int("refs", dec_ctx->refs);
2703  break;
2704 
2705  case AVMEDIA_TYPE_AUDIO:
2706  s = av_get_sample_fmt_name(par->format);
2707  if (s) print_str ("sample_fmt", s);
2708  else print_str_opt("sample_fmt", "unknown");
2709  print_val("sample_rate", par->sample_rate, unit_hertz_str);
2710  print_int("channels", par->channels);
2711 
2712  if (par->channel_layout) {
2713  av_bprint_clear(&pbuf);
2714  av_bprint_channel_layout(&pbuf, par->channels, par->channel_layout);
2715  print_str ("channel_layout", pbuf.str);
2716  } else {
2717  print_str_opt("channel_layout", "unknown");
2718  }
2719 
2720  print_int("bits_per_sample", av_get_bits_per_sample(par->codec_id));
2721  break;
2722 
2723  case AVMEDIA_TYPE_SUBTITLE:
2724  if (par->width)
2725  print_int("width", par->width);
2726  else
2727  print_str_opt("width", "N/A");
2728  if (par->height)
2729  print_int("height", par->height);
2730  else
2731  print_str_opt("height", "N/A");
2732  break;
2733  }
2734 
2735  if (dec_ctx && dec_ctx->codec && dec_ctx->codec->priv_class && show_private_data) {
2736  const AVOption *opt = NULL;
2737  while ((opt = av_opt_next(dec_ctx->priv_data,opt))) {
2738  uint8_t *str;
2739  if (!(opt->flags & AV_OPT_FLAG_EXPORT)) continue;
2740  if (av_opt_get(dec_ctx->priv_data, opt->name, 0, &str) >= 0) {
2741  print_str(opt->name, str);
2742  av_free(str);
2743  }
2744  }
2745  }
2746 
2747  if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS) print_fmt ("id", "0x%x", stream->id);
2748  else print_str_opt("id", "N/A");
2749  print_q("r_frame_rate", stream->r_frame_rate, '/');
2750  print_q("avg_frame_rate", stream->avg_frame_rate, '/');
2751  print_q("time_base", stream->time_base, '/');
2752  print_ts ("start_pts", stream->start_time);
2753  print_time("start_time", stream->start_time, &stream->time_base);
2754  print_ts ("duration_ts", stream->duration);
2755  print_time("duration", stream->duration, &stream->time_base);
2756  if (par->bit_rate > 0) print_val ("bit_rate", par->bit_rate, unit_bit_per_second_str);
2757  else print_str_opt("bit_rate", "N/A");
2758  if (dec_ctx && dec_ctx->rc_max_rate > 0)
2759  print_val ("max_bit_rate", dec_ctx->rc_max_rate, unit_bit_per_second_str);
2760  else
2761  print_str_opt("max_bit_rate", "N/A");
2762  if (dec_ctx && dec_ctx->bits_per_raw_sample > 0) print_fmt("bits_per_raw_sample", "%d", dec_ctx->bits_per_raw_sample);
2763  else print_str_opt("bits_per_raw_sample", "N/A");
2764  if (stream->nb_frames) print_fmt ("nb_frames", "%"PRId64, stream->nb_frames);
2765  else print_str_opt("nb_frames", "N/A");
2766  if (nb_streams_frames[stream_idx]) print_fmt ("nb_read_frames", "%"PRIu64, nb_streams_frames[stream_idx]);
2767  else print_str_opt("nb_read_frames", "N/A");
2768  if (nb_streams_packets[stream_idx]) print_fmt ("nb_read_packets", "%"PRIu64, nb_streams_packets[stream_idx]);
2769  else print_str_opt("nb_read_packets", "N/A");
2770  if (do_show_data)
2771  writer_print_data(w, "extradata", par->extradata,
2772  par->extradata_size);
2773 
2774  if (par->extradata_size > 0) {
2775  writer_print_data_hash(w, "extradata_hash", par->extradata,
2776  par->extradata_size);
2777  }
2778 
2779  /* Print disposition information */
2780 #define PRINT_DISPOSITION(flagname, name) do { \
2781  print_int(name, !!(stream->disposition & AV_DISPOSITION_##flagname)); \
2782  } while (0)
2783 
2786  PRINT_DISPOSITION(DEFAULT, "default");
2787  PRINT_DISPOSITION(DUB, "dub");
2788  PRINT_DISPOSITION(ORIGINAL, "original");
2789  PRINT_DISPOSITION(COMMENT, "comment");
2790  PRINT_DISPOSITION(LYRICS, "lyrics");
2791  PRINT_DISPOSITION(KARAOKE, "karaoke");
2792  PRINT_DISPOSITION(FORCED, "forced");
2793  PRINT_DISPOSITION(HEARING_IMPAIRED, "hearing_impaired");
2794  PRINT_DISPOSITION(VISUAL_IMPAIRED, "visual_impaired");
2795  PRINT_DISPOSITION(CLEAN_EFFECTS, "clean_effects");
2796  PRINT_DISPOSITION(ATTACHED_PIC, "attached_pic");
2797  PRINT_DISPOSITION(TIMED_THUMBNAILS, "timed_thumbnails");
2798  PRINT_DISPOSITION(CAPTIONS, "captions");
2799  PRINT_DISPOSITION(DESCRIPTIONS, "descriptions");
2800  PRINT_DISPOSITION(METADATA, "metadata");
2801  PRINT_DISPOSITION(DEPENDENT, "dependent");
2802  PRINT_DISPOSITION(STILL_IMAGE, "still_image");
2804  }
2805 
2806  if (do_show_stream_tags)
2807  ret = show_tags(w, stream->metadata, in_program ? SECTION_ID_PROGRAM_STREAM_TAGS : SECTION_ID_STREAM_TAGS);
2808 
2809  if (stream->nb_side_data) {
2810  print_pkt_side_data(w, stream->codecpar, stream->side_data, stream->nb_side_data,
2813  }
2814 
2816  av_bprint_finalize(&pbuf, NULL);
2817  fflush(stdout);
2818 
2819  return ret;
2820 }
2821 
2822 static int show_streams(WriterContext *w, InputFile *ifile)
2823 {
2824  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2825  int i, ret = 0;
2826 
2828  for (i = 0; i < ifile->nb_streams; i++)
2829  if (selected_streams[i]) {
2830  ret = show_stream(w, fmt_ctx, i, &ifile->streams[i], 0);
2831  if (ret < 0)
2832  break;
2833  }
2835 
2836  return ret;
2837 }
2838 
2839 static int show_program(WriterContext *w, InputFile *ifile, AVProgram *program)
2840 {
2841  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2842  int i, ret = 0;
2843 
2845  print_int("program_id", program->id);
2846  print_int("program_num", program->program_num);
2847  print_int("nb_streams", program->nb_stream_indexes);
2848  print_int("pmt_pid", program->pmt_pid);
2849  print_int("pcr_pid", program->pcr_pid);
2850  print_ts("start_pts", program->start_time);
2851  print_time("start_time", program->start_time, &AV_TIME_BASE_Q);
2852  print_ts("end_pts", program->end_time);
2853  print_time("end_time", program->end_time, &AV_TIME_BASE_Q);
2855  ret = show_tags(w, program->metadata, SECTION_ID_PROGRAM_TAGS);
2856  if (ret < 0)
2857  goto end;
2858 
2860  for (i = 0; i < program->nb_stream_indexes; i++) {
2861  if (selected_streams[program->stream_index[i]]) {
2862  ret = show_stream(w, fmt_ctx, program->stream_index[i], &ifile->streams[program->stream_index[i]], 1);
2863  if (ret < 0)
2864  break;
2865  }
2866  }
2868 
2869 end:
2871  return ret;
2872 }
2873 
2874 static int show_programs(WriterContext *w, InputFile *ifile)
2875 {
2876  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2877  int i, ret = 0;
2878 
2880  for (i = 0; i < fmt_ctx->nb_programs; i++) {
2881  AVProgram *program = fmt_ctx->programs[i];
2882  if (!program)
2883  continue;
2884  ret = show_program(w, ifile, program);
2885  if (ret < 0)
2886  break;
2887  }
2889  return ret;
2890 }
2891 
2892 static int show_chapters(WriterContext *w, InputFile *ifile)
2893 {
2894  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2895  int i, ret = 0;
2896 
2898  for (i = 0; i < fmt_ctx->nb_chapters; i++) {
2899  AVChapter *chapter = fmt_ctx->chapters[i];
2900 
2902  print_int("id", chapter->id);
2903  print_q ("time_base", chapter->time_base, '/');
2904  print_int("start", chapter->start);
2905  print_time("start_time", chapter->start, &chapter->time_base);
2906  print_int("end", chapter->end);
2907  print_time("end_time", chapter->end, &chapter->time_base);
2909  ret = show_tags(w, chapter->metadata, SECTION_ID_CHAPTER_TAGS);
2911  }
2913 
2914  return ret;
2915 }
2916 
2917 static int show_format(WriterContext *w, InputFile *ifile)
2918 {
2919  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2920  char val_str[128];
2921  int64_t size = fmt_ctx->pb ? avio_size(fmt_ctx->pb) : -1;
2922  int ret = 0;
2923 
2925  print_str_validate("filename", fmt_ctx->url);
2926  print_int("nb_streams", fmt_ctx->nb_streams);
2927  print_int("nb_programs", fmt_ctx->nb_programs);
2928  print_str("format_name", fmt_ctx->iformat->name);
2929  if (!do_bitexact) {
2930  if (fmt_ctx->iformat->long_name) print_str ("format_long_name", fmt_ctx->iformat->long_name);
2931  else print_str_opt("format_long_name", "unknown");
2932  }
2933  print_time("start_time", fmt_ctx->start_time, &AV_TIME_BASE_Q);
2934  print_time("duration", fmt_ctx->duration, &AV_TIME_BASE_Q);
2935  if (size >= 0) print_val ("size", size, unit_byte_str);
2936  else print_str_opt("size", "N/A");
2937  if (fmt_ctx->bit_rate > 0) print_val ("bit_rate", fmt_ctx->bit_rate, unit_bit_per_second_str);
2938  else print_str_opt("bit_rate", "N/A");
2939  print_int("probe_score", fmt_ctx->probe_score);
2940  if (do_show_format_tags)
2941  ret = show_tags(w, fmt_ctx->metadata, SECTION_ID_FORMAT_TAGS);
2942 
2944  fflush(stdout);
2945  return ret;
2946 }
2947 
2948 static void show_error(WriterContext *w, int err)
2949 {
2950  char errbuf[128];
2951  const char *errbuf_ptr = errbuf;
2952 
2953  if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
2954  errbuf_ptr = strerror(AVUNERROR(err));
2955 
2957  print_int("code", err);
2958  print_str("string", errbuf_ptr);
2960 }
2961 
2962 static int open_input_file(InputFile *ifile, const char *filename, const char *print_filename)
2963 {
2964  int err, i;
2965  AVFormatContext *fmt_ctx = NULL;
2966  AVDictionaryEntry *t = NULL;
2967  int scan_all_pmts_set = 0;
2968 
2969  fmt_ctx = avformat_alloc_context();
2970  if (!fmt_ctx) {
2971  print_error(filename, AVERROR(ENOMEM));
2972  exit_program(1);
2973  }
2974 
2975  if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2976  av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2977  scan_all_pmts_set = 1;
2978  }
2979  if ((err = avformat_open_input(&fmt_ctx, filename,
2980  iformat, &format_opts)) < 0) {
2981  print_error(filename, err);
2982  return err;
2983  }
2984  if (print_filename) {
2985  av_freep(&fmt_ctx->url);
2986  fmt_ctx->url = av_strdup(print_filename);
2987  }
2988  ifile->fmt_ctx = fmt_ctx;
2989  if (scan_all_pmts_set)
2990  av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2991  while ((t = av_dict_get(format_opts, "", t, AV_DICT_IGNORE_SUFFIX)))
2992  av_log(NULL, AV_LOG_WARNING, "Option %s skipped - not known to demuxer.\n", t->key);
2993 
2994  if (find_stream_info) {
2995  AVDictionary **opts = setup_find_stream_info_opts(fmt_ctx, codec_opts);
2996  int orig_nb_streams = fmt_ctx->nb_streams;
2997 
2998  err = avformat_find_stream_info(fmt_ctx, opts);
2999 
3000  for (i = 0; i < orig_nb_streams; i++)
3001  av_dict_free(&opts[i]);
3002  av_freep(&opts);
3003 
3004  if (err < 0) {
3005  print_error(filename, err);
3006  return err;
3007  }
3008  }
3009 
3010  av_dump_format(fmt_ctx, 0, filename, 0);
3011 
3012  ifile->streams = av_mallocz_array(fmt_ctx->nb_streams,
3013  sizeof(*ifile->streams));
3014  if (!ifile->streams)
3015  exit(1);
3016  ifile->nb_streams = fmt_ctx->nb_streams;
3017 
3018  /* bind a decoder to each input stream */
3019  for (i = 0; i < fmt_ctx->nb_streams; i++) {
3020  InputStream *ist = &ifile->streams[i];
3021  AVStream *stream = fmt_ctx->streams[i];
3022  const AVCodec *codec;
3023 
3024  ist->st = stream;
3025 
3026  if (stream->codecpar->codec_id == AV_CODEC_ID_PROBE) {
3027  av_log(NULL, AV_LOG_WARNING,
3028  "Failed to probe codec for input stream %d\n",
3029  stream->index);
3030  continue;
3031  }
3032 
3033  codec = avcodec_find_decoder(stream->codecpar->codec_id);
3034  if (!codec) {
3035  av_log(NULL, AV_LOG_WARNING,
3036  "Unsupported codec with id %d for input stream %d\n",
3037  stream->codecpar->codec_id, stream->index);
3038  continue;
3039  }
3040  {
3041  AVDictionary *opts = filter_codec_opts(codec_opts, stream->codecpar->codec_id,
3042  fmt_ctx, stream, codec);
3043 
3044  ist->dec_ctx = avcodec_alloc_context3(codec);
3045  if (!ist->dec_ctx)
3046  exit(1);
3047 
3048  err = avcodec_parameters_to_context(ist->dec_ctx, stream->codecpar);
3049  if (err < 0)
3050  exit(1);
3051 
3052  if (do_show_log) {
3053  // For loging it is needed to disable at least frame threads as otherwise
3054  // the log information would need to be reordered and matches up to contexts and frames
3055  // That is in fact possible but not trivial
3056  av_dict_set(&codec_opts, "threads", "1", 0);
3057  }
3058 
3059  ist->dec_ctx->pkt_timebase = stream->time_base;
3060 
3061  if (avcodec_open2(ist->dec_ctx, codec, &opts) < 0) {
3062  av_log(NULL, AV_LOG_WARNING, "Could not open codec for input stream %d\n",
3063  stream->index);
3064  exit(1);
3065  }
3066 
3067  if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
3068  av_log(NULL, AV_LOG_ERROR, "Option %s for input stream %d not found\n",
3069  t->key, stream->index);
3070  return AVERROR_OPTION_NOT_FOUND;
3071  }
3072  }
3073  }
3074 
3075  ifile->fmt_ctx = fmt_ctx;
3076  return 0;
3077 }
3078 
3079 static void close_input_file(InputFile *ifile)
3080 {
3081  int i;
3082 
3083  /* close decoder for each stream */
3084  for (i = 0; i < ifile->nb_streams; i++)
3085  avcodec_free_context(&ifile->streams[i].dec_ctx);
3086 
3087  av_freep(&ifile->streams);
3088  ifile->nb_streams = 0;
3089 
3090  avformat_close_input(&ifile->fmt_ctx);
3091 }
3092 
3093 static int probe_file(WriterContext *wctx, const char *filename,
3094  const char *print_filename)
3095 {
3096  InputFile ifile = { 0 };
3097  int ret, i;
3098  int section_id;
3099 
3102 
3103  ret = open_input_file(&ifile, filename, print_filename);
3104  if (ret < 0)
3105  goto end;
3106 
3107 #define CHECK_END if (ret < 0) goto end
3108 
3109  nb_streams = ifile.fmt_ctx->nb_streams;
3110  REALLOCZ_ARRAY_STREAM(nb_streams_frames,0,ifile.fmt_ctx->nb_streams);
3111  REALLOCZ_ARRAY_STREAM(nb_streams_packets,0,ifile.fmt_ctx->nb_streams);
3112  REALLOCZ_ARRAY_STREAM(selected_streams,0,ifile.fmt_ctx->nb_streams);
3113 
3114  for (i = 0; i < ifile.fmt_ctx->nb_streams; i++) {
3115  if (stream_specifier) {
3116  ret = avformat_match_stream_specifier(ifile.fmt_ctx,
3117  ifile.fmt_ctx->streams[i],
3119  CHECK_END;
3120  else
3121  selected_streams[i] = ret;
3122  ret = 0;
3123  } else {
3124  selected_streams[i] = 1;
3125  }
3126  if (!selected_streams[i])
3127  ifile.fmt_ctx->streams[i]->discard = AVDISCARD_ALL;
3128  }
3129 
3133  section_id = SECTION_ID_PACKETS_AND_FRAMES;
3134  else if (do_show_packets && !do_show_frames)
3135  section_id = SECTION_ID_PACKETS;
3136  else // (!do_show_packets && do_show_frames)
3137  section_id = SECTION_ID_FRAMES;
3139  writer_print_section_header(wctx, section_id);
3140  ret = read_packets(wctx, &ifile);
3143  CHECK_END;
3144  }
3145 
3146  if (do_show_programs) {
3147  ret = show_programs(wctx, &ifile);
3148  CHECK_END;
3149  }
3150 
3151  if (do_show_streams) {
3152  ret = show_streams(wctx, &ifile);
3153  CHECK_END;
3154  }
3155  if (do_show_chapters) {
3156  ret = show_chapters(wctx, &ifile);
3157  CHECK_END;
3158  }
3159  if (do_show_format) {
3160  ret = show_format(wctx, &ifile);
3161  CHECK_END;
3162  }
3163 
3164 end:
3165  if (ifile.fmt_ctx)
3166  close_input_file(&ifile);
3167  av_freep(&nb_streams_frames);
3168  av_freep(&nb_streams_packets);
3169  av_freep(&selected_streams);
3170 
3171  return ret;
3172 }
3173 
3174 static void show_usage(void)
3175 {
3176  av_log(NULL, AV_LOG_INFO, "Simple multimedia streams analyzer\n");
3177  av_log(NULL, AV_LOG_INFO, "usage: %s [OPTIONS] [INPUT_FILE]\n", program_name);
3178  av_log(NULL, AV_LOG_INFO, "\n");
3179 }
3180 
3182 {
3183  AVBPrint pbuf;
3184  av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
3185 
3187  print_str("version", FFMPEG_VERSION);
3188  print_fmt("copyright", "Copyright (c) %d-%d the FFmpeg developers",
3189  program_birth_year, CONFIG_THIS_YEAR);
3190  print_str("compiler_ident", CC_IDENT);
3191  print_str("configuration", FFMPEG_CONFIGURATION);
3193 
3194  av_bprint_finalize(&pbuf, NULL);
3195 }
3196 
3197 #define SHOW_LIB_VERSION(libname, LIBNAME) \
3198  do { \
3199  if (CONFIG_##LIBNAME) { \
3200  unsigned int version = libname##_version(); \
3201  writer_print_section_header(w, SECTION_ID_LIBRARY_VERSION); \
3202  print_str("name", "lib" #libname); \
3203  print_int("major", LIB##LIBNAME##_VERSION_MAJOR); \
3204  print_int("minor", LIB##LIBNAME##_VERSION_MINOR); \
3205  print_int("micro", LIB##LIBNAME##_VERSION_MICRO); \
3206  print_int("version", version); \
3207  print_str("ident", LIB##LIBNAME##_IDENT); \
3208  writer_print_section_footer(w); \
3209  } \
3210  } while (0)
3211 
3213 {
3215  SHOW_LIB_VERSION(avutil, AVUTIL);
3216  SHOW_LIB_VERSION(avcodec, AVCODEC);
3217  SHOW_LIB_VERSION(avformat, AVFORMAT);
3218  SHOW_LIB_VERSION(avdevice, AVDEVICE);
3219  SHOW_LIB_VERSION(avfilter, AVFILTER);
3220  SHOW_LIB_VERSION(swscale, SWSCALE);
3221  SHOW_LIB_VERSION(swresample, SWRESAMPLE);
3223 }
3224 
3225 #define PRINT_PIX_FMT_FLAG(flagname, name) \
3226  do { \
3227  print_int(name, !!(pixdesc->flags & AV_PIX_FMT_FLAG_##flagname)); \
3228  } while (0)
3229 
3231 {
3232  const AVPixFmtDescriptor *pixdesc = NULL;
3233  int i, n;
3234 
3236  while ((pixdesc = av_pix_fmt_desc_next(pixdesc))) {
3238  print_str("name", pixdesc->name);
3239  print_int("nb_components", pixdesc->nb_components);
3240  if ((pixdesc->nb_components >= 3) && !(pixdesc->flags & AV_PIX_FMT_FLAG_RGB)) {
3241  print_int ("log2_chroma_w", pixdesc->log2_chroma_w);
3242  print_int ("log2_chroma_h", pixdesc->log2_chroma_h);
3243  } else {
3244  print_str_opt("log2_chroma_w", "N/A");
3245  print_str_opt("log2_chroma_h", "N/A");
3246  }
3247  n = av_get_bits_per_pixel(pixdesc);
3248  if (n) print_int ("bits_per_pixel", n);
3249  else print_str_opt("bits_per_pixel", "N/A");
3252  PRINT_PIX_FMT_FLAG(BE, "big_endian");
3253  PRINT_PIX_FMT_FLAG(PAL, "palette");
3254  PRINT_PIX_FMT_FLAG(BITSTREAM, "bitstream");
3255  PRINT_PIX_FMT_FLAG(HWACCEL, "hwaccel");
3256  PRINT_PIX_FMT_FLAG(PLANAR, "planar");
3257  PRINT_PIX_FMT_FLAG(RGB, "rgb");
3258  PRINT_PIX_FMT_FLAG(ALPHA, "alpha");
3260  }
3261  if (do_show_pixel_format_components && (pixdesc->nb_components > 0)) {
3263  for (i = 0; i < pixdesc->nb_components; i++) {
3265  print_int("index", i + 1);
3266  print_int("bit_depth", pixdesc->comp[i].depth);
3268  }
3270  }
3272  }
3274 }
3275 
3276 static int opt_show_optional_fields(void *optctx, const char *opt, const char *arg)
3277 {
3278  if (!av_strcasecmp(arg, "always")) show_optional_fields = SHOW_OPTIONAL_FIELDS_ALWAYS;
3279  else if (!av_strcasecmp(arg, "never")) show_optional_fields = SHOW_OPTIONAL_FIELDS_NEVER;
3280  else if (!av_strcasecmp(arg, "auto")) show_optional_fields = SHOW_OPTIONAL_FIELDS_AUTO;
3281 
3282  if (show_optional_fields == SHOW_OPTIONAL_FIELDS_AUTO && av_strcasecmp(arg, "auto"))
3284  return 0;
3285 }
3286 
3287 static int opt_format(void *optctx, const char *opt, const char *arg)
3288 {
3289  iformat = av_find_input_format(arg);
3290  if (!iformat) {
3291  av_log(NULL, AV_LOG_ERROR, "Unknown input format: %s\n", arg);
3292  return AVERROR(EINVAL);
3293  }
3294  return 0;
3295 }
3296 
3297 static inline void mark_section_show_entries(SectionID section_id,
3298  int show_all_entries, AVDictionary *entries)
3299 {
3300  struct section *section = &sections[section_id];
3301 
3303  if (show_all_entries) {
3304  SectionID *id;
3305  for (id = section->children_ids; *id != -1; id++)
3307  } else {
3308  av_dict_copy(&section->entries_to_show, entries, 0);
3309  }
3310 }
3311 
3312 static int match_section(const char *section_name,
3313  int show_all_entries, AVDictionary *entries)
3314 {
3315  int i, ret = 0;
3316 
3317  for (i = 0; i < FF_ARRAY_ELEMS(sections); i++) {
3318  const struct section *section = &sections[i];
3319  if (!strcmp(section_name, section->name) ||
3320  (section->unique_name && !strcmp(section_name, section->unique_name))) {
3321  av_log(NULL, AV_LOG_DEBUG,
3322  "'%s' matches section with unique name '%s'\n", section_name,
3323  (char *)av_x_if_null(section->unique_name, section->name));
3324  ret++;
3326  }
3327  }
3328  return ret;
3329 }
3330 
3331 static int opt_show_entries(void *optctx, const char *opt, const char *arg)
3332 {
3333  const char *p = arg;
3334  int ret = 0;
3335 
3336  while (*p) {
3337  AVDictionary *entries = NULL;
3338  char *section_name = av_get_token(&p, "=:");
3339  int show_all_entries = 0;
3340 
3341  if (!section_name) {
3342  av_log(NULL, AV_LOG_ERROR,
3343  "Missing section name for option '%s'\n", opt);
3344  return AVERROR(EINVAL);
3345  }
3346 
3347  if (*p == '=') {
3348  p++;
3349  while (*p && *p != ':') {
3350  char *entry = av_get_token(&p, ",:");
3351  if (!entry)
3352  break;
3353  av_log(NULL, AV_LOG_VERBOSE,
3354  "Adding '%s' to the entries to show in section '%s'\n",
3355  entry, section_name);
3356  av_dict_set(&entries, entry, "", AV_DICT_DONT_STRDUP_KEY);
3357  if (*p == ',')
3358  p++;
3359  }
3360  } else {
3361  show_all_entries = 1;
3362  }
3363 
3364  ret = match_section(section_name, show_all_entries, entries);
3365  if (ret == 0) {
3366  av_log(NULL, AV_LOG_ERROR, "No match for section '%s'\n", section_name);
3367  ret = AVERROR(EINVAL);
3368  }
3369  av_dict_free(&entries);
3370  av_free(section_name);
3371 
3372  if (ret <= 0)
3373  break;
3374  if (*p)
3375  p++;
3376  }
3377 
3378  return ret;
3379 }
3380 
3381 static int opt_show_format_entry(void *optctx, const char *opt, const char *arg)
3382 {
3383  char *buf = av_asprintf("format=%s", arg);
3384  int ret;
3385 
3386  if (!buf)
3387  return AVERROR(ENOMEM);
3388 
3389  av_log(NULL, AV_LOG_WARNING,
3390  "Option '%s' is deprecated, use '-show_entries format=%s' instead\n",
3391  opt, arg);
3392  ret = opt_show_entries(optctx, opt, buf);
3393  av_free(buf);
3394  return ret;
3395 }
3396 
3397 static void opt_input_file(void *optctx, const char *arg)
3398 {
3399  if (input_filename) {
3400  av_log(NULL, AV_LOG_ERROR,
3401  "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3402  arg, input_filename);
3403  exit_program(1);
3404  }
3405  if (!strcmp(arg, "-"))
3406  arg = "pipe:";
3407  input_filename = arg;
3408 }
3409 
3410 static int opt_input_file_i(void *optctx, const char *opt, const char *arg)
3411 {
3412  opt_input_file(optctx, arg);
3413  return 0;
3414 }
3415 
3416 static int opt_print_filename(void *optctx, const char *opt, const char *arg)
3417 {
3418  print_input_filename = arg;
3419  return 0;
3420 }
3421 
3422 void show_help_default_ffprobe(const char *opt, const char *arg)
3423 {
3424  show_usage();
3425  show_help_options(ffprobe_options, "Main options:", 0, 0, 0);
3426  av_log(NULL, AV_LOG_STDERR, "\n");
3427 
3428  show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3429  show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
3430 }
3431 
3437 static int parse_read_interval(const char *interval_spec,
3438  ReadInterval *interval)
3439 {
3440  int ret = 0;
3441  char *next, *p, *spec = av_strdup(interval_spec);
3442  if (!spec)
3443  return AVERROR(ENOMEM);
3444 
3445  if (!*spec) {
3446  av_log(NULL, AV_LOG_ERROR, "Invalid empty interval specification\n");
3447  ret = AVERROR(EINVAL);
3448  goto end;
3449  }
3450 
3451  p = spec;
3452  next = strchr(spec, '%');
3453  if (next)
3454  *next++ = 0;
3455 
3456  /* parse first part */
3457  if (*p) {
3458  interval->has_start = 1;
3459 
3460  if (*p == '+') {
3461  interval->start_is_offset = 1;
3462  p++;
3463  } else {
3464  interval->start_is_offset = 0;
3465  }
3466 
3467  ret = av_parse_time(&interval->start, p, 1);
3468  if (ret < 0) {
3469  av_log(NULL, AV_LOG_ERROR, "Invalid interval start specification '%s'\n", p);
3470  goto end;
3471  }
3472  } else {
3473  interval->has_start = 0;
3474  }
3475 
3476  /* parse second part */
3477  p = next;
3478  if (p && *p) {
3479  int64_t us;
3480  interval->has_end = 1;
3481 
3482  if (*p == '+') {
3483  interval->end_is_offset = 1;
3484  p++;
3485  } else {
3486  interval->end_is_offset = 0;
3487  }
3488 
3489  if (interval->end_is_offset && *p == '#') {
3490  long long int lli;
3491  char *tail;
3492  interval->duration_frames = 1;
3493  p++;
3494  lli = strtoll(p, &tail, 10);
3495  if (*tail || lli < 0) {
3496  av_log(NULL, AV_LOG_ERROR,
3497  "Invalid or negative value '%s' for duration number of frames\n", p);
3498  goto end;
3499  }
3500  interval->end = lli;
3501  } else {
3502  interval->duration_frames = 0;
3503  ret = av_parse_time(&us, p, 1);
3504  if (ret < 0) {
3505  av_log(NULL, AV_LOG_ERROR, "Invalid interval end/duration specification '%s'\n", p);
3506  goto end;
3507  }
3508  interval->end = us;
3509  }
3510  } else {
3511  interval->has_end = 0;
3512  }
3513 
3514 end:
3515  av_free(spec);
3516  return ret;
3517 }
3518 
3519 static int parse_read_intervals(const char *intervals_spec)
3520 {
3521  int ret, n, i;
3522  char *p, *spec = av_strdup(intervals_spec);
3523  if (!spec)
3524  return AVERROR(ENOMEM);
3525 
3526  /* preparse specification, get number of intervals */
3527  for (n = 0, p = spec; *p; p++)
3528  if (*p == ',')
3529  n++;
3530  n++;
3531 
3532  read_intervals = av_malloc_array(n, sizeof(*read_intervals));
3533  if (!read_intervals) {
3534  ret = AVERROR(ENOMEM);
3535  goto end;
3536  }
3537  read_intervals_nb = n;
3538 
3539  /* parse intervals */
3540  p = spec;
3541  for (i = 0; p; i++) {
3542  char *next;
3543 
3544  av_assert0(i < read_intervals_nb);
3545  next = strchr(p, ',');
3546  if (next)
3547  *next++ = 0;
3548 
3549  read_intervals[i].id = i;
3550  ret = parse_read_interval(p, &read_intervals[i]);
3551  if (ret < 0) {
3552  av_log(NULL, AV_LOG_ERROR, "Error parsing read interval #%d '%s'\n",
3553  i, p);
3554  goto end;
3555  }
3556  av_log(NULL, AV_LOG_VERBOSE, "Parsed log interval ");
3557  log_read_interval(&read_intervals[i], NULL, AV_LOG_VERBOSE);
3558  p = next;
3559  }
3560  av_assert0(i == read_intervals_nb);
3561 
3562 end:
3563  av_free(spec);
3564  return ret;
3565 }
3566 
3567 static int opt_read_intervals(void *optctx, const char *opt, const char *arg)
3568 {
3569  return parse_read_intervals(arg);
3570 }
3571 
3572 static int opt_pretty(void *optctx, const char *opt, const char *arg)
3573 {
3574  show_value_unit = 1;
3575  use_value_prefix = 1;
3578  return 0;
3579 }
3580 
3581 static void print_section(SectionID id, int level)
3582 {
3583  const SectionID *pid;
3584  const struct section *section = &sections[id];
3585  av_log(NULL, AV_LOG_STDERR, "%c%c%c",
3586  section->flags & SECTION_FLAG_IS_WRAPPER ? 'W' : '.',
3587  section->flags & SECTION_FLAG_IS_ARRAY ? 'A' : '.',
3589  av_log(NULL, AV_LOG_STDERR, "%*c %s", level * 4, ' ', section->name);
3590  if (section->unique_name)
3591  av_log(NULL, AV_LOG_STDERR, "/%s", section->unique_name);
3592  av_log(NULL, AV_LOG_STDERR, "\n");
3593 
3594  for (pid = section->children_ids; *pid != -1; pid++)
3595  print_section(*pid, level+1);
3596 }
3597 
3598 static int opt_sections(void *optctx, const char *opt, const char *arg)
3599 {
3600  av_log(NULL, AV_LOG_STDERR, "Sections:\n"
3601  "W.. = Section is a wrapper (contains other sections, no local entries)\n"
3602  ".A. = Section contains an array of elements of the same type\n"
3603  "..V = Section may contain a variable number of fields with variable keys\n"
3604  "FLAGS NAME/UNIQUE_NAME\n"
3605  "---\n");
3607  return 0;
3608 }
3609 
3610 static int opt_show_versions(void *optctx, const char *opt, const char *arg)
3611 {
3614  return 0;
3615 }
3616 
3617 #define DEFINE_OPT_SHOW_SECTION(section, target_section_id) \
3618  static int opt_show_##section(void *optctx, const char *opt, const char *arg) \
3619  { \
3620  mark_section_show_entries(SECTION_ID_##target_section_id, 1, NULL); \
3621  return 0; \
3622  }
3623 
3624 DEFINE_OPT_SHOW_SECTION(chapters, CHAPTERS)
3625 DEFINE_OPT_SHOW_SECTION(error, ERROR)
3627 DEFINE_OPT_SHOW_SECTION(frames, FRAMES)
3628 DEFINE_OPT_SHOW_SECTION(library_versions, LIBRARY_VERSIONS)
3629 DEFINE_OPT_SHOW_SECTION(packets, PACKETS)
3630 DEFINE_OPT_SHOW_SECTION(pixel_formats, PIXEL_FORMATS)
3631 DEFINE_OPT_SHOW_SECTION(program_version, PROGRAM_VERSION)
3632 DEFINE_OPT_SHOW_SECTION(streams, STREAMS)
3633 DEFINE_OPT_SHOW_SECTION(programs, PROGRAMS)
3634 
3635 static inline int check_section_show_entries(int section_id)
3636 {
3637  int *id;
3638  struct section *section = &sections[section_id];
3639  if (sections[section_id].show_all_entries || sections[section_id].entries_to_show)
3640  return 1;
3641  for (id = section->children_ids; *id != -1; id++)
3642  if (check_section_show_entries(*id))
3643  return 1;
3644  return 0;
3645 }
3646 
3647 #define SET_DO_SHOW(id, varname) do { \
3648  if (check_section_show_entries(SECTION_ID_##id)) \
3649  do_show_##varname = 1; \
3650  } while (0)
3651 
3654  longjmp_value = 0;
3655 
3656  do_bitexact = 0;
3657  do_count_frames = 0;
3658  do_count_packets = 0;
3659  do_read_frames = 0;
3660  do_read_packets = 0;
3661  do_show_chapters = 0;
3662  do_show_error = 0;
3663  do_show_format = 0;
3664  do_show_frames = 0;
3665  do_show_packets = 0;
3666  do_show_programs = 0;
3667  do_show_streams = 0;
3669  do_show_data = 0;
3675  do_show_log = 0;
3676 
3678  do_show_format_tags = 0;
3679  do_show_frame_tags = 0;
3681  do_show_stream_tags = 0;
3682  do_show_packet_tags = 0;
3683 
3684  show_value_unit = 0;
3685  use_value_prefix = 0;
3688  show_private_data = 1;
3689 
3690  print_format = NULL;
3691  stream_specifier = NULL;
3692  show_data_hash = NULL;
3693 
3694  read_intervals = NULL;
3695  read_intervals_nb = 0;
3696  find_stream_info = 1;
3697 
3698  ffprobe_options = NULL;
3699 
3700  input_filename = NULL;
3701  print_input_filename = NULL;
3702  iformat = NULL;
3703 
3704  hash = NULL;
3705 
3707 
3708  nb_streams = 0;
3709  nb_streams_packets = NULL;
3710  nb_streams_frames = NULL;
3711  selected_streams = NULL;
3712 
3713  log_buffer = NULL;
3714  log_buffer_size = 0;
3715 }
3716 
3717 int ffprobe_execute(int argc, char **argv)
3718 {
3719  char _program_name[] = "ffprobe";
3720  program_name = (char*)&_program_name;
3721  program_birth_year = 2007;
3722 
3723  OptionDef options[] = {
3724  { "L", OPT_EXIT, { .func_arg = show_license }, "show license" },
3725  { "h", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" },
3726  { "?", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" },
3727  { "help", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" },
3728  { "-help", OPT_EXIT, { .func_arg = show_help }, "show help", "topic" },
3729  { "version", OPT_EXIT, { .func_arg = show_version }, "show version" },
3730  { "buildconf", OPT_EXIT, { .func_arg = show_buildconf }, "show build configuration" },
3731  { "formats", OPT_EXIT, { .func_arg = show_formats }, "show available formats" },
3732  { "muxers", OPT_EXIT, { .func_arg = show_muxers }, "show available muxers" },
3733  { "demuxers", OPT_EXIT, { .func_arg = show_demuxers }, "show available demuxers" },
3734  { "devices", OPT_EXIT, { .func_arg = show_devices }, "show available devices" },
3735  { "codecs", OPT_EXIT, { .func_arg = show_codecs }, "show available codecs" },
3736  { "decoders", OPT_EXIT, { .func_arg = show_decoders }, "show available decoders" },
3737  { "encoders", OPT_EXIT, { .func_arg = show_encoders }, "show available encoders" },
3738  { "bsfs", OPT_EXIT, { .func_arg = show_bsfs }, "show available bit stream filters" },
3739  { "protocols", OPT_EXIT, { .func_arg = show_protocols }, "show available protocols" },
3740  { "filters", OPT_EXIT, { .func_arg = show_filters }, "show available filters" },
3741  { "pix_fmts", OPT_EXIT, { .func_arg = show_pix_fmts }, "show available pixel formats" },
3742  { "layouts", OPT_EXIT, { .func_arg = show_layouts }, "show standard channel layouts" },
3743  { "sample_fmts", OPT_EXIT, { .func_arg = show_sample_fmts }, "show available audio sample formats" },
3744  { "colors", OPT_EXIT, { .func_arg = show_colors }, "show available color names" },
3745  { "loglevel", HAS_ARG, { .func_arg = opt_loglevel }, "set logging level", "loglevel" },
3746  { "v", HAS_ARG, { .func_arg = opt_loglevel }, "set logging level", "loglevel" },
3747  { "report", 0, { .func_arg = opt_report }, "generate a report" },
3748  { "max_alloc", HAS_ARG, { .func_arg = opt_max_alloc }, "set maximum size of a single allocated block", "bytes" },
3749  { "cpuflags", HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpuflags }, "force specific cpu flags", "flags" },
3750  { "cpucount", HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpucount }, "force specific cpu count", "count" },
3751  { "hide_banner", OPT_BOOL | OPT_EXPERT, {&hide_banner}, "do not show program banner", "hide_banner" },
3752 
3753  #if CONFIG_AVDEVICE
3754  { "sources" , OPT_EXIT | HAS_ARG, { .func_arg = show_sources },
3755  "list sources of the input device", "device" },
3756  { "sinks" , OPT_EXIT | HAS_ARG, { .func_arg = show_sinks },
3757  "list sinks of the output device", "device" },
3758  #endif
3759 
3760  { "f", HAS_ARG, {.func_arg = opt_format}, "force format", "format" },
3761  { "unit", OPT_BOOL, {&show_value_unit}, "show unit of the displayed values" },
3762  { "prefix", OPT_BOOL, {&use_value_prefix}, "use SI prefixes for the displayed values" },
3763  { "byte_binary_prefix", OPT_BOOL, {&use_byte_value_binary_prefix},
3764  "use binary prefixes for byte units" },
3765  { "sexagesimal", OPT_BOOL, {&use_value_sexagesimal_format},
3766  "use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" },
3767  { "pretty", 0, {.func_arg = opt_pretty},
3768  "prettify the format of displayed values, make it more human readable" },
3769  { "print_format", OPT_STRING | HAS_ARG, { &print_format },
3770  "set the output printing format (available formats are: default, compact, csv, flat, ini, json, xml)", "format" },
3771  { "of", OPT_STRING | HAS_ARG, { &print_format }, "alias for -print_format", "format" },
3772  { "select_streams", OPT_STRING | HAS_ARG, { &stream_specifier }, "select the specified streams", "stream_specifier" },
3773  { "sections", OPT_EXIT, {.func_arg = opt_sections}, "print sections structure and section information, and exit" },
3774  { "show_data", OPT_BOOL, { &do_show_data }, "show packets data" },
3775  { "show_data_hash", OPT_STRING | HAS_ARG, { &show_data_hash }, "show packets data hash" },
3776  { "show_error", 0, { .func_arg = &opt_show_error }, "show probing error" },
3777  { "show_format", 0, { .func_arg = &opt_show_format }, "show format/container info" },
3778  { "show_frames", 0, { .func_arg = &opt_show_frames }, "show frames info" },
3779  { "show_format_entry", HAS_ARG, {.func_arg = opt_show_format_entry},
3780  "show a particular entry from the format/container info", "entry" },
3781  { "show_entries", HAS_ARG, {.func_arg = opt_show_entries},
3782  "show a set of specified entries", "entry_list" },
3783  #if HAVE_THREADS
3784  { "show_log", OPT_INT|HAS_ARG, { &do_show_log }, "show log" },
3785  #endif
3786  { "show_packets", 0, { .func_arg = &opt_show_packets }, "show packets info" },
3787  { "show_programs", 0, { .func_arg = &opt_show_programs }, "show programs info" },
3788  { "show_streams", 0, { .func_arg = &opt_show_streams }, "show streams info" },
3789  { "show_chapters", 0, { .func_arg = &opt_show_chapters }, "show chapters info" },
3790  { "count_frames", OPT_BOOL, { &do_count_frames }, "count the number of frames per stream" },
3791  { "count_packets", OPT_BOOL, { &do_count_packets }, "count the number of packets per stream" },
3792  { "show_program_version", 0, { .func_arg = &opt_show_program_version }, "show ffprobe version" },
3793  { "show_library_versions", 0, { .func_arg = &opt_show_library_versions }, "show library versions" },
3794  { "show_versions", 0, { .func_arg = &opt_show_versions }, "show program and library versions" },
3795  { "show_pixel_formats", 0, { .func_arg = &opt_show_pixel_formats }, "show pixel format descriptions" },
3796  { "show_optional_fields", HAS_ARG, { .func_arg = &opt_show_optional_fields }, "show optional fields" },
3797  { "show_private_data", OPT_BOOL, { &show_private_data }, "show private data" },
3798  { "private", OPT_BOOL, { &show_private_data }, "same as show_private_data" },
3799  { "bitexact", OPT_BOOL, {&do_bitexact}, "force bitexact output" },
3800  { "read_intervals", HAS_ARG, {.func_arg = opt_read_intervals}, "set read intervals", "read_intervals" },
3801  { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default}, "generic catch all option", "" },
3802  { "i", HAS_ARG, {.func_arg = opt_input_file_i}, "read specified file", "input_file"},
3803  { "print_filename", HAS_ARG, {.func_arg = opt_print_filename}, "override the printed input filename", "print_file"},
3804  { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
3805  "read and decode the streams to fill missing information with heuristics" },
3806  { NULL, },
3807  };
3808 
3809  const Writer *w;
3810  WriterContext *wctx;
3811  char *buf;
3812  char *w_name = NULL, *w_args = NULL;
3813  int ret, i;
3814 
3815  int savedCode = setjmp(ex_buf__);
3816  if (savedCode == 0) {
3817 
3819 
3820  init_dynload();
3821 
3822  #if HAVE_THREADS
3823  ret = pthread_mutex_init(&log_mutex, NULL);
3824  if (ret != 0) {
3825  goto end;
3826  }
3827  #endif
3828  av_log_set_flags(AV_LOG_SKIP_REPEATED);
3830 
3831  ffprobe_options = options;
3832  parse_loglevel(argc, argv, options);
3833  avformat_network_init();
3834  #if CONFIG_AVDEVICE
3835  avdevice_register_all();
3836  #endif
3837 
3838  show_banner(argc, argv, options);
3839  parse_options(NULL, argc, argv, options, opt_input_file);
3840 
3841  if (do_show_log)
3842  av_log_set_callback(log_callback);
3843 
3844  /* mark things to show, based on -show_entries */
3845  SET_DO_SHOW(CHAPTERS, chapters);
3846  SET_DO_SHOW(ERROR, error);
3847  SET_DO_SHOW(FORMAT, format);
3848  SET_DO_SHOW(FRAMES, frames);
3849  SET_DO_SHOW(LIBRARY_VERSIONS, library_versions);
3850  SET_DO_SHOW(PACKETS, packets);
3851  SET_DO_SHOW(PIXEL_FORMATS, pixel_formats);
3852  SET_DO_SHOW(PIXEL_FORMAT_FLAGS, pixel_format_flags);
3853  SET_DO_SHOW(PIXEL_FORMAT_COMPONENTS, pixel_format_components);
3854  SET_DO_SHOW(PROGRAM_VERSION, program_version);
3855  SET_DO_SHOW(PROGRAMS, programs);
3856  SET_DO_SHOW(STREAMS, streams);
3857  SET_DO_SHOW(STREAM_DISPOSITION, stream_disposition);
3858  SET_DO_SHOW(PROGRAM_STREAM_DISPOSITION, stream_disposition);
3859 
3860  SET_DO_SHOW(CHAPTER_TAGS, chapter_tags);
3861  SET_DO_SHOW(FORMAT_TAGS, format_tags);
3862  SET_DO_SHOW(FRAME_TAGS, frame_tags);
3863  SET_DO_SHOW(PROGRAM_TAGS, program_tags);
3864  SET_DO_SHOW(STREAM_TAGS, stream_tags);
3865  SET_DO_SHOW(PROGRAM_STREAM_TAGS, stream_tags);
3866  SET_DO_SHOW(PACKET_TAGS, packet_tags);
3867 
3869  av_log(NULL, AV_LOG_ERROR,
3870  "-bitexact and -show_program_version or -show_library_versions "
3871  "options are incompatible\n");
3872  ret = AVERROR(EINVAL);
3873  goto end;
3874  }
3875 
3877 
3878  if (!print_format)
3879  print_format = av_strdup("default");
3880  if (!print_format) {
3881  ret = AVERROR(ENOMEM);
3882  goto end;
3883  }
3884  w_name = av_strtok(print_format, "=", &buf);
3885  if (!w_name) {
3886  av_log(NULL, AV_LOG_ERROR,
3887  "No name specified for the output format\n");
3888  ret = AVERROR(EINVAL);
3889  goto end;
3890  }
3891  w_args = buf;
3892 
3893  if (show_data_hash) {
3894  if ((ret = av_hash_alloc(&hash, show_data_hash)) < 0) {
3895  if (ret == AVERROR(EINVAL)) {
3896  const char *n;
3897  av_log(NULL, AV_LOG_ERROR,
3898  "Unknown hash algorithm '%s'\nKnown algorithms:",
3899  show_data_hash);
3900  for (i = 0; (n = av_hash_names(i)); i++)
3901  av_log(NULL, AV_LOG_ERROR, " %s", n);
3902  av_log(NULL, AV_LOG_ERROR, "\n");
3903  }
3904  goto end;
3905  }
3906  }
3907 
3908  w = writer_get_by_name(w_name);
3909  if (!w) {
3910  av_log(NULL, AV_LOG_ERROR, "Unknown output format with name '%s'\n", w_name);
3911  ret = AVERROR(EINVAL);
3912  goto end;
3913  }
3914 
3915  if ((ret = writer_open(&wctx, w, w_args,
3916  sections, FF_ARRAY_ELEMS(sections))) >= 0) {
3917  if (w == &xml_writer)
3918  wctx->string_validation_utf8_flags |= AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES;
3919 
3921 
3928 
3929  if (!input_filename &&
3932  show_usage();
3933  av_log(NULL, AV_LOG_ERROR, "You have to specify one input file.\n");
3934  av_log(NULL, AV_LOG_ERROR, "Use -h to get full help or, even better, run 'man %s'.\n", program_name);
3935  ret = AVERROR(EINVAL);
3936  } else if (input_filename) {
3938  if (ret < 0 && do_show_error)
3939  show_error(wctx, ret);
3940  }
3941 
3943  writer_close(&wctx);
3944  }
3945 
3946  main_ffprobe_return_code = ret < 0;
3947 
3948  } else {
3950  }
3951 
3952 end:
3953  av_freep(&print_format);
3954  av_freep(&read_intervals);
3955  av_hash_freep(&hash);
3956 
3957  uninit_opts();
3958  for (i = 0; i < FF_ARRAY_ELEMS(sections); i++)
3959  av_dict_free(&(sections[i].entries_to_show));
3960 
3961  avformat_network_deinit();
3962 
3963  return main_ffprobe_return_code;
3964 }
xml_print_str
static void xml_print_str(WriterContext *wctx, const char *key, const char *value)
Definition: fftools_ffprobe.c:1743
SECTION_ID_PROGRAM_TAGS
@ SECTION_ID_PROGRAM_TAGS
Definition: fftools_ffprobe.c:201
show_private_data
__thread int show_private_data
Definition: fftools_ffprobe.c:124
ffprobe_show_pixel_formats
static void ffprobe_show_pixel_formats(WriterContext *w)
Definition: fftools_ffprobe.c:3230
json_print_item_str
static void json_print_item_str(WriterContext *wctx, const char *key, const char *value)
Definition: fftools_ffprobe.c:1584
probe_file
static int probe_file(WriterContext *wctx, const char *filename, const char *print_filename)
Definition: fftools_ffprobe.c:3093
JSON_INDENT
#define JSON_INDENT()
Definition: fftools_ffprobe.c:1522
bin_str
const char * bin_str
Definition: fftools_ffprobe.c:279
index
fg index
Definition: fftools_ffmpeg_filter.c:177
print_primaries
static void print_primaries(WriterContext *w, enum AVColorPrimaries color_primaries)
Definition: fftools_ffprobe.c:2077
SECTION_ID_FRAME_SIDE_DATA_TIMECODE
@ SECTION_ID_FRAME_SIDE_DATA_TIMECODE
Definition: fftools_ffprobe.c:180
writer_print_integer
static void writer_print_integer(WriterContext *wctx, const char *key, long long int val)
Definition: fftools_ffprobe.c:685
clear_log
static void clear_log(int need_lock)
Definition: fftools_ffprobe.c:2108
validate_string
static int validate_string(WriterContext *wctx, char **dstp, const char *src)
Definition: fftools_ffprobe.c:696
opt_show_versions
static int opt_show_versions(void *optctx, const char *opt, const char *arg)
Definition: fftools_ffprobe.c:3610
close_input_file
static void close_input_file(InputFile *ifile)
Definition: fftools_ffprobe.c:3079
show_decoders
int show_decoders(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1691
json_print_str
static void json_print_str(WriterContext *wctx, const char *key, const char *value)
Definition: fftools_ffprobe.c:1596
log_buffer
__thread LogBuffer * log_buffer
Definition: fftools_ffprobe.c:312
print_section_footer
#define print_section_footer(s)
Definition: fftools_ffprobe.c:1828
Writer::uninit
void(* uninit)(WriterContext *wctx)
Definition: fftools_ffprobe.c:453
CompactContext::terminate_line
int terminate_line[SECTION_MAX_NB_LEVELS]
Definition: fftools_ffprobe.c:1096
PRINT_STRING_VALIDATE
#define PRINT_STRING_VALIDATE
Definition: fftools_ffprobe.c:752
print_int
#define print_int(k, v)
Definition: fftools_ffprobe.c:1811
do_count_packets
__thread int do_count_packets
Definition: fftools_ffprobe.c:94
LogBuffer
struct LogBuffer LogBuffer
flat_options
static const AVOption flat_options[]
Definition: fftools_ffprobe.c:1256
default_print_section_footer
static void default_print_section_footer(WriterContext *wctx)
Definition: fftools_ffprobe.c:993
show_optional_fields
__thread int show_optional_fields
Definition: fftools_ffprobe.c:129
print_section_header
#define print_section_header(s)
Definition: fftools_ffprobe.c:1827
FlatContext::sep
char sep
Definition: fftools_ffprobe.c:1249
ex_buf__
__thread jmp_buf ex_buf__
Definition: ffmpegkit_exception.cpp:23
DefaultContext
Definition: fftools_ffprobe.c:938
writer_options
static const AVOption writer_options[]
Definition: fftools_ffprobe.c:501
do_show_pixel_format_flags
__thread int do_show_pixel_format_flags
Definition: fftools_ffprobe.c:109
ini_print_str
static void ini_print_str(WriterContext *wctx, const char *key, const char *value)
Definition: fftools_ffprobe.c:1446
ini_writer
static const Writer ini_writer
Definition: fftools_ffprobe.c:1462
OPT_EXIT
#define OPT_EXIT
Definition: fftools_cmdutils.h:203
if
if(!fg) exit_program(1)
SECTION_ID_PIXEL_FORMAT
@ SECTION_ID_PIXEL_FORMAT
Definition: fftools_ffprobe.c:191
SECTION_ID_PACKET
@ SECTION_ID_PACKET
Definition: fftools_ffprobe.c:185
filter_codec_opts
AVDictionary * filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id, AVFormatContext *s, AVStream *st, const AVCodec *codec)
Definition: fftools_cmdutils.c:2156
writer_print_integers
static void writer_print_integers(WriterContext *wctx, const char *name, uint8_t *data, int size, const char *format, int columns, int bytes, int offset_add)
Definition: fftools_ffprobe.c:870
CompactContext::nested_section
int nested_section[SECTION_MAX_NB_LEVELS]
Definition: fftools_ffprobe.c:1094
MAX_REGISTERED_WRITERS_NB
#define MAX_REGISTERED_WRITERS_NB
Definition: fftools_ffprobe.c:896
SECTION_FLAG_HAS_VARIABLE_FIELDS
#define SECTION_FLAG_HAS_VARIABLE_FIELDS
Definition: fftools_ffprobe.c:156
program_name
__thread char * program_name
Definition: fftools_cmdutils.c:97
SECTION_ID_FRAME_SIDE_DATA
@ SECTION_ID_FRAME_SIDE_DATA
Definition: fftools_ffprobe.c:178
read_interval_packets
static int read_interval_packets(WriterContext *w, InputFile *ifile, const ReadInterval *interval, int64_t *cur_ts)
Definition: fftools_ffprobe.c:2474
Writer::flags
int flags
a combination or WRITER_FLAG_*
Definition: fftools_ffprobe.c:460
LogBuffer::parent_category
AVClassCategory parent_category
Definition: fftools_ffprobe.c:309
codec_opts
__thread AVDictionary * codec_opts
Definition: fftools_cmdutils.c:102
DefaultContext::nokey
int nokey
Definition: fftools_ffprobe.c:940
do_show_format
__thread int do_show_format
Definition: fftools_ffprobe.c:99
ffprobe_show_program_version
static void ffprobe_show_program_version(WriterContext *w)
Definition: fftools_ffprobe.c:3181
writer_register_all
static void writer_register_all(void)
Definition: fftools_ffprobe.c:1793
WriterContext::name
char * name
name of this writer instance
Definition: fftools_ffprobe.c:468
writer_get_name
static const char * writer_get_name(void *p)
Definition: fftools_ffprobe.c:493
selected_streams
__thread int * selected_streams
Definition: fftools_ffprobe.c:298
OPT_INPUT
#define OPT_INPUT
Definition: fftools_cmdutils.h:210
WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS
#define WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS
Definition: fftools_ffprobe.c:437
do_show_stream_tags
__thread int do_show_stream_tags
Definition: fftools_ffprobe.c:117
INIContext
Definition: fftools_ffprobe.c:1370
writer_print_ts
static void writer_print_ts(WriterContext *wctx, const char *key, int64_t ts, int is_duration)
Definition: fftools_ffprobe.c:818
c_escape_str
static const char * c_escape_str(AVBPrint *dst, const char *src, const char sep, void *log_ctx)
Definition: fftools_ffprobe.c:1040
ini_escape_str
static char * ini_escape_str(AVBPrint *dst, const char *src)
Definition: fftools_ffprobe.c:1386
show_pix_fmts
int show_pix_fmts(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1791
LogBuffer::category
AVClassCategory category
Definition: fftools_ffprobe.c:307
DEFINE_OPT_SHOW_SECTION
#define DEFINE_OPT_SHOW_SECTION(section, target_section_id)
Definition: fftools_ffprobe.c:3617
WriterContext::writer
const Writer * writer
the Writer of which this is an instance
Definition: fftools_ffprobe.c:467
CompactContext::item_sep_str
char * item_sep_str
Definition: fftools_ffprobe.c:1088
SectionID
SectionID
Definition: fftools_ffprobe.c:166
ReadInterval::end
int64_t end
start, end in second/AV_TIME_BASE units
Definition: fftools_ffprobe.c:137
exit_program
void exit_program(int ret)
Definition: fftools_cmdutils.c:160
section::element_name
const char * element_name
name of the contained element, if provided
Definition: fftools_ffprobe.c:160
compact_print_section_footer
static void compact_print_section_footer(WriterContext *wctx)
Definition: fftools_ffprobe.c:1168
DefaultContext::nested_section
int nested_section[SECTION_MAX_NB_LEVELS]
Definition: fftools_ffprobe.c:942
InputFile::fmt_ctx
AVFormatContext * fmt_ctx
Definition: fftools_ffprobe.c:86
parse_options
void parse_options(void *optctx, int argc, char **argv, const OptionDef *options, void(*parse_arg_function)(void *, const char *))
Definition: fftools_cmdutils.c:409
do_show_chapter_tags
__thread int do_show_chapter_tags
Definition: fftools_ffprobe.c:113
writer_print_string
static int writer_print_string(WriterContext *wctx, const char *key, const char *val, int flags)
Definition: fftools_ffprobe.c:754
InputStream
Definition: fftools_ffmpeg.h:324
upcase_string
static char * upcase_string(char *dst, size_t dst_size, const char *src)
Definition: fftools_ffprobe.c:959
SECTION_ID_PROGRAM_STREAMS
@ SECTION_ID_PROGRAM_STREAMS
Definition: fftools_ffprobe.c:199
DEFINE_WRITER_CLASS
#define DEFINE_WRITER_CLASS(name)
Definition: fftools_ffprobe.c:925
show_encoders
int show_encoders(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1697
flat_print_section_header
static void flat_print_section_header(WriterContext *wctx)
Definition: fftools_ffprobe.c:1313
show_demuxers
int show_demuxers(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1411
section::id
int id
unique id identifying a section
Definition: fftools_ffprobe.c:151
LogBuffer
Definition: fftools_ffprobe.c:303
bin_val
double bin_val
Definition: fftools_ffprobe.c:277
JSONContext::indent_level
int indent_level
Definition: fftools_ffprobe.c:1476
CHECK_COMPLIANCE
#define CHECK_COMPLIANCE(opt, opt_name)
value_string
static char * value_string(char *buf, int buf_size, struct unit_value uv)
Definition: fftools_ffprobe.c:380
WriterContext::level
int level
current level, starting from 0
Definition: fftools_ffprobe.c:474
find_stream_info
__thread int find_stream_info
Definition: fftools_ffmpeg_opt.c:203
print_color_trc
static void print_color_trc(WriterContext *w, enum AVColorTransferCharacteristic color_trc)
Definition: fftools_ffprobe.c:2087
do_show_program_tags
__thread int do_show_program_tags
Definition: fftools_ffprobe.c:116
writer_print_rational
static void writer_print_rational(WriterContext *wctx, const char *key, AVRational q, char sep)
Definition: fftools_ffprobe.c:792
do_show_packets
__thread int do_show_packets
Definition: fftools_ffprobe.c:101
show_muxers
int show_muxers(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1406
section::unique_name
const char * unique_name
unique section name, in case the name is ambiguous
Definition: fftools_ffprobe.c:161
show_streams
static int show_streams(WriterContext *w, InputFile *ifile)
Definition: fftools_ffprobe.c:2822
ffprobe_options
__thread OptionDef * ffprobe_options
Definition: fftools_ffprobe.c:264
FlatContext::hierarchical
int hierarchical
Definition: fftools_ffprobe.c:1250
print_str_opt
#define print_str_opt(k, v)
Definition: fftools_ffprobe.c:1814
LogBuffer::context_name
char * context_name
Definition: fftools_ffprobe.c:304
StringValidation
StringValidation
Definition: fftools_ffprobe.c:440
XMLContext::within_tag
int within_tag
Definition: fftools_ffprobe.c:1642
show_help_options
void show_help_options(const OptionDef *options, const char *msg, int req_flags, int rej_flags, int alt_flags)
Definition: fftools_cmdutils.c:204
do_show_programs
__thread int do_show_programs
Definition: fftools_ffprobe.c:102
do_show_frame_tags
__thread int do_show_frame_tags
Definition: fftools_ffprobe.c:115
print_chroma_location
static void print_chroma_location(WriterContext *w, enum AVChromaLocation chroma_location)
Definition: fftools_ffprobe.c:2097
main_ffprobe_return_code
__thread volatile int main_ffprobe_return_code
Definition: fftools_ffprobe.c:273
show_value_unit
__thread int show_value_unit
Definition: fftools_ffprobe.c:120
InputFile
struct InputFile InputFile
do_count_frames
__thread int do_count_frames
Definition: fftools_ffprobe.c:93
compact_print_int
static void compact_print_int(WriterContext *wctx, const char *key, long long int value)
Definition: fftools_ffprobe.c:1191
flat_writer
static const Writer flat_writer
Definition: fftools_ffprobe.c:1357
show_help_default_ffprobe
void show_help_default_ffprobe(const char *opt, const char *arg)
Definition: fftools_ffprobe.c:3422
none_escape_str
static const char * none_escape_str(AVBPrint *dst, const char *src, const char sep, void *log_ctx)
Definition: fftools_ffprobe.c:1081
ReadInterval::start_is_offset
int start_is_offset
Definition: fftools_ffprobe.c:139
SECTION_FLAG_IS_WRAPPER
#define SECTION_FLAG_IS_WRAPPER
the section only contains other sections, but has no data at its own level
Definition: fftools_ffprobe.c:154
SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST
@ SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST
Definition: fftools_ffprobe.c:179
SECTION_ID_CHAPTER_TAGS
@ SECTION_ID_CHAPTER_TAGS
Definition: fftools_ffprobe.c:169
log_read_interval
static void log_read_interval(const ReadInterval *interval, void *log_ctx, int log_level)
Definition: fftools_ffprobe.c:2450
REALLOCZ_ARRAY_STREAM
#define REALLOCZ_ARRAY_STREAM(ptr, cur_n, new_n)
Definition: fftools_ffprobe.c:1830
xml_print_int
static void xml_print_int(WriterContext *wctx, const char *key, long long int value)
Definition: fftools_ffprobe.c:1774
do_show_format_tags
__thread int do_show_format_tags
Definition: fftools_ffprobe.c:114
XMLContext::indent_level
int indent_level
Definition: fftools_ffprobe.c:1643
print_color_range
static void print_color_range(WriterContext *w, enum AVColorRange color_range)
Definition: fftools_ffprobe.c:2057
show_help
int show_help(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:2042
parse_number_or_die
double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
Definition: fftools_cmdutils.c:171
OPT_VIDEO
#define OPT_VIDEO
Definition: fftools_cmdutils.h:197
writer_class
static const AVClass writer_class
Definition: fftools_ffprobe.c:522
unit_value::val
union unit_value::@4 val
next_registered_writer_idx
__thread int next_registered_writer_idx
Definition: fftools_ffprobe.c:900
xml_init
static av_cold int xml_init(WriterContext *wctx)
Definition: fftools_ffprobe.c:1661
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: fftools_ffprobe.c:72
SECTION_ID_FRAME_LOGS
@ SECTION_ID_FRAME_LOGS
Definition: fftools_ffprobe.c:182
sections
static struct section sections[]
Definition: fftools_ffprobe.c:214
DefaultContext::noprint_wrappers
int noprint_wrappers
Definition: fftools_ffprobe.c:941
use_value_prefix
__thread int use_value_prefix
Definition: fftools_ffprobe.c:121
flat_escape_value_str
static const char * flat_escape_value_str(AVBPrint *dst, const char *src)
Definition: fftools_ffprobe.c:1295
SECTION_ID_FORMAT
@ SECTION_ID_FORMAT
Definition: fftools_ffprobe.c:172
SECTION_ID_PROGRAM
@ SECTION_ID_PROGRAM
Definition: fftools_ffprobe.c:198
match_section
static int match_section(const char *section_name, int show_all_entries, AVDictionary *entries)
Definition: fftools_ffprobe.c:3312
OPT_INT
#define OPT_INT
Definition: fftools_cmdutils.h:199
opt_default
int opt_default(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:575
opt_read_intervals
static int opt_read_intervals(void *optctx, const char *opt, const char *arg)
Definition: fftools_ffprobe.c:3567
CompactContext::print_section
int print_section
Definition: fftools_ffprobe.c:1091
show_filters
int show_filters(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1730
process_frame
static av_always_inline int process_frame(WriterContext *w, InputFile *ifile, AVFrame *frame, AVPacket *pkt, int *packet_new)
Definition: fftools_ffprobe.c:2384
writer_print_section_header
static void writer_print_section_header(WriterContext *wctx, int section_id)
Definition: fftools_ffprobe.c:644
FlatContext
struct FlatContext FlatContext
xml_print_section_header
static void xml_print_section_header(WriterContext *wctx)
Definition: fftools_ffprobe.c:1684
print_fmt
#define print_fmt(k, f,...)
Definition: fftools_ffprobe.c:1805
print_str_validate
#define print_str_validate(k, v)
Definition: fftools_ffprobe.c:1815
compact_init
static av_cold int compact_init(WriterContext *wctx)
Definition: fftools_ffprobe.c:1116
opt_input_file_i
static int opt_input_file_i(void *optctx, const char *opt, const char *arg)
Definition: fftools_ffprobe.c:3410
show_version
int show_version(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1242
use_byte_value_binary_prefix
__thread int use_byte_value_binary_prefix
Definition: fftools_ffprobe.c:122
writer_close
static void writer_close(WriterContext **wctx)
Definition: fftools_ffprobe.c:530
SHOW_OPTIONAL_FIELDS_AUTO
#define SHOW_OPTIONAL_FIELDS_AUTO
Definition: fftools_ffprobe.c:126
parse_loglevel
void parse_loglevel(int argc, char **argv, const OptionDef *options)
Definition: fftools_cmdutils.c:536
default_print_int
static void default_print_int(WriterContext *wctx, const char *key, long long int value)
Definition: fftools_ffprobe.c:1015
DefaultContext
struct DefaultContext DefaultContext
bprint_bytes
static void bprint_bytes(AVBPrint *bp, const uint8_t *ubuf, size_t ubuf_size)
Definition: fftools_ffprobe.c:548
show_program
static int show_program(WriterContext *w, InputFile *ifile, AVProgram *program)
Definition: fftools_ffprobe.c:2839
dec_val
double dec_val
Definition: fftools_ffprobe.c:278
show_programs
static int show_programs(WriterContext *w, InputFile *ifile)
Definition: fftools_ffprobe.c:2874
HAS_ARG
#define HAS_ARG
Definition: fftools_cmdutils.h:193
flat_init
static av_cold int flat_init(WriterContext *wctx)
Definition: fftools_ffprobe.c:1266
json_writer
static const Writer json_writer
Definition: fftools_ffprobe.c:1626
mark_section_show_entries
static void mark_section_show_entries(SectionID section_id, int show_all_entries, AVDictionary *entries)
Definition: fftools_ffprobe.c:3297
print_q
#define print_q(k, v, s)
Definition: fftools_ffprobe.c:1812
show_data_hash
__thread char * show_data_hash
Definition: fftools_ffprobe.c:133
ffmpegkit_exception.h
print_duration_ts
#define print_duration_ts(k, v)
Definition: fftools_ffprobe.c:1819
ReadInterval::has_end
int has_end
Definition: fftools_ffprobe.c:138
SECTION_MAX_NB_CHILDREN
#define SECTION_MAX_NB_CHILDREN
Definition: fftools_ffprobe.c:148
section::show_all_entries
int show_all_entries
Definition: fftools_ffprobe.c:163
SHOW_OPTIONAL_FIELDS_ALWAYS
#define SHOW_OPTIONAL_FIELDS_ALWAYS
Definition: fftools_ffprobe.c:128
Writer::init
int(* init)(WriterContext *wctx)
Definition: fftools_ffprobe.c:452
opt_format
static int opt_format(void *optctx, const char *opt, const char *arg)
Definition: fftools_ffprobe.c:3287
PRINT_STRING_OPT
#define PRINT_STRING_OPT
Definition: fftools_ffprobe.c:751
SECTION_ID_PIXEL_FORMAT_FLAGS
@ SECTION_ID_PIXEL_FORMAT_FLAGS
Definition: fftools_ffprobe.c:192
ReadInterval::end_is_offset
int end_is_offset
Definition: fftools_ffprobe.c:139
InputFile
Definition: fftools_ffmpeg.h:425
default_print_section_header
static void default_print_section_header(WriterContext *wctx)
Definition: fftools_ffprobe.c:968
log_callback
static void log_callback(void *ptr, int level, const char *fmt, va_list vl)
Definition: fftools_ffprobe.c:315
SECTION_ID_STREAM_SIDE_DATA
@ SECTION_ID_STREAM_SIDE_DATA
Definition: fftools_ffprobe.c:210
OPT_STRING
#define OPT_STRING
Definition: fftools_cmdutils.h:196
SECTION_ID_PACKET_SIDE_DATA
@ SECTION_ID_PACKET_SIDE_DATA
Definition: fftools_ffprobe.c:190
InputStream
struct InputStream InputStream
do_show_packet_tags
__thread int do_show_packet_tags
Definition: fftools_ffprobe.c:118
flat_escape_key_str
static const char * flat_escape_key_str(AVBPrint *dst, const char *src, const char sep)
Definition: fftools_ffprobe.c:1280
section::name
const char * name
Definition: fftools_ffprobe.c:152
opt_show_entries
static int opt_show_entries(void *optctx, const char *opt, const char *arg)
Definition: fftools_ffprobe.c:3331
InputFile::streams
InputStream * streams
Definition: fftools_ffprobe.c:88
print_ts
#define print_ts(k, v)
Definition: fftools_ffprobe.c:1817
SECTION_ID_PROGRAM_STREAM_TAGS
@ SECTION_ID_PROGRAM_STREAM_TAGS
Definition: fftools_ffprobe.c:197
show_colors
int show_colors(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1777
opt_show_format_entry
static int opt_show_format_entry(void *optctx, const char *opt, const char *arg)
Definition: fftools_ffprobe.c:3381
default_print_str
static void default_print_str(WriterContext *wctx, const char *key, const char *value)
Definition: fftools_ffprobe.c:1006
section::children_ids
int children_ids[SECTION_MAX_NB_CHILDREN+1]
list of children section IDS, terminated by -1
Definition: fftools_ffprobe.c:159
Writer::print_rational
void(* print_rational)(WriterContext *wctx, AVRational *q, char *sep)
Definition: fftools_ffprobe.c:458
CompactContext
Definition: fftools_ffprobe.c:1086
show_bsfs
int show_bsfs(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1703
csv_escape_str
static const char * csv_escape_str(AVBPrint *dst, const char *src, const char sep, void *log_ctx)
Definition: fftools_ffprobe.c:1063
SECTION_ID_FRAME_SIDE_DATA_LIST
@ SECTION_ID_FRAME_SIDE_DATA_LIST
Definition: fftools_ffprobe.c:177
unit_bit_per_second_str
static const char unit_bit_per_second_str[]
Definition: fftools_ffprobe.c:293
SECTION_ID_FORMAT_TAGS
@ SECTION_ID_FORMAT_TAGS
Definition: fftools_ffprobe.c:173
show_tags
static int show_tags(WriterContext *w, AVDictionary *tags, int section_id)
Definition: fftools_ffprobe.c:1838
Writer::priv_class
const AVClass * priv_class
private class of the writer, if any
Definition: fftools_ffprobe.c:448
Writer
Definition: fftools_ffprobe.c:447
SHOW_LIB_VERSION
#define SHOW_LIB_VERSION(libname, LIBNAME)
Definition: fftools_ffprobe.c:3197
print_time
#define print_time(k, v, tb)
Definition: fftools_ffprobe.c:1816
print_duration_time
#define print_duration_time(k, v, tb)
Definition: fftools_ffprobe.c:1818
print_input_filename
const __thread char * print_input_filename
Definition: fftools_ffprobe.c:268
SECTION_ID_FRAMES
@ SECTION_ID_FRAMES
Definition: fftools_ffprobe.c:175
show_frame
static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, AVFormatContext *fmt_ctx)
Definition: fftools_ffprobe.c:2235
dec_str
const char * dec_str
Definition: fftools_ffprobe.c:280
SECTION_ID_PIXEL_FORMAT_COMPONENTS
@ SECTION_ID_PIXEL_FORMAT_COMPONENTS
Definition: fftools_ffprobe.c:194
SECTION_ID_ROOT
@ SECTION_ID_ROOT
Definition: fftools_ffprobe.c:204
SECTION_ID_ERROR
@ SECTION_ID_ERROR
Definition: fftools_ffprobe.c:171
JSONContext
struct JSONContext JSONContext
csv_writer
static const Writer csv_writer
Definition: fftools_ffprobe.c:1232
WRITER_STRING_VALIDATION_FAIL
@ WRITER_STRING_VALIDATION_FAIL
Definition: fftools_ffprobe.c:441
xml_print_section_footer
static void xml_print_section_footer(WriterContext *wctx)
Definition: fftools_ffprobe.c:1724
SECTION_ID_SUBTITLE
@ SECTION_ID_SUBTITLE
Definition: fftools_ffprobe.c:211
print_color_space
static void print_color_space(WriterContext *w, enum AVColorSpace color_space)
Definition: fftools_ffprobe.c:2067
program_birth_year
__thread int program_birth_year
Definition: fftools_cmdutils.c:98
SECTION_FLAG_IS_ARRAY
#define SECTION_FLAG_IS_ARRAY
the section contains an array of elements of the same type
Definition: fftools_ffprobe.c:155
WriterContext::string_validation_replacement
char * string_validation_replacement
Definition: fftools_ffprobe.c:489
uninit_opts
void uninit_opts(void)
Definition: fftools_cmdutils.c:115
hash
__thread struct AVHashContext * hash
Definition: fftools_ffprobe.c:271
SECTION_ID_PIXEL_FORMATS
@ SECTION_ID_PIXEL_FORMATS
Definition: fftools_ffprobe.c:195
ist
fg inputs[0] ist
Definition: fftools_ffmpeg_filter.c:191
show_error
static void show_error(WriterContext *w, int err)
Definition: fftools_ffprobe.c:2948
InputFile::nb_streams
int nb_streams
Definition: fftools_ffmpeg.h:441
format_opts
__thread AVDictionary * format_opts
Definition: fftools_cmdutils.c:102
json_escape_str
static const char * json_escape_str(AVBPrint *dst, const char *src, void *log_ctx)
Definition: fftools_ffprobe.c:1502
XMLContext::xsd_strict
int xsd_strict
Definition: fftools_ffprobe.c:1645
compact_print_section_header
static void compact_print_section_header(WriterContext *wctx)
Definition: fftools_ffprobe.c:1138
opt_loglevel
int opt_loglevel(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:919
do_show_chapters
__thread int do_show_chapters
Definition: fftools_ffprobe.c:97
show_sample_fmts
int show_sample_fmts(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1853
json_print_section_header
static void json_print_section_header(WriterContext *wctx)
Definition: fftools_ffprobe.c:1524
do_show_frames
__thread int do_show_frames
Definition: fftools_ffprobe.c:100
register_exit
void register_exit(void(*cb)(int ret))
Definition: fftools_cmdutils.c:155
ReadInterval::id
int id
identifier
Definition: fftools_ffprobe.c:136
Writer::print_section_footer
void(* print_section_footer)(WriterContext *wctx)
Definition: fftools_ffprobe.c:456
unit_second_str
static const char unit_second_str[]
Definition: fftools_ffprobe.c:290
show_help_children
void show_help_children(const AVClass *avClass, int flags)
Definition: fftools_cmdutils.c:233
WRITER_STRING_VALIDATION_NB
@ WRITER_STRING_VALIDATION_NB
Definition: fftools_ffprobe.c:444
print_error
void print_error(const char *filename, int err)
Definition: fftools_cmdutils.c:1134
writer_print_time
static void writer_print_time(WriterContext *wctx, const char *key, int64_t ts, const AVRational *time_base, int is_duration)
Definition: fftools_ffprobe.c:801
SECTION_ID_PROGRAM_STREAM
@ SECTION_ID_PROGRAM_STREAM
Definition: fftools_ffprobe.c:200
csv_options
static const AVOption csv_options[]
Definition: fftools_ffprobe.c:1218
SECTION_ID_PROGRAM_VERSION
@ SECTION_ID_PROGRAM_VERSION
Definition: fftools_ffprobe.c:202
Writer::name
const char * name
Definition: fftools_ffprobe.c:450
section
Definition: fftools_ffprobe.c:150
opt_sections
static int opt_sections(void *optctx, const char *opt, const char *arg)
Definition: fftools_ffprobe.c:3598
SECTION_ID_PACKETS_AND_FRAMES
@ SECTION_ID_PACKETS_AND_FRAMES
Definition: fftools_ffprobe.c:188
registered_writers
const __thread Writer * registered_writers[MAX_REGISTERED_WRITERS_NB+1]
Definition: fftools_ffprobe.c:898
do_show_log
__thread int do_show_log
Definition: fftools_ffprobe.c:111
show_banner
void show_banner(int argc, char **argv, const OptionDef *options)
Definition: fftools_cmdutils.c:1231
opt_cpucount
int opt_cpucount(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:893
WriterContext::priv
void * priv
private data for use by the filter
Definition: fftools_ffprobe.c:469
unit_value
Definition: fftools_ffprobe.c:375
InputStream::st
AVStream * st
Definition: fftools_ffmpeg.h:326
ini_print_section_header
static void ini_print_section_header(WriterContext *wctx)
Definition: fftools_ffprobe.c:1413
JSONContext
Definition: fftools_ffprobe.c:1474
ReadInterval::has_start
int has_start
Definition: fftools_ffprobe.c:138
WriterContext::nb_sections
int nb_sections
number of sections
Definition: fftools_ffprobe.c:472
parse_read_interval
static int parse_read_interval(const char *interval_spec, ReadInterval *interval)
Definition: fftools_ffprobe.c:3437
Writer::print_integer
void(* print_integer)(WriterContext *wctx, const char *, long long int)
Definition: fftools_ffprobe.c:457
InputStream::dec_ctx
AVCodecContext * dec_ctx
Definition: fftools_ffmpeg.h:333
LogBuffer::log_level
int log_level
Definition: fftools_ffprobe.c:305
WriterContext::sections
const struct section * sections
array containing all sections
Definition: fftools_ffprobe.c:471
si_prefixes
static const struct @3 si_prefixes[]
d
d
Definition: fftools_ffmpeg_filter.c:165
SECTION_ID_STREAM_TAGS
@ SECTION_ID_STREAM_TAGS
Definition: fftools_ffprobe.c:208
WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER
#define WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER
Definition: fftools_ffprobe.c:438
compact_writer
static const Writer compact_writer
Definition: fftools_ffprobe.c:1201
read_packets
static int read_packets(WriterContext *w, InputFile *ifile)
Definition: fftools_ffprobe.c:2582
stream_specifier
__thread char * stream_specifier
Definition: fftools_ffprobe.c:132
opt_cpuflags
int opt_cpuflags(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:881
section::entries_to_show
AVDictionary * entries_to_show
Definition: fftools_ffprobe.c:162
ReadInterval::duration_frames
int duration_frames
Definition: fftools_ffprobe.c:140
WRITER_STRING_VALIDATION_IGNORE
@ WRITER_STRING_VALIDATION_IGNORE
Definition: fftools_ffprobe.c:443
print_val
#define print_val(k, v, u)
Definition: fftools_ffprobe.c:1820
OFFSET
#define OFFSET(x)
Definition: fftools_ffprobe.c:1649
AV_LOG_STDERR
#define AV_LOG_STDERR
Definition: fftools_cmdutils.h:61
format
fg outputs[0] format
Definition: fftools_ffmpeg_filter.c:184
show_log
static int show_log(WriterContext *w, int section_ids, int section_id, int log_level)
Definition: fftools_ffprobe.c:2124
PRINT_PIX_FMT_FLAG
#define PRINT_PIX_FMT_FLAG(flagname, name)
Definition: fftools_ffprobe.c:3225
do_show_data
__thread int do_show_data
Definition: fftools_ffprobe.c:105
show_protocols
int show_protocols(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1715
Writer
struct Writer Writer
writer_register
static int writer_register(const Writer *writer)
Definition: fftools_ffprobe.c:902
do_show_program_version
__thread int do_show_program_version
Definition: fftools_ffprobe.c:106
XMLContext
Definition: fftools_ffprobe.c:1640
unit_value::unit
const char * unit
Definition: fftools_ffprobe.c:377
WriterContext::nb_section_packet_frame
unsigned int nb_section_packet_frame
nb_section_packet or nb_section_frame according if is_packets_and_frames
Definition: fftools_ffprobe.c:486
SECTION_ID_NONE
@ SECTION_ID_NONE
Definition: fftools_ffprobe.c:167
section::flags
int flags
For these sections the element_name field is mandatory.
Definition: fftools_ffprobe.c:158
int
int
Definition: fftools_ffmpeg_filter.c:165
SECTION_ID_PROGRAMS
@ SECTION_ID_PROGRAMS
Definition: fftools_ffprobe.c:203
show_codecs
int show_codecs(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1596
print_pkt_side_data
static void print_pkt_side_data(WriterContext *w, AVCodecParameters *par, const AVPacketSideData *side_data, int nb_side_data, SectionID id_data_list, SectionID id_data)
Definition: fftools_ffprobe.c:1955
CompactContext::nokey
int nokey
Definition: fftools_ffprobe.c:1090
SECTION_ID_CHAPTER
@ SECTION_ID_CHAPTER
Definition: fftools_ffprobe.c:168
ffprobe_execute
int ffprobe_execute(int argc, char **argv)
Definition: fftools_ffprobe.c:3717
XMLContext
struct XMLContext XMLContext
SECTION_ID_PACKETS
@ SECTION_ID_PACKETS
Definition: fftools_ffprobe.c:187
do_show_stream_disposition
__thread int do_show_stream_disposition
Definition: fftools_ffprobe.c:104
XML_INDENT
#define XML_INDENT()
Definition: fftools_ffprobe.c:1682
hide_banner
__thread int hide_banner
Definition: fftools_cmdutils.c:106
default_writer
static const Writer default_writer
Definition: fftools_ffprobe.c:1024
writer_get_by_name
static const Writer * writer_get_by_name(const char *name)
Definition: fftools_ffprobe.c:911
log_buffer_size
__thread int log_buffer_size
Definition: fftools_ffprobe.c:313
FlatContext
Definition: fftools_ffprobe.c:1246
WriterContext
Definition: fftools_ffprobe.c:465
read_intervals
__thread ReadInterval * read_intervals
Definition: fftools_ffprobe.c:143
OptionDef
Definition: fftools_cmdutils.h:190
opt_report
int opt_report(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1102
unit_byte_str
static const char unit_byte_str[]
Definition: fftools_ffprobe.c:292
opt_input_file
static void opt_input_file(void *optctx, const char *arg)
Definition: fftools_ffprobe.c:3397
show_chapters
static int show_chapters(WriterContext *w, InputFile *ifile)
Definition: fftools_ffprobe.c:2892
nb_streams_frames
__thread uint64_t * nb_streams_frames
Definition: fftools_ffprobe.c:297
opt_pretty
static int opt_pretty(void *optctx, const char *opt, const char *arg)
Definition: fftools_ffprobe.c:3572
ini_options
static const AVOption ini_options[]
Definition: fftools_ffprobe.c:1378
SECTION_ID_STREAM_SIDE_DATA_LIST
@ SECTION_ID_STREAM_SIDE_DATA_LIST
Definition: fftools_ffprobe.c:209
WriterContext::nb_section_frame
unsigned int nb_section_frame
number of the frame section in case we are in "packets_and_frames" section
Definition: fftools_ffprobe.c:485
JSONContext::compact
int compact
Definition: fftools_ffprobe.c:1477
WriterContext::string_validation
int string_validation
Definition: fftools_ffprobe.c:488
do_show_error
__thread int do_show_error
Definition: fftools_ffprobe.c:98
show_usage
static void show_usage(void)
Definition: fftools_ffprobe.c:3174
ini_print_int
static void ini_print_int(WriterContext *wctx, const char *key, long long int value)
Definition: fftools_ffprobe.c:1457
WriterContext::nb_section_packet
unsigned int nb_section_packet
number of the packet section in case we are in "packets_and_frames" section
Definition: fftools_ffprobe.c:484
input_filename
const __thread char * input_filename
Definition: fftools_ffprobe.c:267
ReadInterval::start
int64_t start
Definition: fftools_ffprobe.c:137
SHOW_OPTIONAL_FIELDS_NEVER
#define SHOW_OPTIONAL_FIELDS_NEVER
Definition: fftools_ffprobe.c:127
json_print_int
static void json_print_int(WriterContext *wctx, const char *key, long long int value)
Definition: fftools_ffprobe.c:1609
writer_print_data
static void writer_print_data(WriterContext *wctx, const char *name, uint8_t *data, int size)
Definition: fftools_ffprobe.c:827
SECTION_ID_FRAME_LOG
@ SECTION_ID_FRAME_LOG
Definition: fftools_ffprobe.c:181
check_section_show_entries
static int check_section_show_entries(int section_id)
Definition: fftools_ffprobe.c:3635
show_devices
int show_devices(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1416
show_subtitle
static void show_subtitle(WriterContext *w, AVSubtitle *sub, AVStream *stream, AVFormatContext *fmt_ctx)
Definition: fftools_ffprobe.c:2212
nb_streams
__thread int nb_streams
Definition: fftools_ffprobe.c:295
compact_options
static const AVOption compact_options[]
Definition: fftools_ffprobe.c:1102
SECTION_ID_FRAME
@ SECTION_ID_FRAME
Definition: fftools_ffprobe.c:174
INIContext::hierarchical
int hierarchical
Definition: fftools_ffprobe.c:1372
Writer::print_string
void(* print_string)(WriterContext *wctx, const char *, const char *)
Definition: fftools_ffprobe.c:459
opt_print_filename
static int opt_print_filename(void *optctx, const char *opt, const char *arg)
Definition: fftools_ffprobe.c:3416
ffprobe_var_cleanup
void ffprobe_var_cleanup()
Definition: fftools_ffprobe.c:3652
do_show_streams
__thread int do_show_streams
Definition: fftools_ffprobe.c:103
ffprobe_cleanup
static void ffprobe_cleanup(int ret)
Definition: fftools_ffprobe.c:364
OPT_AUDIO
#define OPT_AUDIO
Definition: fftools_cmdutils.h:198
WriterContext::section
const struct section * section[SECTION_MAX_NB_LEVELS]
Definition: fftools_ffprobe.c:480
Writer::print_section_header
void(* print_section_header)(WriterContext *wctx)
Definition: fftools_ffprobe.c:455
print_dynamic_hdr10_plus
static void print_dynamic_hdr10_plus(WriterContext *w, const AVDynamicHDRPlus *metadata)
Definition: fftools_ffprobe.c:1856
compact_print_str
static void compact_print_str(WriterContext *wctx, const char *key, const char *value)
Definition: fftools_ffprobe.c:1178
OPT_BOOL
#define OPT_BOOL
Definition: fftools_cmdutils.h:194
ReadInterval
struct ReadInterval ReadInterval
WriterContext::nb_item
unsigned int nb_item[SECTION_MAX_NB_LEVELS]
Definition: fftools_ffprobe.c:477
writer_print_data_hash
static void writer_print_data_hash(WriterContext *wctx, const char *name, uint8_t *data, int size)
Definition: fftools_ffprobe.c:855
fftools_cmdutils.h
writer_print_section_footer
static void writer_print_section_footer(WriterContext *wctx)
Definition: fftools_ffprobe.c:668
json_options
static const AVOption json_options[]
Definition: fftools_ffprobe.c:1484
use_value_sexagesimal_format
__thread int use_value_sexagesimal_format
Definition: fftools_ffprobe.c:123
SECTION_ID_PIXEL_FORMAT_COMPONENT
@ SECTION_ID_PIXEL_FORMAT_COMPONENT
Definition: fftools_ffprobe.c:193
CHECK_END
#define CHECK_END
flat_print_str
static void flat_print_str(WriterContext *wctx, const char *key, const char *value)
Definition: fftools_ffprobe.c:1344
do_read_frames
__thread int do_read_frames
Definition: fftools_ffprobe.c:95
flat_print_int
static void flat_print_int(WriterContext *wctx, const char *key, long long int value)
Definition: fftools_ffprobe.c:1339
SECTION_ID_STREAMS
@ SECTION_ID_STREAMS
Definition: fftools_ffprobe.c:207
show_format
static int show_format(WriterContext *w, InputFile *ifile)
Definition: fftools_ffprobe.c:2917
XMLContext::fully_qualified
int fully_qualified
Definition: fftools_ffprobe.c:1644
unit_hertz_str
static const char unit_hertz_str[]
Definition: fftools_ffprobe.c:291
writer_child_next
static void * writer_child_next(void *obj, void *prev)
Definition: fftools_ffprobe.c:514
show_stream
static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx, InputStream *ist, int in_program)
Definition: fftools_ffprobe.c:2602
setup_find_stream_info_opts
AVDictionary ** setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts)
Definition: fftools_cmdutils.c:2214
CompactContext::has_nested_elems
int has_nested_elems[SECTION_MAX_NB_LEVELS]
Definition: fftools_ffprobe.c:1095
WriterContext::section_pbuf
AVBPrint section_pbuf[SECTION_MAX_NB_LEVELS]
Definition: fftools_ffprobe.c:481
SECTION_ID_LIBRARY_VERSIONS
@ SECTION_ID_LIBRARY_VERSIONS
Definition: fftools_ffprobe.c:184
Writer::priv_size
int priv_size
private size for the writer context
Definition: fftools_ffprobe.c:449
JSONContext::item_sep
const char * item_sep
Definition: fftools_ffprobe.c:1478
SECTION_ID_FRAME_TAGS
@ SECTION_ID_FRAME_TAGS
Definition: fftools_ffprobe.c:176
SECTION_MAX_NB_LEVELS
#define SECTION_MAX_NB_LEVELS
Definition: fftools_ffprobe.c:463
unit_value::i
long long int i
Definition: fftools_ffprobe.c:376
SET_DO_SHOW
#define SET_DO_SHOW(id, varname)
Definition: fftools_ffprobe.c:3647
SECTION_ID_CHAPTERS
@ SECTION_ID_CHAPTERS
Definition: fftools_ffprobe.c:170
show_layouts
int show_layouts(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1824
print_section
static void print_section(SectionID id, int level)
Definition: fftools_ffprobe.c:3581
xml_options
static const AVOption xml_options[]
Definition: fftools_ffprobe.c:1651
ffprobe_show_library_versions
static void ffprobe_show_library_versions(WriterContext *w)
Definition: fftools_ffprobe.c:3212
parse_read_intervals
static int parse_read_intervals(const char *intervals_spec)
Definition: fftools_ffprobe.c:3519
SECTION_ID_PACKET_TAGS
@ SECTION_ID_PACKET_TAGS
Definition: fftools_ffprobe.c:186
show_license
int show_license(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1257
SECTION_ID_STREAM
@ SECTION_ID_STREAM
Definition: fftools_ffprobe.c:205
WriterContext::string_validation_utf8_flags
unsigned int string_validation_utf8_flags
Definition: fftools_ffprobe.c:490
show_buildconf
int show_buildconf(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1250
show_formats
int show_formats(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1401
INIContext
struct INIContext INIContext
writer_open
static int writer_open(WriterContext **wctx, const Writer *writer, const char *args, const struct section *sections, int nb_sections)
Definition: fftools_ffprobe.c:557
JSONContext::item_start_end
const char * item_start_end
Definition: fftools_ffprobe.c:1478
SECTION_ID_PACKET_SIDE_DATA_LIST
@ SECTION_ID_PACKET_SIDE_DATA_LIST
Definition: fftools_ffprobe.c:189
CompactContext
struct CompactContext CompactContext
ReadInterval
Definition: fftools_ffprobe.c:135
open_input_file
static int open_input_file(InputFile *ifile, const char *filename, const char *print_filename)
Definition: fftools_ffprobe.c:2962
do_show_library_versions
__thread int do_show_library_versions
Definition: fftools_ffprobe.c:107
xml_writer
static Writer xml_writer
Definition: fftools_ffprobe.c:1781
CompactContext::escape_str
const char *(* escape_str)(AVBPrint *dst, const char *src, const char sep, void *log_ctx)
Definition: fftools_ffprobe.c:1093
PRINT_DISPOSITION
#define PRINT_DISPOSITION(flagname, name)
read_intervals_nb
__thread int read_intervals_nb
Definition: fftools_ffprobe.c:144
LogBuffer::parent_name
char * parent_name
Definition: fftools_ffprobe.c:308
opt_max_alloc
int opt_max_alloc(void *optctx, const char *opt, const char *arg)
Definition: fftools_cmdutils.c:1107
CompactContext::escape_mode_str
char * escape_mode_str
Definition: fftools_ffprobe.c:1092
do_show_pixel_formats
__thread int do_show_pixel_formats
Definition: fftools_ffprobe.c:108
print_str
#define print_str(k, v)
Definition: fftools_ffprobe.c:1813
iformat
const __thread AVInputFormat * iformat
Definition: fftools_ffprobe.c:269
LogBuffer::log_message
char * log_message
Definition: fftools_ffprobe.c:306
SECTION_ID_LIBRARY_VERSION
@ SECTION_ID_LIBRARY_VERSION
Definition: fftools_ffprobe.c:183
do_bitexact
__thread int do_bitexact
Definition: fftools_ffprobe.c:92
init_dynload
void init_dynload(void)
Definition: fftools_cmdutils.c:144
unit_value::d
double d
Definition: fftools_ffprobe.c:376
CompactContext::item_sep
char item_sep
Definition: fftools_ffprobe.c:1089
WRITER_STRING_VALIDATION_REPLACE
@ WRITER_STRING_VALIDATION_REPLACE
Definition: fftools_ffprobe.c:442
print_format
__thread char * print_format
Definition: fftools_ffprobe.c:131
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: fftools_ffprobe.c:76
nb_streams_packets
__thread uint64_t * nb_streams_packets
Definition: fftools_ffprobe.c:296
SECTION_ID_PROGRAM_STREAM_DISPOSITION
@ SECTION_ID_PROGRAM_STREAM_DISPOSITION
Definition: fftools_ffprobe.c:196
OPT_EXPERT
#define OPT_EXPERT
Definition: fftools_cmdutils.h:195
do_read_packets
__thread int do_read_packets
Definition: fftools_ffprobe.c:96
longjmp_value
__thread volatile int longjmp_value
Definition: fftools_cmdutils.c:107
show_packet
static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int packet_idx)
Definition: fftools_ffprobe.c:2159
json_init
static av_cold int json_init(WriterContext *wctx)
Definition: fftools_ffprobe.c:1492
FlatContext::sep_str
const char * sep_str
Definition: fftools_ffprobe.c:1248
json_print_section_footer
static void json_print_section_footer(WriterContext *wctx)
Definition: fftools_ffprobe.c:1562
do_show_pixel_format_components
__thread int do_show_pixel_format_components
Definition: fftools_ffprobe.c:110
SECTION_ID_STREAM_DISPOSITION
@ SECTION_ID_STREAM_DISPOSITION
Definition: fftools_ffprobe.c:206
opt_show_optional_fields
static int opt_show_optional_fields(void *optctx, const char *opt, const char *arg)
Definition: fftools_ffprobe.c:3276
default_options
static const AVOption default_options[]
Definition: fftools_ffprobe.c:948