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 static const char *xml_escape_str(AVBPrint *dst, const char *src, void *log_ctx)
1676 {
1677  const char *p;
1678 
1679  for (p = src; *p; p++) {
1680  switch (*p) {
1681  case '&' : av_bprintf(dst, "%s", "&amp;"); break;
1682  case '<' : av_bprintf(dst, "%s", "&lt;"); break;
1683  case '>' : av_bprintf(dst, "%s", "&gt;"); break;
1684  case '"' : av_bprintf(dst, "%s", "&quot;"); break;
1685  case '\'': av_bprintf(dst, "%s", "&apos;"); break;
1686  default: av_bprint_chars(dst, *p, 1);
1687  }
1688  }
1689 
1690  return dst->str;
1691 }
1692 
1693 #define XML_INDENT() printf("%*c", xml->indent_level * 4, ' ')
1694 
1695 static void xml_print_section_header(WriterContext *wctx)
1696 {
1697  XMLContext *xml = wctx->priv;
1698  const struct section *section = wctx->section[wctx->level];
1699  const struct section *parent_section = wctx->level ?
1700  wctx->section[wctx->level-1] : NULL;
1701 
1702  if (wctx->level == 0) {
1703  const char *qual = " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
1704  "xmlns:ffprobe='http://www.ffmpeg.org/schema/ffprobe' "
1705  "xsi:schemaLocation='http://www.ffmpeg.org/schema/ffprobe ffprobe.xsd'";
1706 
1707  printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1708  printf("<%sffprobe%s>\n",
1709  xml->fully_qualified ? "ffprobe:" : "",
1710  xml->fully_qualified ? qual : "");
1711  return;
1712  }
1713 
1714  if (xml->within_tag) {
1715  xml->within_tag = 0;
1716  printf(">\n");
1717  }
1718  if (section->flags & SECTION_FLAG_HAS_VARIABLE_FIELDS) {
1719  xml->indent_level++;
1720  } else {
1721  if (parent_section && (parent_section->flags & SECTION_FLAG_IS_WRAPPER) &&
1722  wctx->level && wctx->nb_item[wctx->level-1])
1723  printf("\n");
1724  xml->indent_level++;
1725 
1726  if (section->flags & SECTION_FLAG_IS_ARRAY) {
1727  XML_INDENT(); printf("<%s>\n", section->name);
1728  } else {
1729  XML_INDENT(); printf("<%s ", section->name);
1730  xml->within_tag = 1;
1731  }
1732  }
1733 }
1734 
1735 static void xml_print_section_footer(WriterContext *wctx)
1736 {
1737  XMLContext *xml = wctx->priv;
1738  const struct section *section = wctx->section[wctx->level];
1739 
1740  if (wctx->level == 0) {
1741  printf("</%sffprobe>\n", xml->fully_qualified ? "ffprobe:" : "");
1742  } else if (xml->within_tag) {
1743  xml->within_tag = 0;
1744  printf("/>\n");
1745  xml->indent_level--;
1746  } else if (section->flags & SECTION_FLAG_HAS_VARIABLE_FIELDS) {
1747  xml->indent_level--;
1748  } else {
1749  XML_INDENT(); printf("</%s>\n", section->name);
1750  xml->indent_level--;
1751  }
1752 }
1753 
1754 static void xml_print_str(WriterContext *wctx, const char *key, const char *value)
1755 {
1756  AVBPrint buf;
1757  XMLContext *xml = wctx->priv;
1758  const struct section *section = wctx->section[wctx->level];
1759 
1761 
1762  if (section->flags & SECTION_FLAG_HAS_VARIABLE_FIELDS) {
1763  XML_INDENT();
1764  printf("<%s key=\"%s\"",
1765  section->element_name, xml_escape_str(&buf, key, wctx));
1766  av_bprint_clear(&buf);
1767  printf(" value=\"%s\"/>\n", xml_escape_str(&buf, value, wctx));
1768  } else {
1769  if (wctx->nb_item[wctx->level])
1770  printf(" ");
1771  printf("%s=\"%s\"", key, xml_escape_str(&buf, value, wctx));
1772  }
1773 
1774  av_bprint_finalize(&buf, NULL);
1775 }
1776 
1777 static void xml_print_int(WriterContext *wctx, const char *key, long long int value)
1778 {
1779  if (wctx->nb_item[wctx->level])
1780  printf(" ");
1781  printf("%s=\"%lld\"", key, value);
1782 }
1783 
1784 static Writer xml_writer = {
1785  .name = "xml",
1786  .priv_size = sizeof(XMLContext),
1787  .init = xml_init,
1790  .print_integer = xml_print_int,
1791  .print_string = xml_print_str,
1793  .priv_class = &xml_class,
1794 };
1795 
1796 static void writer_register_all(void)
1797 {
1798  static int initialized;
1799 
1800  if (initialized)
1801  return;
1802  initialized = 1;
1803 
1804  writer_register(&default_writer);
1805  writer_register(&compact_writer);
1806  writer_register(&csv_writer);
1807  writer_register(&flat_writer);
1808  writer_register(&ini_writer);
1809  writer_register(&json_writer);
1810  writer_register(&xml_writer);
1811 }
1812 
1813 #define print_fmt(k, f, ...) do { \
1814  av_bprint_clear(&pbuf); \
1815  av_bprintf(&pbuf, f, __VA_ARGS__); \
1816  writer_print_string(w, k, pbuf.str, 0); \
1817 } while (0)
1818 
1819 #define print_int(k, v) writer_print_integer(w, k, v)
1820 #define print_q(k, v, s) writer_print_rational(w, k, v, s)
1821 #define print_str(k, v) writer_print_string(w, k, v, 0)
1822 #define print_str_opt(k, v) writer_print_string(w, k, v, PRINT_STRING_OPT)
1823 #define print_str_validate(k, v) writer_print_string(w, k, v, PRINT_STRING_VALIDATE)
1824 #define print_time(k, v, tb) writer_print_time(w, k, v, tb, 0)
1825 #define print_ts(k, v) writer_print_ts(w, k, v, 0)
1826 #define print_duration_time(k, v, tb) writer_print_time(w, k, v, tb, 1)
1827 #define print_duration_ts(k, v) writer_print_ts(w, k, v, 1)
1828 #define print_val(k, v, u) do { \
1829  struct unit_value uv; \
1830  uv.val.i = v; \
1831  uv.unit = u; \
1832  writer_print_string(w, k, value_string(val_str, sizeof(val_str), uv), 0); \
1833 } while (0)
1834 
1835 #define print_section_header(s) writer_print_section_header(w, s)
1836 #define print_section_footer(s) writer_print_section_footer(w, s)
1837 
1838 #define REALLOCZ_ARRAY_STREAM(ptr, cur_n, new_n) \
1839 { \
1840  ret = av_reallocp_array(&(ptr), (new_n), sizeof(*(ptr))); \
1841  if (ret < 0) \
1842  goto end; \
1843  memset( (ptr) + (cur_n), 0, ((new_n) - (cur_n)) * sizeof(*(ptr)) ); \
1844 }
1845 
1846 static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id)
1847 {
1849  int ret = 0;
1850 
1851  if (!tags)
1852  return 0;
1853  writer_print_section_header(w, section_id);
1854 
1855  while ((tag = av_dict_get(tags, "", tag, AV_DICT_IGNORE_SUFFIX))) {
1856  if ((ret = print_str_validate(tag->key, tag->value)) < 0)
1857  break;
1858  }
1860 
1861  return ret;
1862 }
1863 
1864 static void print_dynamic_hdr10_plus(WriterContext *w, const AVDynamicHDRPlus *metadata)
1865 {
1866  if (!metadata)
1867  return;
1868  print_int("application version", metadata->application_version);
1869  print_int("num_windows", metadata->num_windows);
1870  for (int n = 1; n < metadata->num_windows; n++) {
1871  const AVHDRPlusColorTransformParams *params = &metadata->params[n];
1872  print_q("window_upper_left_corner_x",
1873  params->window_upper_left_corner_x,'/');
1874  print_q("window_upper_left_corner_y",
1875  params->window_upper_left_corner_y,'/');
1876  print_q("window_lower_right_corner_x",
1877  params->window_lower_right_corner_x,'/');
1878  print_q("window_lower_right_corner_y",
1879  params->window_lower_right_corner_y,'/');
1880  print_q("window_upper_left_corner_x",
1881  params->window_upper_left_corner_x,'/');
1882  print_q("window_upper_left_corner_y",
1883  params->window_upper_left_corner_y,'/');
1884  print_int("center_of_ellipse_x",
1885  params->center_of_ellipse_x ) ;
1886  print_int("center_of_ellipse_y",
1887  params->center_of_ellipse_y );
1888  print_int("rotation_angle",
1889  params->rotation_angle);
1890  print_int("semimajor_axis_internal_ellipse",
1892  print_int("semimajor_axis_external_ellipse",
1894  print_int("semiminor_axis_external_ellipse",
1896  print_int("overlap_process_option",
1897  params->overlap_process_option);
1898  }
1899  print_q("targeted_system_display_maximum_luminance",
1902  print_int("num_rows_targeted_system_display_actual_peak_luminance",
1904  print_int("num_cols_targeted_system_display_actual_peak_luminance",
1906  for (int i = 0; i < metadata->num_rows_targeted_system_display_actual_peak_luminance; i++) {
1907  for (int j = 0; j < metadata->num_cols_targeted_system_display_actual_peak_luminance; j++) {
1908  print_q("targeted_system_display_actual_peak_luminance",
1910  }
1911  }
1912  }
1913  for (int n = 0; n < metadata->num_windows; n++) {
1914  const AVHDRPlusColorTransformParams *params = &metadata->params[n];
1915  for (int i = 0; i < 3; i++) {
1916  print_q("maxscl",params->maxscl[i],'/');
1917  }
1918  print_q("average_maxrgb",
1919  params->average_maxrgb,'/');
1920  print_int("num_distribution_maxrgb_percentiles",
1922  for (int i = 0; i < params->num_distribution_maxrgb_percentiles; i++) {
1923  print_int("distribution_maxrgb_percentage",
1924  params->distribution_maxrgb[i].percentage);
1925  print_q("distribution_maxrgb_percentile",
1926  params->distribution_maxrgb[i].percentile,'/');
1927  }
1928  print_q("fraction_bright_pixels",
1929  params->fraction_bright_pixels,'/');
1930  }
1932  print_int("num_rows_mastering_display_actual_peak_luminance",
1934  print_int("num_cols_mastering_display_actual_peak_luminance",
1936  for (int i = 0; i < metadata->num_rows_mastering_display_actual_peak_luminance; i++) {
1937  for (int j = 0; j < metadata->num_cols_mastering_display_actual_peak_luminance; j++) {
1938  print_q("mastering_display_actual_peak_luminance",
1939  metadata->mastering_display_actual_peak_luminance[i][j],'/');
1940  }
1941  }
1942  }
1943 
1944  for (int n = 0; n < metadata->num_windows; n++) {
1945  const AVHDRPlusColorTransformParams *params = &metadata->params[n];
1946  if (params->tone_mapping_flag) {
1947  print_q("knee_point_x", params->knee_point_x,'/');
1948  print_q("knee_point_y", params->knee_point_y,'/');
1949  print_int("num_bezier_curve_anchors",
1950  params->num_bezier_curve_anchors );
1951  for (int i = 0; i < params->num_bezier_curve_anchors; i++) {
1952  print_q("bezier_curve_anchors",
1953  params->bezier_curve_anchors[i],'/');
1954  }
1955  }
1956  if (params->color_saturation_mapping_flag) {
1957  print_q("color_saturation_weight",
1958  params->color_saturation_weight,'/');
1959  }
1960  }
1961 }
1962 
1963 static void print_pkt_side_data(WriterContext *w,
1964  AVCodecParameters *par,
1965  const AVPacketSideData *side_data,
1966  int nb_side_data,
1967  SectionID id_data_list,
1968  SectionID id_data)
1969 {
1970  int i;
1971 
1972  writer_print_section_header(w, id_data_list);
1973  for (i = 0; i < nb_side_data; i++) {
1974  const AVPacketSideData *sd = &side_data[i];
1975  const char *name = av_packet_side_data_name(sd->type);
1976 
1977  writer_print_section_header(w, id_data);
1978  print_str("side_data_type", name ? name : "unknown");
1979  if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9*4) {
1980  writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1);
1981  print_int("rotation", av_display_rotation_get((int32_t *)sd->data));
1982  } else if (sd->type == AV_PKT_DATA_STEREO3D) {
1983  const AVStereo3D *stereo = (AVStereo3D *)sd->data;
1984  print_str("type", av_stereo3d_type_name(stereo->type));
1985  print_int("inverted", !!(stereo->flags & AV_STEREO3D_FLAG_INVERT));
1986  } else if (sd->type == AV_PKT_DATA_SPHERICAL) {
1987  const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data;
1988  print_str("projection", av_spherical_projection_name(spherical->projection));
1989  if (spherical->projection == AV_SPHERICAL_CUBEMAP) {
1990  print_int("padding", spherical->padding);
1991  } else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) {
1992  size_t l, t, r, b;
1993  av_spherical_tile_bounds(spherical, par->width, par->height,
1994  &l, &t, &r, &b);
1995  print_int("bound_left", l);
1996  print_int("bound_top", t);
1997  print_int("bound_right", r);
1998  print_int("bound_bottom", b);
1999  }
2000 
2001  print_int("yaw", (double) spherical->yaw / (1 << 16));
2002  print_int("pitch", (double) spherical->pitch / (1 << 16));
2003  print_int("roll", (double) spherical->roll / (1 << 16));
2004  } else if (sd->type == AV_PKT_DATA_SKIP_SAMPLES && sd->size == 10) {
2005  print_int("skip_samples", AV_RL32(sd->data));
2006  print_int("discard_padding", AV_RL32(sd->data + 4));
2007  print_int("skip_reason", AV_RL8(sd->data + 8));
2008  print_int("discard_reason", AV_RL8(sd->data + 9));
2009  } else if (sd->type == AV_PKT_DATA_MASTERING_DISPLAY_METADATA) {
2011 
2012  if (metadata->has_primaries) {
2013  print_q("red_x", metadata->display_primaries[0][0], '/');
2014  print_q("red_y", metadata->display_primaries[0][1], '/');
2015  print_q("green_x", metadata->display_primaries[1][0], '/');
2016  print_q("green_y", metadata->display_primaries[1][1], '/');
2017  print_q("blue_x", metadata->display_primaries[2][0], '/');
2018  print_q("blue_y", metadata->display_primaries[2][1], '/');
2019 
2020  print_q("white_point_x", metadata->white_point[0], '/');
2021  print_q("white_point_y", metadata->white_point[1], '/');
2022  }
2023 
2024  if (metadata->has_luminance) {
2025  print_q("min_luminance", metadata->min_luminance, '/');
2026  print_q("max_luminance", metadata->max_luminance, '/');
2027  }
2028  } else if (sd->type == AV_PKT_DATA_CONTENT_LIGHT_LEVEL) {
2030  print_int("max_content", metadata->MaxCLL);
2031  print_int("max_average", metadata->MaxFALL);
2032  } else if (sd->type == AV_PKT_DATA_DOVI_CONF) {
2034  print_int("dv_version_major", dovi->dv_version_major);
2035  print_int("dv_version_minor", dovi->dv_version_minor);
2036  print_int("dv_profile", dovi->dv_profile);
2037  print_int("dv_level", dovi->dv_level);
2038  print_int("rpu_present_flag", dovi->rpu_present_flag);
2039  print_int("el_present_flag", dovi->el_present_flag);
2040  print_int("bl_present_flag", dovi->bl_present_flag);
2041  print_int("dv_bl_signal_compatibility_id", dovi->dv_bl_signal_compatibility_id);
2042  }
2044  }
2046 }
2047 
2048 static void print_color_range(WriterContext *w, enum AVColorRange color_range)
2049 {
2050  const char *val = av_color_range_name(color_range);
2051  if (!val || color_range == AVCOL_RANGE_UNSPECIFIED) {
2052  print_str_opt("color_range", "unknown");
2053  } else {
2054  print_str("color_range", val);
2055  }
2056 }
2057 
2058 static void print_color_space(WriterContext *w, enum AVColorSpace color_space)
2059 {
2060  const char *val = av_color_space_name(color_space);
2061  if (!val || color_space == AVCOL_SPC_UNSPECIFIED) {
2062  print_str_opt("color_space", "unknown");
2063  } else {
2064  print_str("color_space", val);
2065  }
2066 }
2067 
2068 static void print_primaries(WriterContext *w, enum AVColorPrimaries color_primaries)
2069 {
2070  const char *val = av_color_primaries_name(color_primaries);
2071  if (!val || color_primaries == AVCOL_PRI_UNSPECIFIED) {
2072  print_str_opt("color_primaries", "unknown");
2073  } else {
2074  print_str("color_primaries", val);
2075  }
2076 }
2077 
2078 static void print_color_trc(WriterContext *w, enum AVColorTransferCharacteristic color_trc)
2079 {
2080  const char *val = av_color_transfer_name(color_trc);
2081  if (!val || color_trc == AVCOL_TRC_UNSPECIFIED) {
2082  print_str_opt("color_transfer", "unknown");
2083  } else {
2084  print_str("color_transfer", val);
2085  }
2086 }
2087 
2088 static void print_chroma_location(WriterContext *w, enum AVChromaLocation chroma_location)
2089 {
2090  const char *val = av_chroma_location_name(chroma_location);
2091  if (!val || chroma_location == AVCHROMA_LOC_UNSPECIFIED) {
2092  print_str_opt("chroma_location", "unspecified");
2093  } else {
2094  print_str("chroma_location", val);
2095  }
2096 }
2097 
2098 
2099 static void clear_log(int need_lock)
2100 {
2101  int i;
2102 
2103  if (need_lock)
2104  pthread_mutex_lock(&log_mutex);
2105  for (i=0; i<log_buffer_size; i++) {
2106  av_freep(&log_buffer[i].context_name);
2107  av_freep(&log_buffer[i].parent_name);
2108  av_freep(&log_buffer[i].log_message);
2109  }
2110  log_buffer_size = 0;
2111  if(need_lock)
2112  pthread_mutex_unlock(&log_mutex);
2113 }
2114 
2115 static int show_log(WriterContext *w, int section_ids, int section_id, int log_level)
2116 {
2117  int i;
2118  pthread_mutex_lock(&log_mutex);
2119  if (!log_buffer_size) {
2120  pthread_mutex_unlock(&log_mutex);
2121  return 0;
2122  }
2123  writer_print_section_header(w, section_ids);
2124 
2125  for (i=0; i<log_buffer_size; i++) {
2126  if (log_buffer[i].log_level <= log_level) {
2127  writer_print_section_header(w, section_id);
2128  print_str("context", log_buffer[i].context_name);
2129  print_int("level", log_buffer[i].log_level);
2130  print_int("category", log_buffer[i].category);
2131  if (log_buffer[i].parent_name) {
2132  print_str("parent_context", log_buffer[i].parent_name);
2133  print_int("parent_category", log_buffer[i].parent_category);
2134  } else {
2135  print_str_opt("parent_context", "N/A");
2136  print_str_opt("parent_category", "N/A");
2137  }
2138  print_str("message", log_buffer[i].log_message);
2140  }
2141  }
2142  clear_log(0);
2143  pthread_mutex_unlock(&log_mutex);
2144 
2146 
2147  return 0;
2148 }
2149 
2150 static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int packet_idx)
2151 {
2152  char val_str[128];
2153  AVStream *st = ifile->streams[pkt->stream_index].st;
2154  AVBPrint pbuf;
2155  const char *s;
2156 
2158 
2160 
2162  if (s) print_str ("codec_type", s);
2163  else print_str_opt("codec_type", "unknown");
2164  print_int("stream_index", pkt->stream_index);
2165  print_ts ("pts", pkt->pts);
2166  print_time("pts_time", pkt->pts, &st->time_base);
2167  print_ts ("dts", pkt->dts);
2168  print_time("dts_time", pkt->dts, &st->time_base);
2169  print_duration_ts("duration", pkt->duration);
2170  print_duration_time("duration_time", pkt->duration, &st->time_base);
2171  print_duration_ts("convergence_duration", pkt->convergence_duration);
2172  print_duration_time("convergence_duration_time", pkt->convergence_duration, &st->time_base);
2173  print_val("size", pkt->size, unit_byte_str);
2174  if (pkt->pos != -1) print_fmt ("pos", "%"PRId64, pkt->pos);
2175  else print_str_opt("pos", "N/A");
2176  print_fmt("flags", "%c%c", pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_',
2177  pkt->flags & AV_PKT_FLAG_DISCARD ? 'D' : '_');
2178 
2179  if (pkt->side_data_elems) {
2180  int size;
2181  const uint8_t *side_metadata;
2182 
2183  side_metadata = av_packet_get_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, &size);
2184  if (side_metadata && size && do_show_packet_tags) {
2185  AVDictionary *dict = NULL;
2186  if (av_packet_unpack_dictionary(side_metadata, size, &dict) >= 0)
2188  av_dict_free(&dict);
2189  }
2190 
2194  }
2195 
2196  if (do_show_data)
2197  writer_print_data(w, "data", pkt->data, pkt->size);
2198  writer_print_data_hash(w, "data_hash", pkt->data, pkt->size);
2200 
2201  av_bprint_finalize(&pbuf, NULL);
2202  fflush(stdout);
2203 }
2204 
2205 static void show_subtitle(WriterContext *w, AVSubtitle *sub, AVStream *stream,
2207 {
2208  AVBPrint pbuf;
2209 
2211 
2213 
2214  print_str ("media_type", "subtitle");
2215  print_ts ("pts", sub->pts);
2216  print_time("pts_time", sub->pts, &AV_TIME_BASE_Q);
2217  print_int ("format", sub->format);
2218  print_int ("start_display_time", sub->start_display_time);
2219  print_int ("end_display_time", sub->end_display_time);
2220  print_int ("num_rects", sub->num_rects);
2221 
2223 
2224  av_bprint_finalize(&pbuf, NULL);
2225  fflush(stdout);
2226 }
2227 
2228 static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
2230 {
2231  AVBPrint pbuf;
2232  char val_str[128];
2233  const char *s;
2234  int i;
2235 
2237 
2239 
2241  if (s) print_str ("media_type", s);
2242  else print_str_opt("media_type", "unknown");
2243  print_int("stream_index", stream->index);
2244  print_int("key_frame", frame->key_frame);
2245  print_ts ("pkt_pts", frame->pts);
2246  print_time("pkt_pts_time", frame->pts, &stream->time_base);
2247  print_ts ("pkt_dts", frame->pkt_dts);
2248  print_time("pkt_dts_time", frame->pkt_dts, &stream->time_base);
2249  print_ts ("best_effort_timestamp", frame->best_effort_timestamp);
2250  print_time("best_effort_timestamp_time", frame->best_effort_timestamp, &stream->time_base);
2251  print_duration_ts ("pkt_duration", frame->pkt_duration);
2252  print_duration_time("pkt_duration_time", frame->pkt_duration, &stream->time_base);
2253  if (frame->pkt_pos != -1) print_fmt ("pkt_pos", "%"PRId64, frame->pkt_pos);
2254  else print_str_opt("pkt_pos", "N/A");
2255  if (frame->pkt_size != -1) print_val ("pkt_size", frame->pkt_size, unit_byte_str);
2256  else print_str_opt("pkt_size", "N/A");
2257 
2258  switch (stream->codecpar->codec_type) {
2259  AVRational sar;
2260 
2261  case AVMEDIA_TYPE_VIDEO:
2262  print_int("width", frame->width);
2263  print_int("height", frame->height);
2264  s = av_get_pix_fmt_name(frame->format);
2265  if (s) print_str ("pix_fmt", s);
2266  else print_str_opt("pix_fmt", "unknown");
2267  sar = av_guess_sample_aspect_ratio(fmt_ctx, stream, frame);
2268  if (sar.num) {
2269  print_q("sample_aspect_ratio", sar, ':');
2270  } else {
2271  print_str_opt("sample_aspect_ratio", "N/A");
2272  }
2273  print_fmt("pict_type", "%c", av_get_picture_type_char(frame->pict_type));
2274  print_int("coded_picture_number", frame->coded_picture_number);
2275  print_int("display_picture_number", frame->display_picture_number);
2276  print_int("interlaced_frame", frame->interlaced_frame);
2277  print_int("top_field_first", frame->top_field_first);
2278  print_int("repeat_pict", frame->repeat_pict);
2279 
2280  print_color_range(w, frame->color_range);
2281  print_color_space(w, frame->colorspace);
2282  print_primaries(w, frame->color_primaries);
2283  print_color_trc(w, frame->color_trc);
2285  break;
2286 
2287  case AVMEDIA_TYPE_AUDIO:
2288  s = av_get_sample_fmt_name(frame->format);
2289  if (s) print_str ("sample_fmt", s);
2290  else print_str_opt("sample_fmt", "unknown");
2291  print_int("nb_samples", frame->nb_samples);
2292  print_int("channels", frame->channels);
2293  if (frame->channel_layout) {
2294  av_bprint_clear(&pbuf);
2295  av_bprint_channel_layout(&pbuf, frame->channels,
2296  frame->channel_layout);
2297  print_str ("channel_layout", pbuf.str);
2298  } else
2299  print_str_opt("channel_layout", "unknown");
2300  break;
2301  }
2302  if (do_show_frame_tags)
2304  if (do_show_log)
2306  if (frame->nb_side_data) {
2308  for (i = 0; i < frame->nb_side_data; i++) {
2309  AVFrameSideData *sd = frame->side_data[i];
2310  const char *name;
2311 
2313  name = av_frame_side_data_name(sd->type);
2314  print_str("side_data_type", name ? name : "unknown");
2315  if (sd->type == AV_FRAME_DATA_DISPLAYMATRIX && sd->size >= 9*4) {
2316  writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1);
2317  print_int("rotation", av_display_rotation_get((int32_t *)sd->data));
2318  } else if (sd->type == AV_FRAME_DATA_GOP_TIMECODE && sd->size >= 8) {
2319  char tcbuf[AV_TIMECODE_STR_SIZE];
2320  av_timecode_make_mpeg_tc_string(tcbuf, *(int64_t *)(sd->data));
2321  print_str("timecode", tcbuf);
2322  } else if (sd->type == AV_FRAME_DATA_S12M_TIMECODE && sd->size == 16) {
2323  uint32_t *tc = (uint32_t*)sd->data;
2324  int m = FFMIN(tc[0],3);
2326  for (int j = 1; j <= m ; j++) {
2327  char tcbuf[AV_TIMECODE_STR_SIZE];
2328  av_timecode_make_smpte_tc_string2(tcbuf, stream->avg_frame_rate, tc[j], 0, 0);
2330  print_str("value", tcbuf);
2332  }
2334  } else if (sd->type == AV_FRAME_DATA_MASTERING_DISPLAY_METADATA) {
2336 
2337  if (metadata->has_primaries) {
2338  print_q("red_x", metadata->display_primaries[0][0], '/');
2339  print_q("red_y", metadata->display_primaries[0][1], '/');
2340  print_q("green_x", metadata->display_primaries[1][0], '/');
2341  print_q("green_y", metadata->display_primaries[1][1], '/');
2342  print_q("blue_x", metadata->display_primaries[2][0], '/');
2343  print_q("blue_y", metadata->display_primaries[2][1], '/');
2344 
2345  print_q("white_point_x", metadata->white_point[0], '/');
2346  print_q("white_point_y", metadata->white_point[1], '/');
2347  }
2348 
2349  if (metadata->has_luminance) {
2350  print_q("min_luminance", metadata->min_luminance, '/');
2351  print_q("max_luminance", metadata->max_luminance, '/');
2352  }
2353  } else if (sd->type == AV_FRAME_DATA_DYNAMIC_HDR_PLUS) {
2354  AVDynamicHDRPlus *metadata = (AVDynamicHDRPlus *)sd->data;
2355  print_dynamic_hdr10_plus(w, metadata);
2356  } else if (sd->type == AV_FRAME_DATA_CONTENT_LIGHT_LEVEL) {
2358  print_int("max_content", metadata->MaxCLL);
2359  print_int("max_average", metadata->MaxFALL);
2360  } else if (sd->type == AV_FRAME_DATA_ICC_PROFILE) {
2362  if (tag)
2363  print_str(tag->key, tag->value);
2364  print_int("size", sd->size);
2365  }
2367  }
2369  }
2370 
2372 
2373  av_bprint_finalize(&pbuf, NULL);
2374  fflush(stdout);
2375 }
2376 
2377 static av_always_inline int process_frame(WriterContext *w,
2378  InputFile *ifile,
2380  int *packet_new)
2381 {
2382  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2384  AVCodecParameters *par = ifile->streams[pkt->stream_index].st->codecpar;
2385  AVSubtitle sub;
2386  int ret = 0, got_frame = 0;
2387 
2388  clear_log(1);
2389  if (dec_ctx && dec_ctx->codec) {
2390  switch (par->codec_type) {
2391  case AVMEDIA_TYPE_VIDEO:
2392  case AVMEDIA_TYPE_AUDIO:
2393  if (*packet_new) {
2394  ret = avcodec_send_packet(dec_ctx, pkt);
2395  if (ret == AVERROR(EAGAIN)) {
2396  ret = 0;
2397  } else if (ret >= 0 || ret == AVERROR_EOF) {
2398  ret = 0;
2399  *packet_new = 0;
2400  }
2401  }
2402  if (ret >= 0) {
2403  ret = avcodec_receive_frame(dec_ctx, frame);
2404  if (ret >= 0) {
2405  got_frame = 1;
2406  } else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2407  ret = 0;
2408  }
2409  }
2410  break;
2411 
2412  case AVMEDIA_TYPE_SUBTITLE:
2413  if (*packet_new)
2414  ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_frame, pkt);
2415  *packet_new = 0;
2416  break;
2417  default:
2418  *packet_new = 0;
2419  }
2420  } else {
2421  *packet_new = 0;
2422  }
2423 
2424  if (ret < 0)
2425  return ret;
2426  if (got_frame) {
2427  int is_sub = (par->codec_type == AVMEDIA_TYPE_SUBTITLE);
2429  if (do_show_frames)
2430  if (is_sub)
2431  show_subtitle(w, &sub, ifile->streams[pkt->stream_index].st, fmt_ctx);
2432  else
2433  show_frame(w, frame, ifile->streams[pkt->stream_index].st, fmt_ctx);
2434  if (is_sub)
2435  avsubtitle_free(&sub);
2436  }
2437  return got_frame || *packet_new;
2438 }
2439 
2440 static void log_read_interval(const ReadInterval *interval, void *log_ctx, int log_level)
2441 {
2442  av_log(log_ctx, log_level, "id:%d", interval->id);
2443 
2444  if (interval->has_start) {
2445  av_log(log_ctx, log_level, " start:%s%s", interval->start_is_offset ? "+" : "",
2446  av_ts2timestr(interval->start, &AV_TIME_BASE_Q));
2447  } else {
2448  av_log(log_ctx, log_level, " start:N/A");
2449  }
2450 
2451  if (interval->has_end) {
2452  av_log(log_ctx, log_level, " end:%s", interval->end_is_offset ? "+" : "");
2453  if (interval->duration_frames)
2454  av_log(log_ctx, log_level, "#%"PRId64, interval->end);
2455  else
2456  av_log(log_ctx, log_level, "%s", av_ts2timestr(interval->end, &AV_TIME_BASE_Q));
2457  } else {
2458  av_log(log_ctx, log_level, " end:N/A");
2459  }
2460 
2461  av_log(log_ctx, log_level, "\n");
2462 }
2463 
2464 static int read_interval_packets(WriterContext *w, InputFile *ifile,
2465  const ReadInterval *interval, int64_t *cur_ts)
2466 {
2467  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2468  AVPacket pkt;
2469  AVFrame *frame = NULL;
2470  int ret = 0, i = 0, frame_count = 0;
2471  int64_t start = -INT64_MAX, end = interval->end;
2472  int has_start = 0, has_end = interval->has_end && !interval->end_is_offset;
2473 
2474  av_init_packet(&pkt);
2475 
2476  av_log(NULL, AV_LOG_VERBOSE, "Processing read interval ");
2478 
2479  if (interval->has_start) {
2480  int64_t target;
2481  if (interval->start_is_offset) {
2482  if (*cur_ts == AV_NOPTS_VALUE) {
2484  "Could not seek to relative position since current "
2485  "timestamp is not defined\n");
2486  ret = AVERROR(EINVAL);
2487  goto end;
2488  }
2489  target = *cur_ts + interval->start;
2490  } else {
2491  target = interval->start;
2492  }
2493 
2494  av_log(NULL, AV_LOG_VERBOSE, "Seeking to read interval start point %s\n",
2495  av_ts2timestr(target, &AV_TIME_BASE_Q));
2496  if ((ret = avformat_seek_file(fmt_ctx, -1, -INT64_MAX, target, INT64_MAX, 0)) < 0) {
2497  av_log(NULL, AV_LOG_ERROR, "Could not seek to position %"PRId64": %s\n",
2498  interval->start, av_err2str(ret));
2499  goto end;
2500  }
2501  }
2502 
2503  frame = av_frame_alloc();
2504  if (!frame) {
2505  ret = AVERROR(ENOMEM);
2506  goto end;
2507  }
2508  while (!av_read_frame(fmt_ctx, &pkt)) {
2509  if (fmt_ctx->nb_streams > nb_streams) {
2513  nb_streams = fmt_ctx->nb_streams;
2514  }
2515  if (selected_streams[pkt.stream_index]) {
2516  AVRational tb = ifile->streams[pkt.stream_index].st->time_base;
2517 
2518  if (pkt.pts != AV_NOPTS_VALUE)
2519  *cur_ts = av_rescale_q(pkt.pts, tb, AV_TIME_BASE_Q);
2520 
2521  if (!has_start && *cur_ts != AV_NOPTS_VALUE) {
2522  start = *cur_ts;
2523  has_start = 1;
2524  }
2525 
2526  if (has_start && !has_end && interval->end_is_offset) {
2527  end = start + interval->end;
2528  has_end = 1;
2529  }
2530 
2531  if (interval->end_is_offset && interval->duration_frames) {
2532  if (frame_count >= interval->end)
2533  break;
2534  } else if (has_end && *cur_ts != AV_NOPTS_VALUE && *cur_ts >= end) {
2535  break;
2536  }
2537 
2538  frame_count++;
2539  if (do_read_packets) {
2540  if (do_show_packets)
2541  show_packet(w, ifile, &pkt, i++);
2543  }
2544  if (do_read_frames) {
2545  int packet_new = 1;
2546  while (process_frame(w, ifile, frame, &pkt, &packet_new) > 0);
2547  }
2548  }
2549  av_packet_unref(&pkt);
2550  }
2551  av_packet_unref(&pkt);
2552  //Flush remaining frames that are cached in the decoder
2553  for (i = 0; i < fmt_ctx->nb_streams; i++) {
2554  pkt.stream_index = i;
2555  if (do_read_frames)
2556  while (process_frame(w, ifile, frame, &pkt, &(int){1}) > 0);
2557  }
2558 
2559 end:
2560  av_frame_free(&frame);
2561  if (ret < 0) {
2562  av_log(NULL, AV_LOG_ERROR, "Could not read packets in interval ");
2563  log_read_interval(interval, NULL, AV_LOG_ERROR);
2564  }
2565  return ret;
2566 }
2567 
2568 static int read_packets(WriterContext *w, InputFile *ifile)
2569 {
2570  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2571  int i, ret = 0;
2572  int64_t cur_ts = fmt_ctx->start_time;
2573 
2574  if (read_intervals_nb == 0) {
2575  ReadInterval interval = (ReadInterval) { .has_start = 0, .has_end = 0 };
2576  ret = read_interval_packets(w, ifile, &interval, &cur_ts);
2577  } else {
2578  for (i = 0; i < read_intervals_nb; i++) {
2579  ret = read_interval_packets(w, ifile, &read_intervals[i], &cur_ts);
2580  if (ret < 0)
2581  break;
2582  }
2583  }
2584 
2585  return ret;
2586 }
2587 
2588 static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx, InputStream *ist, int in_program)
2589 {
2590  AVStream *stream = ist->st;
2591  AVCodecParameters *par;
2593  char val_str[128];
2594  const char *s;
2595  AVRational sar, dar;
2596  AVBPrint pbuf;
2597  const AVCodecDescriptor *cd;
2598  int ret = 0;
2599  const char *profile = NULL;
2600 
2602 
2604 
2605  print_int("index", stream->index);
2606 
2607  par = stream->codecpar;
2608  dec_ctx = ist->dec_ctx;
2609  if (cd = avcodec_descriptor_get(par->codec_id)) {
2610  print_str("codec_name", cd->name);
2611  if (!do_bitexact) {
2612  print_str("codec_long_name",
2613  cd->long_name ? cd->long_name : "unknown");
2614  }
2615  } else {
2616  print_str_opt("codec_name", "unknown");
2617  if (!do_bitexact) {
2618  print_str_opt("codec_long_name", "unknown");
2619  }
2620  }
2621 
2622  if (!do_bitexact && (profile = avcodec_profile_name(par->codec_id, par->profile)))
2623  print_str("profile", profile);
2624  else {
2625  if (par->profile != FF_PROFILE_UNKNOWN) {
2626  char profile_num[12];
2627  snprintf(profile_num, sizeof(profile_num), "%d", par->profile);
2628  print_str("profile", profile_num);
2629  } else
2630  print_str_opt("profile", "unknown");
2631  }
2632 
2634  if (s) print_str ("codec_type", s);
2635  else print_str_opt("codec_type", "unknown");
2636 #if FF_API_LAVF_AVCTX
2637  if (dec_ctx)
2638  print_q("codec_time_base", dec_ctx->time_base, '/');
2639 #endif
2640 
2641  /* print AVI/FourCC tag */
2642  print_str("codec_tag_string", av_fourcc2str(par->codec_tag));
2643  print_fmt("codec_tag", "0x%04"PRIx32, par->codec_tag);
2644 
2645  switch (par->codec_type) {
2646  case AVMEDIA_TYPE_VIDEO:
2647  print_int("width", par->width);
2648  print_int("height", par->height);
2649 #if FF_API_LAVF_AVCTX
2650  if (dec_ctx) {
2651  print_int("coded_width", dec_ctx->coded_width);
2652  print_int("coded_height", dec_ctx->coded_height);
2653  print_int("closed_captions", !!(dec_ctx->properties & FF_CODEC_PROPERTY_CLOSED_CAPTIONS));
2654  }
2655 #endif
2656  print_int("has_b_frames", par->video_delay);
2657  sar = av_guess_sample_aspect_ratio(fmt_ctx, stream, NULL);
2658  if (sar.num) {
2659  print_q("sample_aspect_ratio", sar, ':');
2660  av_reduce(&dar.num, &dar.den,
2661  par->width * sar.num,
2662  par->height * sar.den,
2663  1024*1024);
2664  print_q("display_aspect_ratio", dar, ':');
2665  } else {
2666  print_str_opt("sample_aspect_ratio", "N/A");
2667  print_str_opt("display_aspect_ratio", "N/A");
2668  }
2669  s = av_get_pix_fmt_name(par->format);
2670  if (s) print_str ("pix_fmt", s);
2671  else print_str_opt("pix_fmt", "unknown");
2672  print_int("level", par->level);
2673 
2674  print_color_range(w, par->color_range);
2675  print_color_space(w, par->color_space);
2676  print_color_trc(w, par->color_trc);
2679 
2680  if (par->field_order == AV_FIELD_PROGRESSIVE)
2681  print_str("field_order", "progressive");
2682  else if (par->field_order == AV_FIELD_TT)
2683  print_str("field_order", "tt");
2684  else if (par->field_order == AV_FIELD_BB)
2685  print_str("field_order", "bb");
2686  else if (par->field_order == AV_FIELD_TB)
2687  print_str("field_order", "tb");
2688  else if (par->field_order == AV_FIELD_BT)
2689  print_str("field_order", "bt");
2690  else
2691  print_str_opt("field_order", "unknown");
2692 
2693 #if FF_API_PRIVATE_OPT
2694  if (dec_ctx && dec_ctx->timecode_frame_start >= 0) {
2695  char tcbuf[AV_TIMECODE_STR_SIZE];
2697  print_str("timecode", tcbuf);
2698  } else {
2699  print_str_opt("timecode", "N/A");
2700  }
2701 #endif
2702  if (dec_ctx)
2703  print_int("refs", dec_ctx->refs);
2704  break;
2705 
2706  case AVMEDIA_TYPE_AUDIO:
2707  s = av_get_sample_fmt_name(par->format);
2708  if (s) print_str ("sample_fmt", s);
2709  else print_str_opt("sample_fmt", "unknown");
2710  print_val("sample_rate", par->sample_rate, unit_hertz_str);
2711  print_int("channels", par->channels);
2712 
2713  if (par->channel_layout) {
2714  av_bprint_clear(&pbuf);
2716  print_str ("channel_layout", pbuf.str);
2717  } else {
2718  print_str_opt("channel_layout", "unknown");
2719  }
2720 
2721  print_int("bits_per_sample", av_get_bits_per_sample(par->codec_id));
2722  break;
2723 
2724  case AVMEDIA_TYPE_SUBTITLE:
2725  if (par->width)
2726  print_int("width", par->width);
2727  else
2728  print_str_opt("width", "N/A");
2729  if (par->height)
2730  print_int("height", par->height);
2731  else
2732  print_str_opt("height", "N/A");
2733  break;
2734  }
2735 
2736  if (dec_ctx && dec_ctx->codec && dec_ctx->codec->priv_class && show_private_data) {
2737  const AVOption *opt = NULL;
2738  while (opt = av_opt_next(dec_ctx->priv_data,opt)) {
2739  uint8_t *str;
2740  if (opt->flags) continue;
2741  if (av_opt_get(dec_ctx->priv_data, opt->name, 0, &str) >= 0) {
2742  print_str(opt->name, str);
2743  av_free(str);
2744  }
2745  }
2746  }
2747 
2748  if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS) print_fmt ("id", "0x%x", stream->id);
2749  else print_str_opt("id", "N/A");
2750  print_q("r_frame_rate", stream->r_frame_rate, '/');
2751  print_q("avg_frame_rate", stream->avg_frame_rate, '/');
2752  print_q("time_base", stream->time_base, '/');
2753  print_ts ("start_pts", stream->start_time);
2754  print_time("start_time", stream->start_time, &stream->time_base);
2755  print_ts ("duration_ts", stream->duration);
2756  print_time("duration", stream->duration, &stream->time_base);
2757  if (par->bit_rate > 0) print_val ("bit_rate", par->bit_rate, unit_bit_per_second_str);
2758  else print_str_opt("bit_rate", "N/A");
2759 #if FF_API_LAVF_AVCTX
2760  if (stream->codec->rc_max_rate > 0) print_val ("max_bit_rate", stream->codec->rc_max_rate, unit_bit_per_second_str);
2761  else print_str_opt("max_bit_rate", "N/A");
2762 #endif
2763  if (dec_ctx && dec_ctx->bits_per_raw_sample > 0) print_fmt("bits_per_raw_sample", "%d", dec_ctx->bits_per_raw_sample);
2764  else print_str_opt("bits_per_raw_sample", "N/A");
2765  if (stream->nb_frames) print_fmt ("nb_frames", "%"PRId64, stream->nb_frames);
2766  else print_str_opt("nb_frames", "N/A");
2767  if (nb_streams_frames[stream_idx]) print_fmt ("nb_read_frames", "%"PRIu64, nb_streams_frames[stream_idx]);
2768  else print_str_opt("nb_read_frames", "N/A");
2769  if (nb_streams_packets[stream_idx]) print_fmt ("nb_read_packets", "%"PRIu64, nb_streams_packets[stream_idx]);
2770  else print_str_opt("nb_read_packets", "N/A");
2771  if (do_show_data)
2772  writer_print_data(w, "extradata", par->extradata,
2773  par->extradata_size);
2774  writer_print_data_hash(w, "extradata_hash", par->extradata,
2775  par->extradata_size);
2776 
2777  /* Print disposition information */
2778 #define PRINT_DISPOSITION(flagname, name) do { \
2779  print_int(name, !!(stream->disposition & AV_DISPOSITION_##flagname)); \
2780  } while (0)
2781 
2784  PRINT_DISPOSITION(DEFAULT, "default");
2785  PRINT_DISPOSITION(DUB, "dub");
2786  PRINT_DISPOSITION(ORIGINAL, "original");
2787  PRINT_DISPOSITION(COMMENT, "comment");
2788  PRINT_DISPOSITION(LYRICS, "lyrics");
2789  PRINT_DISPOSITION(KARAOKE, "karaoke");
2790  PRINT_DISPOSITION(FORCED, "forced");
2791  PRINT_DISPOSITION(HEARING_IMPAIRED, "hearing_impaired");
2792  PRINT_DISPOSITION(VISUAL_IMPAIRED, "visual_impaired");
2793  PRINT_DISPOSITION(CLEAN_EFFECTS, "clean_effects");
2794  PRINT_DISPOSITION(ATTACHED_PIC, "attached_pic");
2795  PRINT_DISPOSITION(TIMED_THUMBNAILS, "timed_thumbnails");
2797  }
2798 
2799  if (do_show_stream_tags)
2800  ret = show_tags(w, stream->metadata, in_program ? SECTION_ID_PROGRAM_STREAM_TAGS : SECTION_ID_STREAM_TAGS);
2801 
2802  if (stream->nb_side_data) {
2803  print_pkt_side_data(w, stream->codecpar, stream->side_data, stream->nb_side_data,
2806  }
2807 
2809  av_bprint_finalize(&pbuf, NULL);
2810  fflush(stdout);
2811 
2812  return ret;
2813 }
2814 
2815 static int show_streams(WriterContext *w, InputFile *ifile)
2816 {
2817  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2818  int i, ret = 0;
2819 
2821  for (i = 0; i < ifile->nb_streams; i++)
2822  if (selected_streams[i]) {
2823  ret = show_stream(w, fmt_ctx, i, &ifile->streams[i], 0);
2824  if (ret < 0)
2825  break;
2826  }
2828 
2829  return ret;
2830 }
2831 
2832 static int show_program(WriterContext *w, InputFile *ifile, AVProgram *program)
2833 {
2834  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2835  int i, ret = 0;
2836 
2838  print_int("program_id", program->id);
2839  print_int("program_num", program->program_num);
2840  print_int("nb_streams", program->nb_stream_indexes);
2841  print_int("pmt_pid", program->pmt_pid);
2842  print_int("pcr_pid", program->pcr_pid);
2843  print_ts("start_pts", program->start_time);
2844  print_time("start_time", program->start_time, &AV_TIME_BASE_Q);
2845  print_ts("end_pts", program->end_time);
2846  print_time("end_time", program->end_time, &AV_TIME_BASE_Q);
2848  ret = show_tags(w, program->metadata, SECTION_ID_PROGRAM_TAGS);
2849  if (ret < 0)
2850  goto end;
2851 
2853  for (i = 0; i < program->nb_stream_indexes; i++) {
2854  if (selected_streams[program->stream_index[i]]) {
2855  ret = show_stream(w, fmt_ctx, program->stream_index[i], &ifile->streams[program->stream_index[i]], 1);
2856  if (ret < 0)
2857  break;
2858  }
2859  }
2861 
2862 end:
2864  return ret;
2865 }
2866 
2867 static int show_programs(WriterContext *w, InputFile *ifile)
2868 {
2869  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2870  int i, ret = 0;
2871 
2873  for (i = 0; i < fmt_ctx->nb_programs; i++) {
2874  AVProgram *program = fmt_ctx->programs[i];
2875  if (!program)
2876  continue;
2877  ret = show_program(w, ifile, program);
2878  if (ret < 0)
2879  break;
2880  }
2882  return ret;
2883 }
2884 
2885 static int show_chapters(WriterContext *w, InputFile *ifile)
2886 {
2887  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2888  int i, ret = 0;
2889 
2891  for (i = 0; i < fmt_ctx->nb_chapters; i++) {
2892  AVChapter *chapter = fmt_ctx->chapters[i];
2893 
2895  print_int("id", chapter->id);
2896  print_q ("time_base", chapter->time_base, '/');
2897  print_int("start", chapter->start);
2898  print_time("start_time", chapter->start, &chapter->time_base);
2899  print_int("end", chapter->end);
2900  print_time("end_time", chapter->end, &chapter->time_base);
2902  ret = show_tags(w, chapter->metadata, SECTION_ID_CHAPTER_TAGS);
2904  }
2906 
2907  return ret;
2908 }
2909 
2910 static int show_format(WriterContext *w, InputFile *ifile)
2911 {
2912  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2913  char val_str[128];
2914  int64_t size = fmt_ctx->pb ? avio_size(fmt_ctx->pb) : -1;
2915  int ret = 0;
2916 
2918  print_str_validate("filename", fmt_ctx->url);
2919  print_int("nb_streams", fmt_ctx->nb_streams);
2920  print_int("nb_programs", fmt_ctx->nb_programs);
2921  print_str("format_name", fmt_ctx->iformat->name);
2922  if (!do_bitexact) {
2923  if (fmt_ctx->iformat->long_name) print_str ("format_long_name", fmt_ctx->iformat->long_name);
2924  else print_str_opt("format_long_name", "unknown");
2925  }
2926  print_time("start_time", fmt_ctx->start_time, &AV_TIME_BASE_Q);
2927  print_time("duration", fmt_ctx->duration, &AV_TIME_BASE_Q);
2928  if (size >= 0) print_val ("size", size, unit_byte_str);
2929  else print_str_opt("size", "N/A");
2930  if (fmt_ctx->bit_rate > 0) print_val ("bit_rate", fmt_ctx->bit_rate, unit_bit_per_second_str);
2931  else print_str_opt("bit_rate", "N/A");
2932  print_int("probe_score", fmt_ctx->probe_score);
2933  if (do_show_format_tags)
2934  ret = show_tags(w, fmt_ctx->metadata, SECTION_ID_FORMAT_TAGS);
2935 
2937  fflush(stdout);
2938  return ret;
2939 }
2940 
2941 static void show_error(WriterContext *w, int err)
2942 {
2943  char errbuf[128];
2944  const char *errbuf_ptr = errbuf;
2945 
2946  if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
2947  errbuf_ptr = strerror(AVUNERROR(err));
2948 
2950  print_int("code", err);
2951  print_str("string", errbuf_ptr);
2953 }
2954 
2955 static int open_input_file(InputFile *ifile, const char *filename,
2956  const char *print_filename)
2957 {
2958  int err, i;
2960  AVDictionaryEntry *t = NULL;
2961  int scan_all_pmts_set = 0;
2962 
2963  fmt_ctx = avformat_alloc_context();
2964  if (!fmt_ctx) {
2965  print_error(filename, AVERROR(ENOMEM));
2966  exit_program(1);
2967  }
2968 
2969  if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2970  av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2971  scan_all_pmts_set = 1;
2972  }
2973  if ((err = avformat_open_input(&fmt_ctx, filename,
2974  iformat, &format_opts)) < 0) {
2975  print_error(filename, err);
2976  return err;
2977  }
2978  if (print_filename) {
2979  av_freep(&fmt_ctx->url);
2980  fmt_ctx->url = av_strdup(print_filename);
2981  }
2982  ifile->fmt_ctx = fmt_ctx;
2983  if (scan_all_pmts_set)
2984  av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2985  while ((t = av_dict_get(format_opts, "", t, AV_DICT_IGNORE_SUFFIX)))
2986  av_log(NULL, AV_LOG_WARNING, "Option %s skipped - not known to demuxer.\n", t->key);
2987 
2988  if (find_stream_info) {
2990  int orig_nb_streams = fmt_ctx->nb_streams;
2991 
2992  err = avformat_find_stream_info(fmt_ctx, opts);
2993 
2994  for (i = 0; i < orig_nb_streams; i++)
2995  av_dict_free(&opts[i]);
2996  av_freep(&opts);
2997 
2998  if (err < 0) {
2999  print_error(filename, err);
3000  return err;
3001  }
3002  }
3003 
3004  av_dump_format(fmt_ctx, 0, filename, 0);
3005 
3006  ifile->streams = av_mallocz_array(fmt_ctx->nb_streams,
3007  sizeof(*ifile->streams));
3008  if (!ifile->streams)
3009  exit(1);
3010  ifile->nb_streams = fmt_ctx->nb_streams;
3011 
3012  /* bind a decoder to each input stream */
3013  for (i = 0; i < fmt_ctx->nb_streams; i++) {
3014  InputStream *ist = &ifile->streams[i];
3015  AVStream *stream = fmt_ctx->streams[i];
3016  AVCodec *codec;
3017 
3018  ist->st = stream;
3019 
3020  if (stream->codecpar->codec_id == AV_CODEC_ID_PROBE) {
3022  "Failed to probe codec for input stream %d\n",
3023  stream->index);
3024  continue;
3025  }
3026 
3027  codec = avcodec_find_decoder(stream->codecpar->codec_id);
3028  if (!codec) {
3030  "Unsupported codec with id %d for input stream %d\n",
3031  stream->codecpar->codec_id, stream->index);
3032  continue;
3033  }
3034  {
3036  fmt_ctx, stream, codec);
3037 
3038  ist->dec_ctx = avcodec_alloc_context3(codec);
3039  if (!ist->dec_ctx)
3040  exit(1);
3041 
3042  err = avcodec_parameters_to_context(ist->dec_ctx, stream->codecpar);
3043  if (err < 0)
3044  exit(1);
3045 
3046  if (do_show_log) {
3047  // For loging it is needed to disable at least frame threads as otherwise
3048  // the log information would need to be reordered and matches up to contexts and frames
3049  // That is in fact possible but not trivial
3050  av_dict_set(&codec_opts, "threads", "1", 0);
3051  }
3052 
3053  ist->dec_ctx->pkt_timebase = stream->time_base;
3054  ist->dec_ctx->framerate = stream->avg_frame_rate;
3055 #if FF_API_LAVF_AVCTX
3056  ist->dec_ctx->properties = stream->codec->properties;
3057  ist->dec_ctx->coded_width = stream->codec->coded_width;
3058  ist->dec_ctx->coded_height = stream->codec->coded_height;
3059 #endif
3060 
3061  if (avcodec_open2(ist->dec_ctx, codec, &opts) < 0) {
3062  av_log(NULL, AV_LOG_WARNING, "Could not open codec for input stream %d\n",
3063  stream->index);
3064  exit(1);
3065  }
3066 
3067  if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
3068  av_log(NULL, AV_LOG_ERROR, "Option %s for input stream %d not found\n",
3069  t->key, stream->index);
3070  return AVERROR_OPTION_NOT_FOUND;
3071  }
3072  }
3073  }
3074 
3075  ifile->fmt_ctx = fmt_ctx;
3076  return 0;
3077 }
3078 
3080 {
3081  int i;
3082 
3083  /* close decoder for each stream */
3084  for (i = 0; i < ifile->nb_streams; i++)
3085  if (ifile->streams[i].st->codecpar->codec_id != AV_CODEC_ID_NONE)
3086  avcodec_free_context(&ifile->streams[i].dec_ctx);
3087 
3088  av_freep(&ifile->streams);
3089  ifile->nb_streams = 0;
3090 
3091  avformat_close_input(&ifile->fmt_ctx);
3092 }
3093 
3094 static int probe_file(WriterContext *wctx, const char *filename,
3095  const char *print_filename)
3096 {
3097  InputFile ifile = { 0 };
3098  int ret, i;
3099  int section_id;
3100 
3103 
3104  ret = open_input_file(&ifile, filename, print_filename);
3105  if (ret < 0)
3106  goto end;
3107 
3108 #define CHECK_END if (ret < 0) goto end
3109 
3110  nb_streams = ifile.fmt_ctx->nb_streams;
3114 
3115  for (i = 0; i < ifile.fmt_ctx->nb_streams; i++) {
3116  if (stream_specifier) {
3118  ifile.fmt_ctx->streams[i],
3120  CHECK_END;
3121  else
3122  selected_streams[i] = ret;
3123  ret = 0;
3124  } else {
3125  selected_streams[i] = 1;
3126  }
3127  if (!selected_streams[i])
3128  ifile.fmt_ctx->streams[i]->discard = AVDISCARD_ALL;
3129  }
3130 
3134  section_id = SECTION_ID_PACKETS_AND_FRAMES;
3135  else if (do_show_packets && !do_show_frames)
3136  section_id = SECTION_ID_PACKETS;
3137  else // (!do_show_packets && do_show_frames)
3138  section_id = SECTION_ID_FRAMES;
3140  writer_print_section_header(wctx, section_id);
3141  ret = read_packets(wctx, &ifile);
3144  CHECK_END;
3145  }
3146 
3147  if (do_show_programs) {
3148  ret = show_programs(wctx, &ifile);
3149  CHECK_END;
3150  }
3151 
3152  if (do_show_streams) {
3153  ret = show_streams(wctx, &ifile);
3154  CHECK_END;
3155  }
3156  if (do_show_chapters) {
3157  ret = show_chapters(wctx, &ifile);
3158  CHECK_END;
3159  }
3160  if (do_show_format) {
3161  ret = show_format(wctx, &ifile);
3162  CHECK_END;
3163  }
3164 
3165 end:
3166  if (ifile.fmt_ctx)
3167  close_input_file(&ifile);
3171 
3172  return ret;
3173 }
3174 
3175 static void show_usage(void)
3176 {
3177  av_log(NULL, AV_LOG_INFO, "Simple multimedia streams analyzer\n");
3178  av_log(NULL, AV_LOG_INFO, "usage: %s [OPTIONS] [INPUT_FILE]\n", program_name);
3179  av_log(NULL, AV_LOG_INFO, "\n");
3180 }
3181 
3182 static void ffprobe_show_program_version(WriterContext *w)
3183 {
3184  AVBPrint pbuf;
3186 
3188  print_str("version", FFMPEG_VERSION);
3189  print_fmt("copyright", "Copyright (c) %d-%d the FFmpeg developers",
3190  program_birth_year, CONFIG_THIS_YEAR);
3191  print_str("compiler_ident", CC_IDENT);
3192  print_str("configuration", FFMPEG_CONFIGURATION);
3194 
3195  av_bprint_finalize(&pbuf, NULL);
3196 }
3197 
3198 #define SHOW_LIB_VERSION(libname, LIBNAME) \
3199  do { \
3200  if (CONFIG_##LIBNAME) { \
3201  unsigned int version = libname##_version(); \
3202  writer_print_section_header(w, SECTION_ID_LIBRARY_VERSION); \
3203  print_str("name", "lib" #libname); \
3204  print_int("major", LIB##LIBNAME##_VERSION_MAJOR); \
3205  print_int("minor", LIB##LIBNAME##_VERSION_MINOR); \
3206  print_int("micro", LIB##LIBNAME##_VERSION_MICRO); \
3207  print_int("version", version); \
3208  print_str("ident", LIB##LIBNAME##_IDENT); \
3209  writer_print_section_footer(w); \
3210  } \
3211  } while (0)
3212 
3213 static void ffprobe_show_library_versions(WriterContext *w)
3214 {
3216  SHOW_LIB_VERSION(avutil, AVUTIL);
3217  SHOW_LIB_VERSION(avcodec, AVCODEC);
3218  SHOW_LIB_VERSION(avformat, AVFORMAT);
3219  SHOW_LIB_VERSION(avdevice, AVDEVICE);
3220  SHOW_LIB_VERSION(avfilter, AVFILTER);
3221  SHOW_LIB_VERSION(swscale, SWSCALE);
3222  SHOW_LIB_VERSION(swresample, SWRESAMPLE);
3223  SHOW_LIB_VERSION(postproc, POSTPROC);
3225 }
3226 
3227 #define PRINT_PIX_FMT_FLAG(flagname, name) \
3228  do { \
3229  print_int(name, !!(pixdesc->flags & AV_PIX_FMT_FLAG_##flagname)); \
3230  } while (0)
3231 
3232 static void ffprobe_show_pixel_formats(WriterContext *w)
3233 {
3234  const AVPixFmtDescriptor *pixdesc = NULL;
3235  int i, n;
3236 
3238  while (pixdesc = av_pix_fmt_desc_next(pixdesc)) {
3240  print_str("name", pixdesc->name);
3241  print_int("nb_components", pixdesc->nb_components);
3242  if ((pixdesc->nb_components >= 3) && !(pixdesc->flags & AV_PIX_FMT_FLAG_RGB)) {
3243  print_int ("log2_chroma_w", pixdesc->log2_chroma_w);
3244  print_int ("log2_chroma_h", pixdesc->log2_chroma_h);
3245  } else {
3246  print_str_opt("log2_chroma_w", "N/A");
3247  print_str_opt("log2_chroma_h", "N/A");
3248  }
3249  n = av_get_bits_per_pixel(pixdesc);
3250  if (n) print_int ("bits_per_pixel", n);
3251  else print_str_opt("bits_per_pixel", "N/A");
3254  PRINT_PIX_FMT_FLAG(BE, "big_endian");
3255  PRINT_PIX_FMT_FLAG(PAL, "palette");
3256  PRINT_PIX_FMT_FLAG(BITSTREAM, "bitstream");
3257  PRINT_PIX_FMT_FLAG(HWACCEL, "hwaccel");
3258  PRINT_PIX_FMT_FLAG(PLANAR, "planar");
3259  PRINT_PIX_FMT_FLAG(RGB, "rgb");
3260 #if FF_API_PSEUDOPAL
3261  PRINT_PIX_FMT_FLAG(PSEUDOPAL, "pseudopal");
3262 #endif
3263  PRINT_PIX_FMT_FLAG(ALPHA, "alpha");
3265  }
3266  if (do_show_pixel_format_components && (pixdesc->nb_components > 0)) {
3268  for (i = 0; i < pixdesc->nb_components; i++) {
3270  print_int("index", i + 1);
3271  print_int("bit_depth", pixdesc->comp[i].depth);
3273  }
3275  }
3277  }
3279 }
3280 
3281 static int opt_format(void *optctx, const char *opt, const char *arg)
3282 {
3283  iformat = av_find_input_format(arg);
3284  if (!iformat) {
3285  av_log(NULL, AV_LOG_ERROR, "Unknown input format: %s\n", arg);
3286  return AVERROR(EINVAL);
3287  }
3288  return 0;
3289 }
3290 
3291 static inline void mark_section_show_entries(SectionID section_id,
3292  int show_all_entries, AVDictionary *entries)
3293 {
3294  struct section *section = &sections[section_id];
3295 
3297  if (show_all_entries) {
3298  SectionID *id;
3299  for (id = section->children_ids; *id != -1; id++)
3300  mark_section_show_entries(*id, show_all_entries, entries);
3301  } else {
3302  av_dict_copy(&section->entries_to_show, entries, 0);
3303  }
3304 }
3305 
3306 static int match_section(const char *section_name,
3307  int show_all_entries, AVDictionary *entries)
3308 {
3309  int i, ret = 0;
3310 
3311  for (i = 0; i < FF_ARRAY_ELEMS(sections); i++) {
3312  const struct section *section = &sections[i];
3313  if (!strcmp(section_name, section->name) ||
3314  (section->unique_name && !strcmp(section_name, section->unique_name))) {
3316  "'%s' matches section with unique name '%s'\n", section_name,
3317  (char *)av_x_if_null(section->unique_name, section->name));
3318  ret++;
3319  mark_section_show_entries(section->id, show_all_entries, entries);
3320  }
3321  }
3322  return ret;
3323 }
3324 
3325 static int opt_show_entries(void *optctx, const char *opt, const char *arg)
3326 {
3327  const char *p = arg;
3328  int ret = 0;
3329 
3330  while (*p) {
3331  AVDictionary *entries = NULL;
3332  char *section_name = av_get_token(&p, "=:");
3333  int show_all_entries = 0;
3334 
3335  if (!section_name) {
3337  "Missing section name for option '%s'\n", opt);
3338  return AVERROR(EINVAL);
3339  }
3340 
3341  if (*p == '=') {
3342  p++;
3343  while (*p && *p != ':') {
3344  char *entry = av_get_token(&p, ",:");
3345  if (!entry)
3346  break;
3348  "Adding '%s' to the entries to show in section '%s'\n",
3349  entry, section_name);
3350  av_dict_set(&entries, entry, "", AV_DICT_DONT_STRDUP_KEY);
3351  if (*p == ',')
3352  p++;
3353  }
3354  } else {
3355  show_all_entries = 1;
3356  }
3357 
3358  ret = match_section(section_name, show_all_entries, entries);
3359  if (ret == 0) {
3360  av_log(NULL, AV_LOG_ERROR, "No match for section '%s'\n", section_name);
3361  ret = AVERROR(EINVAL);
3362  }
3363  av_dict_free(&entries);
3364  av_free(section_name);
3365 
3366  if (ret <= 0)
3367  break;
3368  if (*p)
3369  p++;
3370  }
3371 
3372  return ret;
3373 }
3374 
3375 static int opt_show_format_entry(void *optctx, const char *opt, const char *arg)
3376 {
3377  char *buf = av_asprintf("format=%s", arg);
3378  int ret;
3379 
3380  if (!buf)
3381  return AVERROR(ENOMEM);
3382 
3384  "Option '%s' is deprecated, use '-show_entries format=%s' instead\n",
3385  opt, arg);
3386  ret = opt_show_entries(optctx, opt, buf);
3387  av_free(buf);
3388  return ret;
3389 }
3390 
3391 static void opt_input_file(void *optctx, const char *arg)
3392 {
3393  if (input_filename) {
3395  "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3396  arg, input_filename);
3397  exit_program(1);
3398  }
3399  if (!strcmp(arg, "-"))
3400  arg = "pipe:";
3401  input_filename = arg;
3402 }
3403 
3404 static int opt_input_file_i(void *optctx, const char *opt, const char *arg)
3405 {
3406  opt_input_file(optctx, arg);
3407  return 0;
3408 }
3409 
3410 static int opt_print_filename(void *optctx, const char *opt, const char *arg)
3411 {
3413  return 0;
3414 }
3415 
3416 void show_help_default(const char *opt, const char *arg)
3417 {
3419  show_usage();
3420  show_help_options(options, "Main options:", 0, 0, 0);
3421  printf("\n");
3422 
3425 }
3426 
3427 /**
3428  * Parse interval specification, according to the format:
3429  * INTERVAL ::= [START|+START_OFFSET][%[END|+END_OFFSET]]
3430  * INTERVALS ::= INTERVAL[,INTERVALS]
3431 */
3432 static int parse_read_interval(const char *interval_spec,
3433  ReadInterval *interval)
3434 {
3435  int ret = 0;
3436  char *next, *p, *spec = av_strdup(interval_spec);
3437  if (!spec)
3438  return AVERROR(ENOMEM);
3439 
3440  if (!*spec) {
3441  av_log(NULL, AV_LOG_ERROR, "Invalid empty interval specification\n");
3442  ret = AVERROR(EINVAL);
3443  goto end;
3444  }
3445 
3446  p = spec;
3447  next = strchr(spec, '%');
3448  if (next)
3449  *next++ = 0;
3450 
3451  /* parse first part */
3452  if (*p) {
3453  interval->has_start = 1;
3454 
3455  if (*p == '+') {
3456  interval->start_is_offset = 1;
3457  p++;
3458  } else {
3459  interval->start_is_offset = 0;
3460  }
3461 
3462  ret = av_parse_time(&interval->start, p, 1);
3463  if (ret < 0) {
3464  av_log(NULL, AV_LOG_ERROR, "Invalid interval start specification '%s'\n", p);
3465  goto end;
3466  }
3467  } else {
3468  interval->has_start = 0;
3469  }
3470 
3471  /* parse second part */
3472  p = next;
3473  if (p && *p) {
3474  int64_t us;
3475  interval->has_end = 1;
3476 
3477  if (*p == '+') {
3478  interval->end_is_offset = 1;
3479  p++;
3480  } else {
3481  interval->end_is_offset = 0;
3482  }
3483 
3484  if (interval->end_is_offset && *p == '#') {
3485  long long int lli;
3486  char *tail;
3487  interval->duration_frames = 1;
3488  p++;
3489  lli = strtoll(p, &tail, 10);
3490  if (*tail || lli < 0) {
3492  "Invalid or negative value '%s' for duration number of frames\n", p);
3493  goto end;
3494  }
3495  interval->end = lli;
3496  } else {
3497  interval->duration_frames = 0;
3498  ret = av_parse_time(&us, p, 1);
3499  if (ret < 0) {
3500  av_log(NULL, AV_LOG_ERROR, "Invalid interval end/duration specification '%s'\n", p);
3501  goto end;
3502  }
3503  interval->end = us;
3504  }
3505  } else {
3506  interval->has_end = 0;
3507  }
3508 
3509 end:
3510  av_free(spec);
3511  return ret;
3512 }
3513 
3514 static int parse_read_intervals(const char *intervals_spec)
3515 {
3516  int ret, n, i;
3517  char *p, *spec = av_strdup(intervals_spec);
3518  if (!spec)
3519  return AVERROR(ENOMEM);
3520 
3521  /* preparse specification, get number of intervals */
3522  for (n = 0, p = spec; *p; p++)
3523  if (*p == ',')
3524  n++;
3525  n++;
3526 
3527  read_intervals = av_malloc_array(n, sizeof(*read_intervals));
3528  if (!read_intervals) {
3529  ret = AVERROR(ENOMEM);
3530  goto end;
3531  }
3532  read_intervals_nb = n;
3533 
3534  /* parse intervals */
3535  p = spec;
3536  for (i = 0; p; i++) {
3537  char *next;
3538 
3540  next = strchr(p, ',');
3541  if (next)
3542  *next++ = 0;
3543 
3544  read_intervals[i].id = i;
3545  ret = parse_read_interval(p, &read_intervals[i]);
3546  if (ret < 0) {
3547  av_log(NULL, AV_LOG_ERROR, "Error parsing read interval #%d '%s'\n",
3548  i, p);
3549  goto end;
3550  }
3551  av_log(NULL, AV_LOG_VERBOSE, "Parsed log interval ");
3552  log_read_interval(&read_intervals[i], NULL, AV_LOG_VERBOSE);
3553  p = next;
3554  }
3556 
3557 end:
3558  av_free(spec);
3559  return ret;
3560 }
3561 
3562 static int opt_read_intervals(void *optctx, const char *opt, const char *arg)
3563 {
3564  return parse_read_intervals(arg);
3565 }
3566 
3567 static int opt_pretty(void *optctx, const char *opt, const char *arg)
3568 {
3569  show_value_unit = 1;
3570  use_value_prefix = 1;
3573  return 0;
3574 }
3575 
3576 static void print_section(SectionID id, int level)
3577 {
3578  const SectionID *pid;
3579  const struct section *section = &sections[id];
3580  printf("%c%c%c",
3581  section->flags & SECTION_FLAG_IS_WRAPPER ? 'W' : '.',
3582  section->flags & SECTION_FLAG_IS_ARRAY ? 'A' : '.',
3583  section->flags & SECTION_FLAG_HAS_VARIABLE_FIELDS ? 'V' : '.');
3584  printf("%*c %s", level * 4, ' ', section->name);
3585  if (section->unique_name)
3586  printf("/%s", section->unique_name);
3587  printf("\n");
3588 
3589  for (pid = section->children_ids; *pid != -1; pid++)
3590  print_section(*pid, level+1);
3591 }
3592 
3593 static int opt_sections(void *optctx, const char *opt, const char *arg)
3594 {
3595  printf("Sections:\n"
3596  "W.. = Section is a wrapper (contains other sections, no local entries)\n"
3597  ".A. = Section contains an array of elements of the same type\n"
3598  "..V = Section may contain a variable number of fields with variable keys\n"
3599  "FLAGS NAME/UNIQUE_NAME\n"
3600  "---\n");
3602  return 0;
3603 }
3604 
3605 static int opt_show_versions(void *optctx, const char *opt, const char *arg)
3606 {
3609  return 0;
3610 }
3611 
3612 #define DEFINE_OPT_SHOW_SECTION(section, target_section_id) \
3613  static int opt_show_##section(void *optctx, const char *opt, const char *arg) \
3614  { \
3615  mark_section_show_entries(SECTION_ID_##target_section_id, 1, NULL); \
3616  return 0; \
3617  }
3618 
3619 DEFINE_OPT_SHOW_SECTION(chapters, CHAPTERS)
3623 DEFINE_OPT_SHOW_SECTION(library_versions, LIBRARY_VERSIONS)
3624 DEFINE_OPT_SHOW_SECTION(packets, PACKETS)
3625 DEFINE_OPT_SHOW_SECTION(pixel_formats, PIXEL_FORMATS)
3626 DEFINE_OPT_SHOW_SECTION(program_version, PROGRAM_VERSION)
3627 DEFINE_OPT_SHOW_SECTION(streams, STREAMS)
3628 DEFINE_OPT_SHOW_SECTION(programs, PROGRAMS)
3629 
3630 static const OptionDef real_options[] = {
3632  { "f", HAS_ARG, {.func_arg = opt_format}, "force format", "format" },
3633  { "unit", OPT_BOOL, {&show_value_unit}, "show unit of the displayed values" },
3634  { "prefix", OPT_BOOL, {&use_value_prefix}, "use SI prefixes for the displayed values" },
3635  { "byte_binary_prefix", OPT_BOOL, {&use_byte_value_binary_prefix},
3636  "use binary prefixes for byte units" },
3637  { "sexagesimal", OPT_BOOL, {&use_value_sexagesimal_format},
3638  "use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" },
3639  { "pretty", 0, {.func_arg = opt_pretty},
3640  "prettify the format of displayed values, make it more human readable" },
3641  { "print_format", OPT_STRING | HAS_ARG, { &print_format },
3642  "set the output printing format (available formats are: default, compact, csv, flat, ini, json, xml)", "format" },
3643  { "of", OPT_STRING | HAS_ARG, { &print_format }, "alias for -print_format", "format" },
3644  { "select_streams", OPT_STRING | HAS_ARG, { &stream_specifier }, "select the specified streams", "stream_specifier" },
3645  { "sections", OPT_EXIT, {.func_arg = opt_sections}, "print sections structure and section information, and exit" },
3646  { "show_data", OPT_BOOL, { &do_show_data }, "show packets data" },
3647  { "show_data_hash", OPT_STRING | HAS_ARG, { &show_data_hash }, "show packets data hash" },
3648  { "show_error", 0, { .func_arg = &opt_show_error }, "show probing error" },
3649  { "show_format", 0, { .func_arg = &opt_show_format }, "show format/container info" },
3650  { "show_frames", 0, { .func_arg = &opt_show_frames }, "show frames info" },
3651  { "show_format_entry", HAS_ARG, {.func_arg = opt_show_format_entry},
3652  "show a particular entry from the format/container info", "entry" },
3653  { "show_entries", HAS_ARG, {.func_arg = opt_show_entries},
3654  "show a set of specified entries", "entry_list" },
3655 #if HAVE_THREADS
3656  { "show_log", OPT_INT|HAS_ARG, { &do_show_log }, "show log" },
3657 #endif
3658  { "show_packets", 0, { .func_arg = &opt_show_packets }, "show packets info" },
3659  { "show_programs", 0, { .func_arg = &opt_show_programs }, "show programs info" },
3660  { "show_streams", 0, { .func_arg = &opt_show_streams }, "show streams info" },
3661  { "show_chapters", 0, { .func_arg = &opt_show_chapters }, "show chapters info" },
3662  { "count_frames", OPT_BOOL, { &do_count_frames }, "count the number of frames per stream" },
3663  { "count_packets", OPT_BOOL, { &do_count_packets }, "count the number of packets per stream" },
3664  { "show_program_version", 0, { .func_arg = &opt_show_program_version }, "show ffprobe version" },
3665  { "show_library_versions", 0, { .func_arg = &opt_show_library_versions }, "show library versions" },
3666  { "show_versions", 0, { .func_arg = &opt_show_versions }, "show program and library versions" },
3667  { "show_pixel_formats", 0, { .func_arg = &opt_show_pixel_formats }, "show pixel format descriptions" },
3668  { "show_private_data", OPT_BOOL, { &show_private_data }, "show private data" },
3669  { "private", OPT_BOOL, { &show_private_data }, "same as show_private_data" },
3670  { "bitexact", OPT_BOOL, {&do_bitexact}, "force bitexact output" },
3671  { "read_intervals", HAS_ARG, {.func_arg = opt_read_intervals}, "set read intervals", "read_intervals" },
3672  { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default}, "generic catch all option", "" },
3673  { "i", HAS_ARG, {.func_arg = opt_input_file_i}, "read specified file", "input_file"},
3674  { "print_filename", HAS_ARG, {.func_arg = opt_print_filename}, "override the printed input filename", "print_file"},
3675  { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
3676  "read and decode the streams to fill missing information with heuristics" },
3677  { NULL, },
3678 };
3679 
3680 static inline int check_section_show_entries(int section_id)
3681 {
3682  int *id;
3683  struct section *section = &sections[section_id];
3684  if (sections[section_id].show_all_entries || sections[section_id].entries_to_show)
3685  return 1;
3686  for (id = section->children_ids; *id != -1; id++)
3687  if (check_section_show_entries(*id))
3688  return 1;
3689  return 0;
3690 }
3691 
3692 #define SET_DO_SHOW(id, varname) do { \
3693  if (check_section_show_entries(SECTION_ID_##id)) \
3694  do_show_##varname = 1; \
3695  } while (0)
3696 
3697 int main(int argc, char **argv)
3698 {
3699  const Writer *w;
3700  WriterContext *wctx;
3701  char *buf;
3702  char *w_name = NULL, *w_args = NULL;
3703  int ret, i;
3704 
3705  init_dynload();
3706 
3707 #if HAVE_THREADS
3708  ret = pthread_mutex_init(&log_mutex, NULL);
3709  if (ret != 0) {
3710  goto end;
3711  }
3712 #endif
3715 
3716  options = real_options;
3717  parse_loglevel(argc, argv, options);
3719  init_opts();
3720 #if CONFIG_AVDEVICE
3722 #endif
3723 
3724  show_banner(argc, argv, options);
3725  parse_options(NULL, argc, argv, options, opt_input_file);
3726 
3727  if (do_show_log)
3729 
3730  /* mark things to show, based on -show_entries */
3731  SET_DO_SHOW(CHAPTERS, chapters);
3733  SET_DO_SHOW(FORMAT, format);
3734  SET_DO_SHOW(FRAMES, frames);
3735  SET_DO_SHOW(LIBRARY_VERSIONS, library_versions);
3736  SET_DO_SHOW(PACKETS, packets);
3737  SET_DO_SHOW(PIXEL_FORMATS, pixel_formats);
3738  SET_DO_SHOW(PIXEL_FORMAT_FLAGS, pixel_format_flags);
3739  SET_DO_SHOW(PIXEL_FORMAT_COMPONENTS, pixel_format_components);
3740  SET_DO_SHOW(PROGRAM_VERSION, program_version);
3741  SET_DO_SHOW(PROGRAMS, programs);
3742  SET_DO_SHOW(STREAMS, streams);
3743  SET_DO_SHOW(STREAM_DISPOSITION, stream_disposition);
3744  SET_DO_SHOW(PROGRAM_STREAM_DISPOSITION, stream_disposition);
3745 
3746  SET_DO_SHOW(CHAPTER_TAGS, chapter_tags);
3747  SET_DO_SHOW(FORMAT_TAGS, format_tags);
3748  SET_DO_SHOW(FRAME_TAGS, frame_tags);
3749  SET_DO_SHOW(PROGRAM_TAGS, program_tags);
3750  SET_DO_SHOW(STREAM_TAGS, stream_tags);
3751  SET_DO_SHOW(PROGRAM_STREAM_TAGS, stream_tags);
3752  SET_DO_SHOW(PACKET_TAGS, packet_tags);
3753 
3756  "-bitexact and -show_program_version or -show_library_versions "
3757  "options are incompatible\n");
3758  ret = AVERROR(EINVAL);
3759  goto end;
3760  }
3761 
3763 
3764  if (!print_format)
3765  print_format = av_strdup("default");
3766  if (!print_format) {
3767  ret = AVERROR(ENOMEM);
3768  goto end;
3769  }
3770  w_name = av_strtok(print_format, "=", &buf);
3771  if (!w_name) {
3773  "No name specified for the output format\n");
3774  ret = AVERROR(EINVAL);
3775  goto end;
3776  }
3777  w_args = buf;
3778 
3779  if (show_data_hash) {
3780  if ((ret = av_hash_alloc(&hash, show_data_hash)) < 0) {
3781  if (ret == AVERROR(EINVAL)) {
3782  const char *n;
3784  "Unknown hash algorithm '%s'\nKnown algorithms:",
3785  show_data_hash);
3786  for (i = 0; (n = av_hash_names(i)); i++)
3787  av_log(NULL, AV_LOG_ERROR, " %s", n);
3788  av_log(NULL, AV_LOG_ERROR, "\n");
3789  }
3790  goto end;
3791  }
3792  }
3793 
3794  w = writer_get_by_name(w_name);
3795  if (!w) {
3796  av_log(NULL, AV_LOG_ERROR, "Unknown output format with name '%s'\n", w_name);
3797  ret = AVERROR(EINVAL);
3798  goto end;
3799  }
3800 
3801  if ((ret = writer_open(&wctx, w, w_args,
3802  sections, FF_ARRAY_ELEMS(sections))) >= 0) {
3803  if (w == &xml_writer)
3805 
3807 
3814 
3815  if (!input_filename &&
3818  show_usage();
3819  av_log(NULL, AV_LOG_ERROR, "You have to specify one input file.\n");
3820  av_log(NULL, AV_LOG_ERROR, "Use -h to get full help or, even better, run 'man %s'.\n", program_name);
3821  ret = AVERROR(EINVAL);
3822  } else if (input_filename) {
3824  if (ret < 0 && do_show_error)
3825  show_error(wctx, ret);
3826  }
3827 
3829  writer_close(&wctx);
3830  }
3831 
3832 end:
3834  av_freep(&read_intervals);
3835  av_hash_freep(&hash);
3836 
3837  uninit_opts();
3838  for (i = 0; i < FF_ARRAY_ELEMS(sections); i++)
3839  av_dict_free(&(sections[i].entries_to_show));
3840 
3842 
3843  return ret < 0;
3844 }
unsigned int nb_chapters
Number of chapters in AVChapter array.
Definition: avformat.h:1468
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:564
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:3410
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
AVRational framerate
Definition: avcodec.h:2064
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:1846
#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:1825
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:3404
static int opt_format(void *optctx, const char *opt, const char *arg)
Definition: ffprobe.c:3281
int within_tag
Definition: ffprobe.c:1628
#define SHOW_LIB_VERSION(libname, LIBNAME)
Definition: ffprobe.c:3198
#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:3375
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...
static const char * xml_escape_str(AVBPrint *dst, const char *src, void *log_ctx)
Definition: ffprobe.c:1675
#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:35
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:2088
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:5074
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:2815
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:881
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:2588
#define us(width, name, range_min, range_max, subs,...)
Definition: cbs_h2645.c:278
#define print_str_opt(k, v)
Definition: ffprobe.c:1822
static int read_packets(WriterContext *w, InputFile *ifile)
Definition: ffprobe.c:2568
int64_t bit_rate
Total stream bitrate in bit/s, 0 if not available.
Definition: avformat.h:1361
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:1185
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:505
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:2692
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.
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:982
static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, AVFormatContext *fmt_ctx)
Definition: ffprobe.c:2228
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:1735
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:3291
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:1003
AVDictionary * metadata
Definition: avformat.h:1200
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
AVDictionary * filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id, AVFormatContext *s, AVStream *st, AVCodec *codec)
Filter out options for given codec.
Definition: cmdutils.c:2105
This struct describes the properties of an encoded stream.
Definition: codec_par.h:52
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:483
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:2966
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:2377
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.
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avcodec.h:654
#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:1239
#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:1161
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:3094
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:1827
#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:543
static int opt_read_intervals(void *optctx, const char *opt, const char *arg)
Definition: ffprobe.c:3562
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:666
#define HAS_ARG
Definition: cmdutils.h:161
static void close_input_file(InputFile *ifile)
Definition: ffprobe.c:3079
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:2899
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:92
int id
unique ID to identify the chapter
Definition: avformat.h:1197
static int show_chapters(WriterContext *w, InputFile *ifile)
Definition: ffprobe.c:2885
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:887
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:5281
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:36
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:986
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:3306
int pmt_pid
Definition: avformat.h:1165
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:1307
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:2187
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:2440
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:413
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:381
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:2832
uint32_t tag
Definition: movenc.c:1597
int avformat_network_init(void)
Do global initialization of network libraries.
Definition: utils.c:5011
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:3680
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:3576
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:504
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:3416
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:1796
static void xml_print_str(WriterContext *wctx, const char *key, const char *value)
Definition: ffprobe.c:1754
int children_ids[SECTION_MAX_NB_CHILDREN+1]
list of children section IDS, terminated by -1
Definition: ffprobe.c:150