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