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