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