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\"%s", section->name, json->item_sep);
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 
1583  if (wctx->nb_item[wctx->level])
1584  printf("%s", json->item_sep);
1585  if (!json->compact)
1586  JSON_INDENT();
1587  json_print_item_str(wctx, key, value);
1588 }
1589 
1590 static void json_print_int(WriterContext *wctx, const char *key, long long int value)
1591 {
1592  JSONContext *json = wctx->priv;
1593  AVBPrint buf;
1594 
1595  if (wctx->nb_item[wctx->level])
1596  printf("%s", json->item_sep);
1597  if (!json->compact)
1598  JSON_INDENT();
1599 
1601  printf("\"%s\": %lld", json_escape_str(&buf, key, wctx), value);
1602  av_bprint_finalize(&buf, NULL);
1603 }
1604 
1605 static const Writer json_writer = {
1606  .name = "json",
1607  .priv_size = sizeof(JSONContext),
1608  .init = json_init,
1611  .print_integer = json_print_int,
1612  .print_string = json_print_str,
1614  .priv_class = &json_class,
1615 };
1616 
1617 /* XML output */
1618 
1619 typedef struct XMLContext {
1620  const AVClass *class;
1625 } XMLContext;
1626 
1627 #undef OFFSET
1628 #define OFFSET(x) offsetof(XMLContext, x)
1629 
1630 static const AVOption xml_options[] = {
1631  {"fully_qualified", "specify if the output should be fully qualified", OFFSET(fully_qualified), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
1632  {"q", "specify if the output should be fully qualified", OFFSET(fully_qualified), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
1633  {"xsd_strict", "ensure that the output is XSD compliant", OFFSET(xsd_strict), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
1634  {"x", "ensure that the output is XSD compliant", OFFSET(xsd_strict), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1 },
1635  {NULL},
1636 };
1637 
1638 DEFINE_WRITER_CLASS(xml);
1639 
1640 static av_cold int xml_init(WriterContext *wctx)
1641 {
1642  XMLContext *xml = wctx->priv;
1643 
1644  if (xml->xsd_strict) {
1645  xml->fully_qualified = 1;
1646 #define CHECK_COMPLIANCE(opt, opt_name) \
1647  if (opt) { \
1648  av_log(wctx, AV_LOG_ERROR, \
1649  "XSD-compliant output selected but option '%s' was selected, XML output may be non-compliant.\n" \
1650  "You need to disable such option with '-no%s'\n", opt_name, opt_name); \
1651  return AVERROR(EINVAL); \
1652  }
1653  CHECK_COMPLIANCE(show_private_data, "private");
1656 
1658  av_log(wctx, AV_LOG_ERROR,
1659  "Interleaved frames and packets are not allowed in XSD. "
1660  "Select only one between the -show_frames and the -show_packets options.\n");
1661  return AVERROR(EINVAL);
1662  }
1663  }
1664 
1665  return 0;
1666 }
1667 
1668 static const char *xml_escape_str(AVBPrint *dst, const char *src, void *log_ctx)
1669 {
1670  const char *p;
1671 
1672  for (p = src; *p; p++) {
1673  switch (*p) {
1674  case '&' : av_bprintf(dst, "%s", "&amp;"); break;
1675  case '<' : av_bprintf(dst, "%s", "&lt;"); break;
1676  case '>' : av_bprintf(dst, "%s", "&gt;"); break;
1677  case '"' : av_bprintf(dst, "%s", "&quot;"); break;
1678  case '\'': av_bprintf(dst, "%s", "&apos;"); break;
1679  default: av_bprint_chars(dst, *p, 1);
1680  }
1681  }
1682 
1683  return dst->str;
1684 }
1685 
1686 #define XML_INDENT() printf("%*c", xml->indent_level * 4, ' ')
1687 
1688 static void xml_print_section_header(WriterContext *wctx)
1689 {
1690  XMLContext *xml = wctx->priv;
1691  const struct section *section = wctx->section[wctx->level];
1692  const struct section *parent_section = wctx->level ?
1693  wctx->section[wctx->level-1] : NULL;
1694 
1695  if (wctx->level == 0) {
1696  const char *qual = " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
1697  "xmlns:ffprobe='http://www.ffmpeg.org/schema/ffprobe' "
1698  "xsi:schemaLocation='http://www.ffmpeg.org/schema/ffprobe ffprobe.xsd'";
1699 
1700  printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1701  printf("<%sffprobe%s>\n",
1702  xml->fully_qualified ? "ffprobe:" : "",
1703  xml->fully_qualified ? qual : "");
1704  return;
1705  }
1706 
1707  if (xml->within_tag) {
1708  xml->within_tag = 0;
1709  printf(">\n");
1710  }
1711  if (section->flags & SECTION_FLAG_HAS_VARIABLE_FIELDS) {
1712  xml->indent_level++;
1713  } else {
1714  if (parent_section && (parent_section->flags & SECTION_FLAG_IS_WRAPPER) &&
1715  wctx->level && wctx->nb_item[wctx->level-1])
1716  printf("\n");
1717  xml->indent_level++;
1718 
1719  if (section->flags & SECTION_FLAG_IS_ARRAY) {
1720  XML_INDENT(); printf("<%s>\n", section->name);
1721  } else {
1722  XML_INDENT(); printf("<%s ", section->name);
1723  xml->within_tag = 1;
1724  }
1725  }
1726 }
1727 
1728 static void xml_print_section_footer(WriterContext *wctx)
1729 {
1730  XMLContext *xml = wctx->priv;
1731  const struct section *section = wctx->section[wctx->level];
1732 
1733  if (wctx->level == 0) {
1734  printf("</%sffprobe>\n", xml->fully_qualified ? "ffprobe:" : "");
1735  } else if (xml->within_tag) {
1736  xml->within_tag = 0;
1737  printf("/>\n");
1738  xml->indent_level--;
1739  } else if (section->flags & SECTION_FLAG_HAS_VARIABLE_FIELDS) {
1740  xml->indent_level--;
1741  } else {
1742  XML_INDENT(); printf("</%s>\n", section->name);
1743  xml->indent_level--;
1744  }
1745 }
1746 
1747 static void xml_print_str(WriterContext *wctx, const char *key, const char *value)
1748 {
1749  AVBPrint buf;
1750  XMLContext *xml = wctx->priv;
1751  const struct section *section = wctx->section[wctx->level];
1752 
1754 
1755  if (section->flags & SECTION_FLAG_HAS_VARIABLE_FIELDS) {
1756  XML_INDENT();
1757  printf("<%s key=\"%s\"",
1758  section->element_name, xml_escape_str(&buf, key, wctx));
1759  av_bprint_clear(&buf);
1760  printf(" value=\"%s\"/>\n", xml_escape_str(&buf, value, wctx));
1761  } else {
1762  if (wctx->nb_item[wctx->level])
1763  printf(" ");
1764  printf("%s=\"%s\"", key, xml_escape_str(&buf, value, wctx));
1765  }
1766 
1767  av_bprint_finalize(&buf, NULL);
1768 }
1769 
1770 static void xml_print_int(WriterContext *wctx, const char *key, long long int value)
1771 {
1772  if (wctx->nb_item[wctx->level])
1773  printf(" ");
1774  printf("%s=\"%lld\"", key, value);
1775 }
1776 
1777 static Writer xml_writer = {
1778  .name = "xml",
1779  .priv_size = sizeof(XMLContext),
1780  .init = xml_init,
1783  .print_integer = xml_print_int,
1784  .print_string = xml_print_str,
1786  .priv_class = &xml_class,
1787 };
1788 
1789 static void writer_register_all(void)
1790 {
1791  static int initialized;
1792 
1793  if (initialized)
1794  return;
1795  initialized = 1;
1796 
1797  writer_register(&default_writer);
1798  writer_register(&compact_writer);
1799  writer_register(&csv_writer);
1800  writer_register(&flat_writer);
1801  writer_register(&ini_writer);
1802  writer_register(&json_writer);
1803  writer_register(&xml_writer);
1804 }
1805 
1806 #define print_fmt(k, f, ...) do { \
1807  av_bprint_clear(&pbuf); \
1808  av_bprintf(&pbuf, f, __VA_ARGS__); \
1809  writer_print_string(w, k, pbuf.str, 0); \
1810 } while (0)
1811 
1812 #define print_int(k, v) writer_print_integer(w, k, v)
1813 #define print_q(k, v, s) writer_print_rational(w, k, v, s)
1814 #define print_str(k, v) writer_print_string(w, k, v, 0)
1815 #define print_str_opt(k, v) writer_print_string(w, k, v, PRINT_STRING_OPT)
1816 #define print_str_validate(k, v) writer_print_string(w, k, v, PRINT_STRING_VALIDATE)
1817 #define print_time(k, v, tb) writer_print_time(w, k, v, tb, 0)
1818 #define print_ts(k, v) writer_print_ts(w, k, v, 0)
1819 #define print_duration_time(k, v, tb) writer_print_time(w, k, v, tb, 1)
1820 #define print_duration_ts(k, v) writer_print_ts(w, k, v, 1)
1821 #define print_val(k, v, u) do { \
1822  struct unit_value uv; \
1823  uv.val.i = v; \
1824  uv.unit = u; \
1825  writer_print_string(w, k, value_string(val_str, sizeof(val_str), uv), 0); \
1826 } while (0)
1827 
1828 #define print_section_header(s) writer_print_section_header(w, s)
1829 #define print_section_footer(s) writer_print_section_footer(w, s)
1830 
1831 #define REALLOCZ_ARRAY_STREAM(ptr, cur_n, new_n) \
1832 { \
1833  ret = av_reallocp_array(&(ptr), (new_n), sizeof(*(ptr))); \
1834  if (ret < 0) \
1835  goto end; \
1836  memset( (ptr) + (cur_n), 0, ((new_n) - (cur_n)) * sizeof(*(ptr)) ); \
1837 }
1838 
1839 static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id)
1840 {
1842  int ret = 0;
1843 
1844  if (!tags)
1845  return 0;
1846  writer_print_section_header(w, section_id);
1847 
1848  while ((tag = av_dict_get(tags, "", tag, AV_DICT_IGNORE_SUFFIX))) {
1849  if ((ret = print_str_validate(tag->key, tag->value)) < 0)
1850  break;
1851  }
1853 
1854  return ret;
1855 }
1856 
1857 static void print_pkt_side_data(WriterContext *w,
1858  AVCodecParameters *par,
1859  const AVPacketSideData *side_data,
1860  int nb_side_data,
1861  SectionID id_data_list,
1862  SectionID id_data)
1863 {
1864  int i;
1865 
1866  writer_print_section_header(w, id_data_list);
1867  for (i = 0; i < nb_side_data; i++) {
1868  const AVPacketSideData *sd = &side_data[i];
1869  const char *name = av_packet_side_data_name(sd->type);
1870 
1871  writer_print_section_header(w, id_data);
1872  print_str("side_data_type", name ? name : "unknown");
1873  if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9*4) {
1874  writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1);
1875  print_int("rotation", av_display_rotation_get((int32_t *)sd->data));
1876  } else if (sd->type == AV_PKT_DATA_STEREO3D) {
1877  const AVStereo3D *stereo = (AVStereo3D *)sd->data;
1878  print_str("type", av_stereo3d_type_name(stereo->type));
1879  print_int("inverted", !!(stereo->flags & AV_STEREO3D_FLAG_INVERT));
1880  } else if (sd->type == AV_PKT_DATA_SPHERICAL) {
1881  const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data;
1882  print_str("projection", av_spherical_projection_name(spherical->projection));
1883  if (spherical->projection == AV_SPHERICAL_CUBEMAP) {
1884  print_int("padding", spherical->padding);
1885  } else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) {
1886  size_t l, t, r, b;
1887  av_spherical_tile_bounds(spherical, par->width, par->height,
1888  &l, &t, &r, &b);
1889  print_int("bound_left", l);
1890  print_int("bound_top", t);
1891  print_int("bound_right", r);
1892  print_int("bound_bottom", b);
1893  }
1894 
1895  print_int("yaw", (double) spherical->yaw / (1 << 16));
1896  print_int("pitch", (double) spherical->pitch / (1 << 16));
1897  print_int("roll", (double) spherical->roll / (1 << 16));
1898  } else if (sd->type == AV_PKT_DATA_SKIP_SAMPLES && sd->size == 10) {
1899  print_int("skip_samples", AV_RL32(sd->data));
1900  print_int("discard_padding", AV_RL32(sd->data + 4));
1901  print_int("skip_reason", AV_RL8(sd->data + 8));
1902  print_int("discard_reason", AV_RL8(sd->data + 9));
1903  } else if (sd->type == AV_PKT_DATA_MASTERING_DISPLAY_METADATA) {
1905 
1906  if (metadata->has_primaries) {
1907  print_q("red_x", metadata->display_primaries[0][0], '/');
1908  print_q("red_y", metadata->display_primaries[0][1], '/');
1909  print_q("green_x", metadata->display_primaries[1][0], '/');
1910  print_q("green_y", metadata->display_primaries[1][1], '/');
1911  print_q("blue_x", metadata->display_primaries[2][0], '/');
1912  print_q("blue_y", metadata->display_primaries[2][1], '/');
1913 
1914  print_q("white_point_x", metadata->white_point[0], '/');
1915  print_q("white_point_y", metadata->white_point[1], '/');
1916  }
1917 
1918  if (metadata->has_luminance) {
1919  print_q("min_luminance", metadata->min_luminance, '/');
1920  print_q("max_luminance", metadata->max_luminance, '/');
1921  }
1922  } else if (sd->type == AV_PKT_DATA_CONTENT_LIGHT_LEVEL) {
1924  print_int("max_content", metadata->MaxCLL);
1925  print_int("max_average", metadata->MaxFALL);
1926  }
1928  }
1930 }
1931 
1932 static void print_color_range(WriterContext *w, enum AVColorRange color_range)
1933 {
1934  const char *val = av_color_range_name(color_range);
1935  if (!val || color_range == AVCOL_RANGE_UNSPECIFIED) {
1936  print_str_opt("color_range", "unknown");
1937  } else {
1938  print_str("color_range", val);
1939  }
1940 }
1941 
1942 static void print_color_space(WriterContext *w, enum AVColorSpace color_space)
1943 {
1944  const char *val = av_color_space_name(color_space);
1945  if (!val || color_space == AVCOL_SPC_UNSPECIFIED) {
1946  print_str_opt("color_space", "unknown");
1947  } else {
1948  print_str("color_space", val);
1949  }
1950 }
1951 
1952 static void print_primaries(WriterContext *w, enum AVColorPrimaries color_primaries)
1953 {
1954  const char *val = av_color_primaries_name(color_primaries);
1955  if (!val || color_primaries == AVCOL_PRI_UNSPECIFIED) {
1956  print_str_opt("color_primaries", "unknown");
1957  } else {
1958  print_str("color_primaries", val);
1959  }
1960 }
1961 
1962 static void print_color_trc(WriterContext *w, enum AVColorTransferCharacteristic color_trc)
1963 {
1964  const char *val = av_color_transfer_name(color_trc);
1965  if (!val || color_trc == AVCOL_TRC_UNSPECIFIED) {
1966  print_str_opt("color_transfer", "unknown");
1967  } else {
1968  print_str("color_transfer", val);
1969  }
1970 }
1971 
1972 static void print_chroma_location(WriterContext *w, enum AVChromaLocation chroma_location)
1973 {
1974  const char *val = av_chroma_location_name(chroma_location);
1975  if (!val || chroma_location == AVCHROMA_LOC_UNSPECIFIED) {
1976  print_str_opt("chroma_location", "unspecified");
1977  } else {
1978  print_str("chroma_location", val);
1979  }
1980 }
1981 
1982 
1983 static void clear_log(int need_lock)
1984 {
1985  int i;
1986 
1987  if (need_lock)
1988  pthread_mutex_lock(&log_mutex);
1989  for (i=0; i<log_buffer_size; i++) {
1990  av_freep(&log_buffer[i].context_name);
1991  av_freep(&log_buffer[i].parent_name);
1992  av_freep(&log_buffer[i].log_message);
1993  }
1994  log_buffer_size = 0;
1995  if(need_lock)
1996  pthread_mutex_unlock(&log_mutex);
1997 }
1998 
1999 static int show_log(WriterContext *w, int section_ids, int section_id, int log_level)
2000 {
2001  int i;
2002  pthread_mutex_lock(&log_mutex);
2003  if (!log_buffer_size) {
2004  pthread_mutex_unlock(&log_mutex);
2005  return 0;
2006  }
2007  writer_print_section_header(w, section_ids);
2008 
2009  for (i=0; i<log_buffer_size; i++) {
2010  if (log_buffer[i].log_level <= log_level) {
2011  writer_print_section_header(w, section_id);
2012  print_str("context", log_buffer[i].context_name);
2013  print_int("level", log_buffer[i].log_level);
2014  print_int("category", log_buffer[i].category);
2015  if (log_buffer[i].parent_name) {
2016  print_str("parent_context", log_buffer[i].parent_name);
2017  print_int("parent_category", log_buffer[i].parent_category);
2018  } else {
2019  print_str_opt("parent_context", "N/A");
2020  print_str_opt("parent_category", "N/A");
2021  }
2022  print_str("message", log_buffer[i].log_message);
2024  }
2025  }
2026  clear_log(0);
2027  pthread_mutex_unlock(&log_mutex);
2028 
2030 
2031  return 0;
2032 }
2033 
2034 static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int packet_idx)
2035 {
2036  char val_str[128];
2037  AVStream *st = ifile->streams[pkt->stream_index].st;
2038  AVBPrint pbuf;
2039  const char *s;
2040 
2042 
2044 
2046  if (s) print_str ("codec_type", s);
2047  else print_str_opt("codec_type", "unknown");
2048  print_int("stream_index", pkt->stream_index);
2049  print_ts ("pts", pkt->pts);
2050  print_time("pts_time", pkt->pts, &st->time_base);
2051  print_ts ("dts", pkt->dts);
2052  print_time("dts_time", pkt->dts, &st->time_base);
2053  print_duration_ts("duration", pkt->duration);
2054  print_duration_time("duration_time", pkt->duration, &st->time_base);
2055  print_duration_ts("convergence_duration", pkt->convergence_duration);
2056  print_duration_time("convergence_duration_time", pkt->convergence_duration, &st->time_base);
2057  print_val("size", pkt->size, unit_byte_str);
2058  if (pkt->pos != -1) print_fmt ("pos", "%"PRId64, pkt->pos);
2059  else print_str_opt("pos", "N/A");
2060  print_fmt("flags", "%c%c", pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_',
2061  pkt->flags & AV_PKT_FLAG_DISCARD ? 'D' : '_');
2062 
2063  if (pkt->side_data_elems) {
2064  int size;
2065  const uint8_t *side_metadata;
2066 
2067  side_metadata = av_packet_get_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, &size);
2068  if (side_metadata && size && do_show_packet_tags) {
2069  AVDictionary *dict = NULL;
2070  if (av_packet_unpack_dictionary(side_metadata, size, &dict) >= 0)
2072  av_dict_free(&dict);
2073  }
2074 
2078  }
2079 
2080  if (do_show_data)
2081  writer_print_data(w, "data", pkt->data, pkt->size);
2082  writer_print_data_hash(w, "data_hash", pkt->data, pkt->size);
2084 
2085  av_bprint_finalize(&pbuf, NULL);
2086  fflush(stdout);
2087 }
2088 
2089 static void show_subtitle(WriterContext *w, AVSubtitle *sub, AVStream *stream,
2091 {
2092  AVBPrint pbuf;
2093 
2095 
2097 
2098  print_str ("media_type", "subtitle");
2099  print_ts ("pts", sub->pts);
2100  print_time("pts_time", sub->pts, &AV_TIME_BASE_Q);
2101  print_int ("format", sub->format);
2102  print_int ("start_display_time", sub->start_display_time);
2103  print_int ("end_display_time", sub->end_display_time);
2104  print_int ("num_rects", sub->num_rects);
2105 
2107 
2108  av_bprint_finalize(&pbuf, NULL);
2109  fflush(stdout);
2110 }
2111 
2112 static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
2114 {
2115  AVBPrint pbuf;
2116  char val_str[128];
2117  const char *s;
2118  int i;
2119 
2121 
2123 
2125  if (s) print_str ("media_type", s);
2126  else print_str_opt("media_type", "unknown");
2127  print_int("stream_index", stream->index);
2128  print_int("key_frame", frame->key_frame);
2129  print_ts ("pkt_pts", frame->pts);
2130  print_time("pkt_pts_time", frame->pts, &stream->time_base);
2131  print_ts ("pkt_dts", frame->pkt_dts);
2132  print_time("pkt_dts_time", frame->pkt_dts, &stream->time_base);
2133  print_ts ("best_effort_timestamp", frame->best_effort_timestamp);
2134  print_time("best_effort_timestamp_time", frame->best_effort_timestamp, &stream->time_base);
2135  print_duration_ts ("pkt_duration", frame->pkt_duration);
2136  print_duration_time("pkt_duration_time", frame->pkt_duration, &stream->time_base);
2137  if (frame->pkt_pos != -1) print_fmt ("pkt_pos", "%"PRId64, frame->pkt_pos);
2138  else print_str_opt("pkt_pos", "N/A");
2139  if (frame->pkt_size != -1) print_val ("pkt_size", frame->pkt_size, unit_byte_str);
2140  else print_str_opt("pkt_size", "N/A");
2141 
2142  switch (stream->codecpar->codec_type) {
2143  AVRational sar;
2144 
2145  case AVMEDIA_TYPE_VIDEO:
2146  print_int("width", frame->width);
2147  print_int("height", frame->height);
2148  s = av_get_pix_fmt_name(frame->format);
2149  if (s) print_str ("pix_fmt", s);
2150  else print_str_opt("pix_fmt", "unknown");
2151  sar = av_guess_sample_aspect_ratio(fmt_ctx, stream, frame);
2152  if (sar.num) {
2153  print_q("sample_aspect_ratio", sar, ':');
2154  } else {
2155  print_str_opt("sample_aspect_ratio", "N/A");
2156  }
2157  print_fmt("pict_type", "%c", av_get_picture_type_char(frame->pict_type));
2158  print_int("coded_picture_number", frame->coded_picture_number);
2159  print_int("display_picture_number", frame->display_picture_number);
2160  print_int("interlaced_frame", frame->interlaced_frame);
2161  print_int("top_field_first", frame->top_field_first);
2162  print_int("repeat_pict", frame->repeat_pict);
2163 
2164  print_color_range(w, frame->color_range);
2165  print_color_space(w, frame->colorspace);
2166  print_primaries(w, frame->color_primaries);
2167  print_color_trc(w, frame->color_trc);
2169  break;
2170 
2171  case AVMEDIA_TYPE_AUDIO:
2172  s = av_get_sample_fmt_name(frame->format);
2173  if (s) print_str ("sample_fmt", s);
2174  else print_str_opt("sample_fmt", "unknown");
2175  print_int("nb_samples", frame->nb_samples);
2176  print_int("channels", frame->channels);
2177  if (frame->channel_layout) {
2178  av_bprint_clear(&pbuf);
2179  av_bprint_channel_layout(&pbuf, frame->channels,
2180  frame->channel_layout);
2181  print_str ("channel_layout", pbuf.str);
2182  } else
2183  print_str_opt("channel_layout", "unknown");
2184  break;
2185  }
2186  if (do_show_frame_tags)
2188  if (do_show_log)
2190  if (frame->nb_side_data) {
2192  for (i = 0; i < frame->nb_side_data; i++) {
2193  AVFrameSideData *sd = frame->side_data[i];
2194  const char *name;
2195 
2197  name = av_frame_side_data_name(sd->type);
2198  print_str("side_data_type", name ? name : "unknown");
2199  if (sd->type == AV_FRAME_DATA_DISPLAYMATRIX && sd->size >= 9*4) {
2200  writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1);
2201  print_int("rotation", av_display_rotation_get((int32_t *)sd->data));
2202  } else if (sd->type == AV_FRAME_DATA_GOP_TIMECODE && sd->size >= 8) {
2203  char tcbuf[AV_TIMECODE_STR_SIZE];
2204  av_timecode_make_mpeg_tc_string(tcbuf, *(int64_t *)(sd->data));
2205  print_str("timecode", tcbuf);
2206  } else if (sd->type == AV_FRAME_DATA_S12M_TIMECODE && sd->size == 16) {
2207  uint32_t *tc = (uint32_t*)sd->data;
2208  int m = FFMIN(tc[0],3);
2210  for (int j = 1; j <= m ; j++) {
2211  char tcbuf[AV_TIMECODE_STR_SIZE];
2212  av_timecode_make_smpte_tc_string(tcbuf, tc[j], 0);
2214  print_str("value", tcbuf);
2216  }
2218  } else if (sd->type == AV_FRAME_DATA_MASTERING_DISPLAY_METADATA) {
2220 
2221  if (metadata->has_primaries) {
2222  print_q("red_x", metadata->display_primaries[0][0], '/');
2223  print_q("red_y", metadata->display_primaries[0][1], '/');
2224  print_q("green_x", metadata->display_primaries[1][0], '/');
2225  print_q("green_y", metadata->display_primaries[1][1], '/');
2226  print_q("blue_x", metadata->display_primaries[2][0], '/');
2227  print_q("blue_y", metadata->display_primaries[2][1], '/');
2228 
2229  print_q("white_point_x", metadata->white_point[0], '/');
2230  print_q("white_point_y", metadata->white_point[1], '/');
2231  }
2232 
2233  if (metadata->has_luminance) {
2234  print_q("min_luminance", metadata->min_luminance, '/');
2235  print_q("max_luminance", metadata->max_luminance, '/');
2236  }
2237  } else if (sd->type == AV_FRAME_DATA_CONTENT_LIGHT_LEVEL) {
2239  print_int("max_content", metadata->MaxCLL);
2240  print_int("max_average", metadata->MaxFALL);
2241  } else if (sd->type == AV_FRAME_DATA_ICC_PROFILE) {
2243  if (tag)
2244  print_str(tag->key, tag->value);
2245  print_int("size", sd->size);
2246  }
2248  }
2250  }
2251 
2253 
2254  av_bprint_finalize(&pbuf, NULL);
2255  fflush(stdout);
2256 }
2257 
2258 static av_always_inline int process_frame(WriterContext *w,
2259  InputFile *ifile,
2261  int *packet_new)
2262 {
2263  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2265  AVCodecParameters *par = ifile->streams[pkt->stream_index].st->codecpar;
2266  AVSubtitle sub;
2267  int ret = 0, got_frame = 0;
2268 
2269  clear_log(1);
2270  if (dec_ctx && dec_ctx->codec) {
2271  switch (par->codec_type) {
2272  case AVMEDIA_TYPE_VIDEO:
2273  case AVMEDIA_TYPE_AUDIO:
2274  if (*packet_new) {
2275  ret = avcodec_send_packet(dec_ctx, pkt);
2276  if (ret == AVERROR(EAGAIN)) {
2277  ret = 0;
2278  } else if (ret >= 0 || ret == AVERROR_EOF) {
2279  ret = 0;
2280  *packet_new = 0;
2281  }
2282  }
2283  if (ret >= 0) {
2284  ret = avcodec_receive_frame(dec_ctx, frame);
2285  if (ret >= 0) {
2286  got_frame = 1;
2287  } else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
2288  ret = 0;
2289  }
2290  }
2291  break;
2292 
2293  case AVMEDIA_TYPE_SUBTITLE:
2294  if (*packet_new)
2295  ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_frame, pkt);
2296  *packet_new = 0;
2297  break;
2298  default:
2299  *packet_new = 0;
2300  }
2301  } else {
2302  *packet_new = 0;
2303  }
2304 
2305  if (ret < 0)
2306  return ret;
2307  if (got_frame) {
2308  int is_sub = (par->codec_type == AVMEDIA_TYPE_SUBTITLE);
2310  if (do_show_frames)
2311  if (is_sub)
2312  show_subtitle(w, &sub, ifile->streams[pkt->stream_index].st, fmt_ctx);
2313  else
2314  show_frame(w, frame, ifile->streams[pkt->stream_index].st, fmt_ctx);
2315  if (is_sub)
2316  avsubtitle_free(&sub);
2317  }
2318  return got_frame || *packet_new;
2319 }
2320 
2321 static void log_read_interval(const ReadInterval *interval, void *log_ctx, int log_level)
2322 {
2323  av_log(log_ctx, log_level, "id:%d", interval->id);
2324 
2325  if (interval->has_start) {
2326  av_log(log_ctx, log_level, " start:%s%s", interval->start_is_offset ? "+" : "",
2327  av_ts2timestr(interval->start, &AV_TIME_BASE_Q));
2328  } else {
2329  av_log(log_ctx, log_level, " start:N/A");
2330  }
2331 
2332  if (interval->has_end) {
2333  av_log(log_ctx, log_level, " end:%s", interval->end_is_offset ? "+" : "");
2334  if (interval->duration_frames)
2335  av_log(log_ctx, log_level, "#%"PRId64, interval->end);
2336  else
2337  av_log(log_ctx, log_level, "%s", av_ts2timestr(interval->end, &AV_TIME_BASE_Q));
2338  } else {
2339  av_log(log_ctx, log_level, " end:N/A");
2340  }
2341 
2342  av_log(log_ctx, log_level, "\n");
2343 }
2344 
2345 static int read_interval_packets(WriterContext *w, InputFile *ifile,
2346  const ReadInterval *interval, int64_t *cur_ts)
2347 {
2348  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2349  AVPacket pkt;
2350  AVFrame *frame = NULL;
2351  int ret = 0, i = 0, frame_count = 0;
2352  int64_t start = -INT64_MAX, end = interval->end;
2353  int has_start = 0, has_end = interval->has_end && !interval->end_is_offset;
2354 
2355  av_init_packet(&pkt);
2356 
2357  av_log(NULL, AV_LOG_VERBOSE, "Processing read interval ");
2359 
2360  if (interval->has_start) {
2361  int64_t target;
2362  if (interval->start_is_offset) {
2363  if (*cur_ts == AV_NOPTS_VALUE) {
2365  "Could not seek to relative position since current "
2366  "timestamp is not defined\n");
2367  ret = AVERROR(EINVAL);
2368  goto end;
2369  }
2370  target = *cur_ts + interval->start;
2371  } else {
2372  target = interval->start;
2373  }
2374 
2375  av_log(NULL, AV_LOG_VERBOSE, "Seeking to read interval start point %s\n",
2376  av_ts2timestr(target, &AV_TIME_BASE_Q));
2377  if ((ret = avformat_seek_file(fmt_ctx, -1, -INT64_MAX, target, INT64_MAX, 0)) < 0) {
2378  av_log(NULL, AV_LOG_ERROR, "Could not seek to position %"PRId64": %s\n",
2379  interval->start, av_err2str(ret));
2380  goto end;
2381  }
2382  }
2383 
2384  frame = av_frame_alloc();
2385  if (!frame) {
2386  ret = AVERROR(ENOMEM);
2387  goto end;
2388  }
2389  while (!av_read_frame(fmt_ctx, &pkt)) {
2390  if (fmt_ctx->nb_streams > nb_streams) {
2394  nb_streams = fmt_ctx->nb_streams;
2395  }
2396  if (selected_streams[pkt.stream_index]) {
2397  AVRational tb = ifile->streams[pkt.stream_index].st->time_base;
2398 
2399  if (pkt.pts != AV_NOPTS_VALUE)
2400  *cur_ts = av_rescale_q(pkt.pts, tb, AV_TIME_BASE_Q);
2401 
2402  if (!has_start && *cur_ts != AV_NOPTS_VALUE) {
2403  start = *cur_ts;
2404  has_start = 1;
2405  }
2406 
2407  if (has_start && !has_end && interval->end_is_offset) {
2408  end = start + interval->end;
2409  has_end = 1;
2410  }
2411 
2412  if (interval->end_is_offset && interval->duration_frames) {
2413  if (frame_count >= interval->end)
2414  break;
2415  } else if (has_end && *cur_ts != AV_NOPTS_VALUE && *cur_ts >= end) {
2416  break;
2417  }
2418 
2419  frame_count++;
2420  if (do_read_packets) {
2421  if (do_show_packets)
2422  show_packet(w, ifile, &pkt, i++);
2424  }
2425  if (do_read_frames) {
2426  int packet_new = 1;
2427  while (process_frame(w, ifile, frame, &pkt, &packet_new) > 0);
2428  }
2429  }
2430  av_packet_unref(&pkt);
2431  }
2432  av_packet_unref(&pkt);
2433  //Flush remaining frames that are cached in the decoder
2434  for (i = 0; i < fmt_ctx->nb_streams; i++) {
2435  pkt.stream_index = i;
2436  if (do_read_frames)
2437  while (process_frame(w, ifile, frame, &pkt, &(int){1}) > 0);
2438  }
2439 
2440 end:
2441  av_frame_free(&frame);
2442  if (ret < 0) {
2443  av_log(NULL, AV_LOG_ERROR, "Could not read packets in interval ");
2444  log_read_interval(interval, NULL, AV_LOG_ERROR);
2445  }
2446  return ret;
2447 }
2448 
2449 static int read_packets(WriterContext *w, InputFile *ifile)
2450 {
2451  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2452  int i, ret = 0;
2453  int64_t cur_ts = fmt_ctx->start_time;
2454 
2455  if (read_intervals_nb == 0) {
2456  ReadInterval interval = (ReadInterval) { .has_start = 0, .has_end = 0 };
2457  ret = read_interval_packets(w, ifile, &interval, &cur_ts);
2458  } else {
2459  for (i = 0; i < read_intervals_nb; i++) {
2460  ret = read_interval_packets(w, ifile, &read_intervals[i], &cur_ts);
2461  if (ret < 0)
2462  break;
2463  }
2464  }
2465 
2466  return ret;
2467 }
2468 
2469 static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx, InputStream *ist, int in_program)
2470 {
2471  AVStream *stream = ist->st;
2472  AVCodecParameters *par;
2474  char val_str[128];
2475  const char *s;
2476  AVRational sar, dar;
2477  AVBPrint pbuf;
2478  const AVCodecDescriptor *cd;
2479  int ret = 0;
2480  const char *profile = NULL;
2481 
2483 
2485 
2486  print_int("index", stream->index);
2487 
2488  par = stream->codecpar;
2489  dec_ctx = ist->dec_ctx;
2490  if (cd = avcodec_descriptor_get(par->codec_id)) {
2491  print_str("codec_name", cd->name);
2492  if (!do_bitexact) {
2493  print_str("codec_long_name",
2494  cd->long_name ? cd->long_name : "unknown");
2495  }
2496  } else {
2497  print_str_opt("codec_name", "unknown");
2498  if (!do_bitexact) {
2499  print_str_opt("codec_long_name", "unknown");
2500  }
2501  }
2502 
2503  if (!do_bitexact && (profile = avcodec_profile_name(par->codec_id, par->profile)))
2504  print_str("profile", profile);
2505  else {
2506  if (par->profile != FF_PROFILE_UNKNOWN) {
2507  char profile_num[12];
2508  snprintf(profile_num, sizeof(profile_num), "%d", par->profile);
2509  print_str("profile", profile_num);
2510  } else
2511  print_str_opt("profile", "unknown");
2512  }
2513 
2515  if (s) print_str ("codec_type", s);
2516  else print_str_opt("codec_type", "unknown");
2517 #if FF_API_LAVF_AVCTX
2518  if (dec_ctx)
2519  print_q("codec_time_base", dec_ctx->time_base, '/');
2520 #endif
2521 
2522  /* print AVI/FourCC tag */
2523  print_str("codec_tag_string", av_fourcc2str(par->codec_tag));
2524  print_fmt("codec_tag", "0x%04"PRIx32, par->codec_tag);
2525 
2526  switch (par->codec_type) {
2527  case AVMEDIA_TYPE_VIDEO:
2528  print_int("width", par->width);
2529  print_int("height", par->height);
2530 #if FF_API_LAVF_AVCTX
2531  if (dec_ctx) {
2532  print_int("coded_width", dec_ctx->coded_width);
2533  print_int("coded_height", dec_ctx->coded_height);
2534  }
2535 #endif
2536  print_int("has_b_frames", par->video_delay);
2537  sar = av_guess_sample_aspect_ratio(fmt_ctx, stream, NULL);
2538  if (sar.num) {
2539  print_q("sample_aspect_ratio", sar, ':');
2540  av_reduce(&dar.num, &dar.den,
2541  par->width * sar.num,
2542  par->height * sar.den,
2543  1024*1024);
2544  print_q("display_aspect_ratio", dar, ':');
2545  } else {
2546  print_str_opt("sample_aspect_ratio", "N/A");
2547  print_str_opt("display_aspect_ratio", "N/A");
2548  }
2549  s = av_get_pix_fmt_name(par->format);
2550  if (s) print_str ("pix_fmt", s);
2551  else print_str_opt("pix_fmt", "unknown");
2552  print_int("level", par->level);
2553 
2554  print_color_range(w, par->color_range);
2555  print_color_space(w, par->color_space);
2556  print_color_trc(w, par->color_trc);
2559 
2560  if (par->field_order == AV_FIELD_PROGRESSIVE)
2561  print_str("field_order", "progressive");
2562  else if (par->field_order == AV_FIELD_TT)
2563  print_str("field_order", "tt");
2564  else if (par->field_order == AV_FIELD_BB)
2565  print_str("field_order", "bb");
2566  else if (par->field_order == AV_FIELD_TB)
2567  print_str("field_order", "tb");
2568  else if (par->field_order == AV_FIELD_BT)
2569  print_str("field_order", "bt");
2570  else
2571  print_str_opt("field_order", "unknown");
2572 
2573 #if FF_API_PRIVATE_OPT
2574  if (dec_ctx && dec_ctx->timecode_frame_start >= 0) {
2575  char tcbuf[AV_TIMECODE_STR_SIZE];
2577  print_str("timecode", tcbuf);
2578  } else {
2579  print_str_opt("timecode", "N/A");
2580  }
2581 #endif
2582  if (dec_ctx)
2583  print_int("refs", dec_ctx->refs);
2584  break;
2585 
2586  case AVMEDIA_TYPE_AUDIO:
2587  s = av_get_sample_fmt_name(par->format);
2588  if (s) print_str ("sample_fmt", s);
2589  else print_str_opt("sample_fmt", "unknown");
2590  print_val("sample_rate", par->sample_rate, unit_hertz_str);
2591  print_int("channels", par->channels);
2592 
2593  if (par->channel_layout) {
2594  av_bprint_clear(&pbuf);
2596  print_str ("channel_layout", pbuf.str);
2597  } else {
2598  print_str_opt("channel_layout", "unknown");
2599  }
2600 
2601  print_int("bits_per_sample", av_get_bits_per_sample(par->codec_id));
2602  break;
2603 
2604  case AVMEDIA_TYPE_SUBTITLE:
2605  if (par->width)
2606  print_int("width", par->width);
2607  else
2608  print_str_opt("width", "N/A");
2609  if (par->height)
2610  print_int("height", par->height);
2611  else
2612  print_str_opt("height", "N/A");
2613  break;
2614  }
2615 
2616  if (dec_ctx && dec_ctx->codec && dec_ctx->codec->priv_class && show_private_data) {
2617  const AVOption *opt = NULL;
2618  while (opt = av_opt_next(dec_ctx->priv_data,opt)) {
2619  uint8_t *str;
2620  if (opt->flags) continue;
2621  if (av_opt_get(dec_ctx->priv_data, opt->name, 0, &str) >= 0) {
2622  print_str(opt->name, str);
2623  av_free(str);
2624  }
2625  }
2626  }
2627 
2628  if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS) print_fmt ("id", "0x%x", stream->id);
2629  else print_str_opt("id", "N/A");
2630  print_q("r_frame_rate", stream->r_frame_rate, '/');
2631  print_q("avg_frame_rate", stream->avg_frame_rate, '/');
2632  print_q("time_base", stream->time_base, '/');
2633  print_ts ("start_pts", stream->start_time);
2634  print_time("start_time", stream->start_time, &stream->time_base);
2635  print_ts ("duration_ts", stream->duration);
2636  print_time("duration", stream->duration, &stream->time_base);
2637  if (par->bit_rate > 0) print_val ("bit_rate", par->bit_rate, unit_bit_per_second_str);
2638  else print_str_opt("bit_rate", "N/A");
2639 #if FF_API_LAVF_AVCTX
2640  if (stream->codec->rc_max_rate > 0) print_val ("max_bit_rate", stream->codec->rc_max_rate, unit_bit_per_second_str);
2641  else print_str_opt("max_bit_rate", "N/A");
2642 #endif
2643  if (dec_ctx && dec_ctx->bits_per_raw_sample > 0) print_fmt("bits_per_raw_sample", "%d", dec_ctx->bits_per_raw_sample);
2644  else print_str_opt("bits_per_raw_sample", "N/A");
2645  if (stream->nb_frames) print_fmt ("nb_frames", "%"PRId64, stream->nb_frames);
2646  else print_str_opt("nb_frames", "N/A");
2647  if (nb_streams_frames[stream_idx]) print_fmt ("nb_read_frames", "%"PRIu64, nb_streams_frames[stream_idx]);
2648  else print_str_opt("nb_read_frames", "N/A");
2649  if (nb_streams_packets[stream_idx]) print_fmt ("nb_read_packets", "%"PRIu64, nb_streams_packets[stream_idx]);
2650  else print_str_opt("nb_read_packets", "N/A");
2651  if (do_show_data)
2652  writer_print_data(w, "extradata", par->extradata,
2653  par->extradata_size);
2654  writer_print_data_hash(w, "extradata_hash", par->extradata,
2655  par->extradata_size);
2656 
2657  /* Print disposition information */
2658 #define PRINT_DISPOSITION(flagname, name) do { \
2659  print_int(name, !!(stream->disposition & AV_DISPOSITION_##flagname)); \
2660  } while (0)
2661 
2664  PRINT_DISPOSITION(DEFAULT, "default");
2665  PRINT_DISPOSITION(DUB, "dub");
2666  PRINT_DISPOSITION(ORIGINAL, "original");
2667  PRINT_DISPOSITION(COMMENT, "comment");
2668  PRINT_DISPOSITION(LYRICS, "lyrics");
2669  PRINT_DISPOSITION(KARAOKE, "karaoke");
2670  PRINT_DISPOSITION(FORCED, "forced");
2671  PRINT_DISPOSITION(HEARING_IMPAIRED, "hearing_impaired");
2672  PRINT_DISPOSITION(VISUAL_IMPAIRED, "visual_impaired");
2673  PRINT_DISPOSITION(CLEAN_EFFECTS, "clean_effects");
2674  PRINT_DISPOSITION(ATTACHED_PIC, "attached_pic");
2675  PRINT_DISPOSITION(TIMED_THUMBNAILS, "timed_thumbnails");
2677  }
2678 
2679  if (do_show_stream_tags)
2680  ret = show_tags(w, stream->metadata, in_program ? SECTION_ID_PROGRAM_STREAM_TAGS : SECTION_ID_STREAM_TAGS);
2681 
2682  if (stream->nb_side_data) {
2683  print_pkt_side_data(w, stream->codecpar, stream->side_data, stream->nb_side_data,
2686  }
2687 
2689  av_bprint_finalize(&pbuf, NULL);
2690  fflush(stdout);
2691 
2692  return ret;
2693 }
2694 
2695 static int show_streams(WriterContext *w, InputFile *ifile)
2696 {
2697  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2698  int i, ret = 0;
2699 
2701  for (i = 0; i < ifile->nb_streams; i++)
2702  if (selected_streams[i]) {
2703  ret = show_stream(w, fmt_ctx, i, &ifile->streams[i], 0);
2704  if (ret < 0)
2705  break;
2706  }
2708 
2709  return ret;
2710 }
2711 
2712 static int show_program(WriterContext *w, InputFile *ifile, AVProgram *program)
2713 {
2714  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2715  int i, ret = 0;
2716 
2718  print_int("program_id", program->id);
2719  print_int("program_num", program->program_num);
2720  print_int("nb_streams", program->nb_stream_indexes);
2721  print_int("pmt_pid", program->pmt_pid);
2722  print_int("pcr_pid", program->pcr_pid);
2723  print_ts("start_pts", program->start_time);
2724  print_time("start_time", program->start_time, &AV_TIME_BASE_Q);
2725  print_ts("end_pts", program->end_time);
2726  print_time("end_time", program->end_time, &AV_TIME_BASE_Q);
2728  ret = show_tags(w, program->metadata, SECTION_ID_PROGRAM_TAGS);
2729  if (ret < 0)
2730  goto end;
2731 
2733  for (i = 0; i < program->nb_stream_indexes; i++) {
2734  if (selected_streams[program->stream_index[i]]) {
2735  ret = show_stream(w, fmt_ctx, program->stream_index[i], &ifile->streams[program->stream_index[i]], 1);
2736  if (ret < 0)
2737  break;
2738  }
2739  }
2741 
2742 end:
2744  return ret;
2745 }
2746 
2747 static int show_programs(WriterContext *w, InputFile *ifile)
2748 {
2749  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2750  int i, ret = 0;
2751 
2753  for (i = 0; i < fmt_ctx->nb_programs; i++) {
2754  AVProgram *program = fmt_ctx->programs[i];
2755  if (!program)
2756  continue;
2757  ret = show_program(w, ifile, program);
2758  if (ret < 0)
2759  break;
2760  }
2762  return ret;
2763 }
2764 
2765 static int show_chapters(WriterContext *w, InputFile *ifile)
2766 {
2767  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2768  int i, ret = 0;
2769 
2771  for (i = 0; i < fmt_ctx->nb_chapters; i++) {
2772  AVChapter *chapter = fmt_ctx->chapters[i];
2773 
2775  print_int("id", chapter->id);
2776  print_q ("time_base", chapter->time_base, '/');
2777  print_int("start", chapter->start);
2778  print_time("start_time", chapter->start, &chapter->time_base);
2779  print_int("end", chapter->end);
2780  print_time("end_time", chapter->end, &chapter->time_base);
2782  ret = show_tags(w, chapter->metadata, SECTION_ID_CHAPTER_TAGS);
2784  }
2786 
2787  return ret;
2788 }
2789 
2790 static int show_format(WriterContext *w, InputFile *ifile)
2791 {
2792  AVFormatContext *fmt_ctx = ifile->fmt_ctx;
2793  char val_str[128];
2794  int64_t size = fmt_ctx->pb ? avio_size(fmt_ctx->pb) : -1;
2795  int ret = 0;
2796 
2798  print_str_validate("filename", fmt_ctx->url);
2799  print_int("nb_streams", fmt_ctx->nb_streams);
2800  print_int("nb_programs", fmt_ctx->nb_programs);
2801  print_str("format_name", fmt_ctx->iformat->name);
2802  if (!do_bitexact) {
2803  if (fmt_ctx->iformat->long_name) print_str ("format_long_name", fmt_ctx->iformat->long_name);
2804  else print_str_opt("format_long_name", "unknown");
2805  }
2806  print_time("start_time", fmt_ctx->start_time, &AV_TIME_BASE_Q);
2807  print_time("duration", fmt_ctx->duration, &AV_TIME_BASE_Q);
2808  if (size >= 0) print_val ("size", size, unit_byte_str);
2809  else print_str_opt("size", "N/A");
2810  if (fmt_ctx->bit_rate > 0) print_val ("bit_rate", fmt_ctx->bit_rate, unit_bit_per_second_str);
2811  else print_str_opt("bit_rate", "N/A");
2812  print_int("probe_score", fmt_ctx->probe_score);
2813  if (do_show_format_tags)
2814  ret = show_tags(w, fmt_ctx->metadata, SECTION_ID_FORMAT_TAGS);
2815 
2817  fflush(stdout);
2818  return ret;
2819 }
2820 
2821 static void show_error(WriterContext *w, int err)
2822 {
2823  char errbuf[128];
2824  const char *errbuf_ptr = errbuf;
2825 
2826  if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
2827  errbuf_ptr = strerror(AVUNERROR(err));
2828 
2830  print_int("code", err);
2831  print_str("string", errbuf_ptr);
2833 }
2834 
2835 static int open_input_file(InputFile *ifile, const char *filename)
2836 {
2837  int err, i;
2839  AVDictionaryEntry *t;
2840  int scan_all_pmts_set = 0;
2841 
2842  fmt_ctx = avformat_alloc_context();
2843  if (!fmt_ctx) {
2844  print_error(filename, AVERROR(ENOMEM));
2845  exit_program(1);
2846  }
2847 
2848  if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
2849  av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
2850  scan_all_pmts_set = 1;
2851  }
2852  if ((err = avformat_open_input(&fmt_ctx, filename,
2853  iformat, &format_opts)) < 0) {
2854  print_error(filename, err);
2855  return err;
2856  }
2857  ifile->fmt_ctx = fmt_ctx;
2858  if (scan_all_pmts_set)
2859  av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
2861  av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
2862  return AVERROR_OPTION_NOT_FOUND;
2863  }
2864 
2865  if (find_stream_info) {
2867  int orig_nb_streams = fmt_ctx->nb_streams;
2868 
2869  err = avformat_find_stream_info(fmt_ctx, opts);
2870 
2871  for (i = 0; i < orig_nb_streams; i++)
2872  av_dict_free(&opts[i]);
2873  av_freep(&opts);
2874 
2875  if (err < 0) {
2876  print_error(filename, err);
2877  return err;
2878  }
2879  }
2880 
2881  av_dump_format(fmt_ctx, 0, filename, 0);
2882 
2883  ifile->streams = av_mallocz_array(fmt_ctx->nb_streams,
2884  sizeof(*ifile->streams));
2885  if (!ifile->streams)
2886  exit(1);
2887  ifile->nb_streams = fmt_ctx->nb_streams;
2888 
2889  /* bind a decoder to each input stream */
2890  for (i = 0; i < fmt_ctx->nb_streams; i++) {
2891  InputStream *ist = &ifile->streams[i];
2892  AVStream *stream = fmt_ctx->streams[i];
2893  AVCodec *codec;
2894 
2895  ist->st = stream;
2896 
2897  if (stream->codecpar->codec_id == AV_CODEC_ID_PROBE) {
2899  "Failed to probe codec for input stream %d\n",
2900  stream->index);
2901  continue;
2902  }
2903 
2904  codec = avcodec_find_decoder(stream->codecpar->codec_id);
2905  if (!codec) {
2907  "Unsupported codec with id %d for input stream %d\n",
2908  stream->codecpar->codec_id, stream->index);
2909  continue;
2910  }
2911  {
2913  fmt_ctx, stream, codec);
2914 
2915  ist->dec_ctx = avcodec_alloc_context3(codec);
2916  if (!ist->dec_ctx)
2917  exit(1);
2918 
2919  err = avcodec_parameters_to_context(ist->dec_ctx, stream->codecpar);
2920  if (err < 0)
2921  exit(1);
2922 
2923  if (do_show_log) {
2924  // For loging it is needed to disable at least frame threads as otherwise
2925  // the log information would need to be reordered and matches up to contexts and frames
2926  // That is in fact possible but not trivial
2927  av_dict_set(&codec_opts, "threads", "1", 0);
2928  }
2929 
2930  ist->dec_ctx->pkt_timebase = stream->time_base;
2931  ist->dec_ctx->framerate = stream->avg_frame_rate;
2932 #if FF_API_LAVF_AVCTX
2933  ist->dec_ctx->coded_width = stream->codec->coded_width;
2934  ist->dec_ctx->coded_height = stream->codec->coded_height;
2935 #endif
2936 
2937  if (avcodec_open2(ist->dec_ctx, codec, &opts) < 0) {
2938  av_log(NULL, AV_LOG_WARNING, "Could not open codec for input stream %d\n",
2939  stream->index);
2940  exit(1);
2941  }
2942 
2943  if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
2944  av_log(NULL, AV_LOG_ERROR, "Option %s for input stream %d not found\n",
2945  t->key, stream->index);
2946  return AVERROR_OPTION_NOT_FOUND;
2947  }
2948  }
2949  }
2950 
2951  ifile->fmt_ctx = fmt_ctx;
2952  return 0;
2953 }
2954 
2956 {
2957  int i;
2958 
2959  /* close decoder for each stream */
2960  for (i = 0; i < ifile->nb_streams; i++)
2961  if (ifile->streams[i].st->codecpar->codec_id != AV_CODEC_ID_NONE)
2962  avcodec_free_context(&ifile->streams[i].dec_ctx);
2963 
2964  av_freep(&ifile->streams);
2965  ifile->nb_streams = 0;
2966 
2967  avformat_close_input(&ifile->fmt_ctx);
2968 }
2969 
2970 static int probe_file(WriterContext *wctx, const char *filename)
2971 {
2972  InputFile ifile = { 0 };
2973  int ret, i;
2974  int section_id;
2975 
2978 
2979  ret = open_input_file(&ifile, filename);
2980  if (ret < 0)
2981  goto end;
2982 
2983 #define CHECK_END if (ret < 0) goto end
2984 
2985  nb_streams = ifile.fmt_ctx->nb_streams;
2989 
2990  for (i = 0; i < ifile.fmt_ctx->nb_streams; i++) {
2991  if (stream_specifier) {
2993  ifile.fmt_ctx->streams[i],
2995  CHECK_END;
2996  else
2997  selected_streams[i] = ret;
2998  ret = 0;
2999  } else {
3000  selected_streams[i] = 1;
3001  }
3002  if (!selected_streams[i])
3003  ifile.fmt_ctx->streams[i]->discard = AVDISCARD_ALL;
3004  }
3005 
3009  section_id = SECTION_ID_PACKETS_AND_FRAMES;
3010  else if (do_show_packets && !do_show_frames)
3011  section_id = SECTION_ID_PACKETS;
3012  else // (!do_show_packets && do_show_frames)
3013  section_id = SECTION_ID_FRAMES;
3015  writer_print_section_header(wctx, section_id);
3016  ret = read_packets(wctx, &ifile);
3019  CHECK_END;
3020  }
3021 
3022  if (do_show_programs) {
3023  ret = show_programs(wctx, &ifile);
3024  CHECK_END;
3025  }
3026 
3027  if (do_show_streams) {
3028  ret = show_streams(wctx, &ifile);
3029  CHECK_END;
3030  }
3031  if (do_show_chapters) {
3032  ret = show_chapters(wctx, &ifile);
3033  CHECK_END;
3034  }
3035  if (do_show_format) {
3036  ret = show_format(wctx, &ifile);
3037  CHECK_END;
3038  }
3039 
3040 end:
3041  if (ifile.fmt_ctx)
3042  close_input_file(&ifile);
3046 
3047  return ret;
3048 }
3049 
3050 static void show_usage(void)
3051 {
3052  av_log(NULL, AV_LOG_INFO, "Simple multimedia streams analyzer\n");
3053  av_log(NULL, AV_LOG_INFO, "usage: %s [OPTIONS] [INPUT_FILE]\n", program_name);
3054  av_log(NULL, AV_LOG_INFO, "\n");
3055 }
3056 
3057 static void ffprobe_show_program_version(WriterContext *w)
3058 {
3059  AVBPrint pbuf;
3061 
3063  print_str("version", FFMPEG_VERSION);
3064  print_fmt("copyright", "Copyright (c) %d-%d the FFmpeg developers",
3065  program_birth_year, CONFIG_THIS_YEAR);
3066  print_str("compiler_ident", CC_IDENT);
3067  print_str("configuration", FFMPEG_CONFIGURATION);
3069 
3070  av_bprint_finalize(&pbuf, NULL);
3071 }
3072 
3073 #define SHOW_LIB_VERSION(libname, LIBNAME) \
3074  do { \
3075  if (CONFIG_##LIBNAME) { \
3076  unsigned int version = libname##_version(); \
3077  writer_print_section_header(w, SECTION_ID_LIBRARY_VERSION); \
3078  print_str("name", "lib" #libname); \
3079  print_int("major", LIB##LIBNAME##_VERSION_MAJOR); \
3080  print_int("minor", LIB##LIBNAME##_VERSION_MINOR); \
3081  print_int("micro", LIB##LIBNAME##_VERSION_MICRO); \
3082  print_int("version", version); \
3083  print_str("ident", LIB##LIBNAME##_IDENT); \
3084  writer_print_section_footer(w); \
3085  } \
3086  } while (0)
3087 
3088 static void ffprobe_show_library_versions(WriterContext *w)
3089 {
3091  SHOW_LIB_VERSION(avutil, AVUTIL);
3092  SHOW_LIB_VERSION(avcodec, AVCODEC);
3093  SHOW_LIB_VERSION(avformat, AVFORMAT);
3094  SHOW_LIB_VERSION(avdevice, AVDEVICE);
3095  SHOW_LIB_VERSION(avfilter, AVFILTER);
3096  SHOW_LIB_VERSION(swscale, SWSCALE);
3097  SHOW_LIB_VERSION(swresample, SWRESAMPLE);
3098  SHOW_LIB_VERSION(postproc, POSTPROC);
3100 }
3101 
3102 #define PRINT_PIX_FMT_FLAG(flagname, name) \
3103  do { \
3104  print_int(name, !!(pixdesc->flags & AV_PIX_FMT_FLAG_##flagname)); \
3105  } while (0)
3106 
3107 static void ffprobe_show_pixel_formats(WriterContext *w)
3108 {
3109  const AVPixFmtDescriptor *pixdesc = NULL;
3110  int i, n;
3111 
3113  while (pixdesc = av_pix_fmt_desc_next(pixdesc)) {
3115  print_str("name", pixdesc->name);
3116  print_int("nb_components", pixdesc->nb_components);
3117  if ((pixdesc->nb_components >= 3) && !(pixdesc->flags & AV_PIX_FMT_FLAG_RGB)) {
3118  print_int ("log2_chroma_w", pixdesc->log2_chroma_w);
3119  print_int ("log2_chroma_h", pixdesc->log2_chroma_h);
3120  } else {
3121  print_str_opt("log2_chroma_w", "N/A");
3122  print_str_opt("log2_chroma_h", "N/A");
3123  }
3124  n = av_get_bits_per_pixel(pixdesc);
3125  if (n) print_int ("bits_per_pixel", n);
3126  else print_str_opt("bits_per_pixel", "N/A");
3129  PRINT_PIX_FMT_FLAG(BE, "big_endian");
3130  PRINT_PIX_FMT_FLAG(PAL, "palette");
3131  PRINT_PIX_FMT_FLAG(BITSTREAM, "bitstream");
3132  PRINT_PIX_FMT_FLAG(HWACCEL, "hwaccel");
3133  PRINT_PIX_FMT_FLAG(PLANAR, "planar");
3134  PRINT_PIX_FMT_FLAG(RGB, "rgb");
3135 #if FF_API_PSEUDOPAL
3136  PRINT_PIX_FMT_FLAG(PSEUDOPAL, "pseudopal");
3137 #endif
3138  PRINT_PIX_FMT_FLAG(ALPHA, "alpha");
3140  }
3141  if (do_show_pixel_format_components && (pixdesc->nb_components > 0)) {
3143  for (i = 0; i < pixdesc->nb_components; i++) {
3145  print_int("index", i + 1);
3146  print_int("bit_depth", pixdesc->comp[i].depth);
3148  }
3150  }
3152  }
3154 }
3155 
3156 static int opt_format(void *optctx, const char *opt, const char *arg)
3157 {
3158  iformat = av_find_input_format(arg);
3159  if (!iformat) {
3160  av_log(NULL, AV_LOG_ERROR, "Unknown input format: %s\n", arg);
3161  return AVERROR(EINVAL);
3162  }
3163  return 0;
3164 }
3165 
3166 static inline void mark_section_show_entries(SectionID section_id,
3167  int show_all_entries, AVDictionary *entries)
3168 {
3169  struct section *section = &sections[section_id];
3170 
3172  if (show_all_entries) {
3173  SectionID *id;
3174  for (id = section->children_ids; *id != -1; id++)
3175  mark_section_show_entries(*id, show_all_entries, entries);
3176  } else {
3177  av_dict_copy(&section->entries_to_show, entries, 0);
3178  }
3179 }
3180 
3181 static int match_section(const char *section_name,
3182  int show_all_entries, AVDictionary *entries)
3183 {
3184  int i, ret = 0;
3185 
3186  for (i = 0; i < FF_ARRAY_ELEMS(sections); i++) {
3187  const struct section *section = &sections[i];
3188  if (!strcmp(section_name, section->name) ||
3189  (section->unique_name && !strcmp(section_name, section->unique_name))) {
3191  "'%s' matches section with unique name '%s'\n", section_name,
3192  (char *)av_x_if_null(section->unique_name, section->name));
3193  ret++;
3194  mark_section_show_entries(section->id, show_all_entries, entries);
3195  }
3196  }
3197  return ret;
3198 }
3199 
3200 static int opt_show_entries(void *optctx, const char *opt, const char *arg)
3201 {
3202  const char *p = arg;
3203  int ret = 0;
3204 
3205  while (*p) {
3206  AVDictionary *entries = NULL;
3207  char *section_name = av_get_token(&p, "=:");
3208  int show_all_entries = 0;
3209 
3210  if (!section_name) {
3212  "Missing section name for option '%s'\n", opt);
3213  return AVERROR(EINVAL);
3214  }
3215 
3216  if (*p == '=') {
3217  p++;
3218  while (*p && *p != ':') {
3219  char *entry = av_get_token(&p, ",:");
3220  if (!entry)
3221  break;
3223  "Adding '%s' to the entries to show in section '%s'\n",
3224  entry, section_name);
3225  av_dict_set(&entries, entry, "", AV_DICT_DONT_STRDUP_KEY);
3226  if (*p == ',')
3227  p++;
3228  }
3229  } else {
3230  show_all_entries = 1;
3231  }
3232 
3233  ret = match_section(section_name, show_all_entries, entries);
3234  if (ret == 0) {
3235  av_log(NULL, AV_LOG_ERROR, "No match for section '%s'\n", section_name);
3236  ret = AVERROR(EINVAL);
3237  }
3238  av_dict_free(&entries);
3239  av_free(section_name);
3240 
3241  if (ret <= 0)
3242  break;
3243  if (*p)
3244  p++;
3245  }
3246 
3247  return ret;
3248 }
3249 
3250 static int opt_show_format_entry(void *optctx, const char *opt, const char *arg)
3251 {
3252  char *buf = av_asprintf("format=%s", arg);
3253  int ret;
3254 
3255  if (!buf)
3256  return AVERROR(ENOMEM);
3257 
3259  "Option '%s' is deprecated, use '-show_entries format=%s' instead\n",
3260  opt, arg);
3261  ret = opt_show_entries(optctx, opt, buf);
3262  av_free(buf);
3263  return ret;
3264 }
3265 
3266 static void opt_input_file(void *optctx, const char *arg)
3267 {
3268  if (input_filename) {
3270  "Argument '%s' provided as input filename, but '%s' was already specified.\n",
3271  arg, input_filename);
3272  exit_program(1);
3273  }
3274  if (!strcmp(arg, "-"))
3275  arg = "pipe:";
3276  input_filename = arg;
3277 }
3278 
3279 static int opt_input_file_i(void *optctx, const char *opt, const char *arg)
3280 {
3281  opt_input_file(optctx, arg);
3282  return 0;
3283 }
3284 
3285 void show_help_default(const char *opt, const char *arg)
3286 {
3288  show_usage();
3289  show_help_options(options, "Main options:", 0, 0, 0);
3290  printf("\n");
3291 
3294 }
3295 
3296 /**
3297  * Parse interval specification, according to the format:
3298  * INTERVAL ::= [START|+START_OFFSET][%[END|+END_OFFSET]]
3299  * INTERVALS ::= INTERVAL[,INTERVALS]
3300 */
3301 static int parse_read_interval(const char *interval_spec,
3302  ReadInterval *interval)
3303 {
3304  int ret = 0;
3305  char *next, *p, *spec = av_strdup(interval_spec);
3306  if (!spec)
3307  return AVERROR(ENOMEM);
3308 
3309  if (!*spec) {
3310  av_log(NULL, AV_LOG_ERROR, "Invalid empty interval specification\n");
3311  ret = AVERROR(EINVAL);
3312  goto end;
3313  }
3314 
3315  p = spec;
3316  next = strchr(spec, '%');
3317  if (next)
3318  *next++ = 0;
3319 
3320  /* parse first part */
3321  if (*p) {
3322  interval->has_start = 1;
3323 
3324  if (*p == '+') {
3325  interval->start_is_offset = 1;
3326  p++;
3327  } else {
3328  interval->start_is_offset = 0;
3329  }
3330 
3331  ret = av_parse_time(&interval->start, p, 1);
3332  if (ret < 0) {
3333  av_log(NULL, AV_LOG_ERROR, "Invalid interval start specification '%s'\n", p);
3334  goto end;
3335  }
3336  } else {
3337  interval->has_start = 0;
3338  }
3339 
3340  /* parse second part */
3341  p = next;
3342  if (p && *p) {
3343  int64_t us;
3344  interval->has_end = 1;
3345 
3346  if (*p == '+') {
3347  interval->end_is_offset = 1;
3348  p++;
3349  } else {
3350  interval->end_is_offset = 0;
3351  }
3352 
3353  if (interval->end_is_offset && *p == '#') {
3354  long long int lli;
3355  char *tail;
3356  interval->duration_frames = 1;
3357  p++;
3358  lli = strtoll(p, &tail, 10);
3359  if (*tail || lli < 0) {
3361  "Invalid or negative value '%s' for duration number of frames\n", p);
3362  goto end;
3363  }
3364  interval->end = lli;
3365  } else {
3366  interval->duration_frames = 0;
3367  ret = av_parse_time(&us, p, 1);
3368  if (ret < 0) {
3369  av_log(NULL, AV_LOG_ERROR, "Invalid interval end/duration specification '%s'\n", p);
3370  goto end;
3371  }
3372  interval->end = us;
3373  }
3374  } else {
3375  interval->has_end = 0;
3376  }
3377 
3378 end:
3379  av_free(spec);
3380  return ret;
3381 }
3382 
3383 static int parse_read_intervals(const char *intervals_spec)
3384 {
3385  int ret, n, i;
3386  char *p, *spec = av_strdup(intervals_spec);
3387  if (!spec)
3388  return AVERROR(ENOMEM);
3389 
3390  /* preparse specification, get number of intervals */
3391  for (n = 0, p = spec; *p; p++)
3392  if (*p == ',')
3393  n++;
3394  n++;
3395 
3396  read_intervals = av_malloc_array(n, sizeof(*read_intervals));
3397  if (!read_intervals) {
3398  ret = AVERROR(ENOMEM);
3399  goto end;
3400  }
3401  read_intervals_nb = n;
3402 
3403  /* parse intervals */
3404  p = spec;
3405  for (i = 0; p; i++) {
3406  char *next;
3407 
3409  next = strchr(p, ',');
3410  if (next)
3411  *next++ = 0;
3412 
3413  read_intervals[i].id = i;
3414  ret = parse_read_interval(p, &read_intervals[i]);
3415  if (ret < 0) {
3416  av_log(NULL, AV_LOG_ERROR, "Error parsing read interval #%d '%s'\n",
3417  i, p);
3418  goto end;
3419  }
3420  av_log(NULL, AV_LOG_VERBOSE, "Parsed log interval ");
3421  log_read_interval(&read_intervals[i], NULL, AV_LOG_VERBOSE);
3422  p = next;
3423  }
3425 
3426 end:
3427  av_free(spec);
3428  return ret;
3429 }
3430 
3431 static int opt_read_intervals(void *optctx, const char *opt, const char *arg)
3432 {
3433  return parse_read_intervals(arg);
3434 }
3435 
3436 static int opt_pretty(void *optctx, const char *opt, const char *arg)
3437 {
3438  show_value_unit = 1;
3439  use_value_prefix = 1;
3442  return 0;
3443 }
3444 
3445 static void print_section(SectionID id, int level)
3446 {
3447  const SectionID *pid;
3448  const struct section *section = &sections[id];
3449  printf("%c%c%c",
3450  section->flags & SECTION_FLAG_IS_WRAPPER ? 'W' : '.',
3451  section->flags & SECTION_FLAG_IS_ARRAY ? 'A' : '.',
3452  section->flags & SECTION_FLAG_HAS_VARIABLE_FIELDS ? 'V' : '.');
3453  printf("%*c %s", level * 4, ' ', section->name);
3454  if (section->unique_name)
3455  printf("/%s", section->unique_name);
3456  printf("\n");
3457 
3458  for (pid = section->children_ids; *pid != -1; pid++)
3459  print_section(*pid, level+1);
3460 }
3461 
3462 static int opt_sections(void *optctx, const char *opt, const char *arg)
3463 {
3464  printf("Sections:\n"
3465  "W.. = Section is a wrapper (contains other sections, no local entries)\n"
3466  ".A. = Section contains an array of elements of the same type\n"
3467  "..V = Section may contain a variable number of fields with variable keys\n"
3468  "FLAGS NAME/UNIQUE_NAME\n"
3469  "---\n");
3471  return 0;
3472 }
3473 
3474 static int opt_show_versions(const char *opt, const char *arg)
3475 {
3478  return 0;
3479 }
3480 
3481 #define DEFINE_OPT_SHOW_SECTION(section, target_section_id) \
3482  static int opt_show_##section(const char *opt, const char *arg) \
3483  { \
3484  mark_section_show_entries(SECTION_ID_##target_section_id, 1, NULL); \
3485  return 0; \
3486  }
3487 
3488 DEFINE_OPT_SHOW_SECTION(chapters, CHAPTERS)
3492 DEFINE_OPT_SHOW_SECTION(library_versions, LIBRARY_VERSIONS)
3493 DEFINE_OPT_SHOW_SECTION(packets, PACKETS)
3494 DEFINE_OPT_SHOW_SECTION(pixel_formats, PIXEL_FORMATS)
3495 DEFINE_OPT_SHOW_SECTION(program_version, PROGRAM_VERSION)
3496 DEFINE_OPT_SHOW_SECTION(streams, STREAMS)
3497 DEFINE_OPT_SHOW_SECTION(programs, PROGRAMS)
3498 
3499 static const OptionDef real_options[] = {
3501  { "f", HAS_ARG, {.func_arg = opt_format}, "force format", "format" },
3502  { "unit", OPT_BOOL, {&show_value_unit}, "show unit of the displayed values" },
3503  { "prefix", OPT_BOOL, {&use_value_prefix}, "use SI prefixes for the displayed values" },
3504  { "byte_binary_prefix", OPT_BOOL, {&use_byte_value_binary_prefix},
3505  "use binary prefixes for byte units" },
3506  { "sexagesimal", OPT_BOOL, {&use_value_sexagesimal_format},
3507  "use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" },
3508  { "pretty", 0, {.func_arg = opt_pretty},
3509  "prettify the format of displayed values, make it more human readable" },
3510  { "print_format", OPT_STRING | HAS_ARG, {(void*)&print_format},
3511  "set the output printing format (available formats are: default, compact, csv, flat, ini, json, xml)", "format" },
3512  { "of", OPT_STRING | HAS_ARG, {(void*)&print_format}, "alias for -print_format", "format" },
3513  { "select_streams", OPT_STRING | HAS_ARG, {(void*)&stream_specifier}, "select the specified streams", "stream_specifier" },
3514  { "sections", OPT_EXIT, {.func_arg = opt_sections}, "print sections structure and section information, and exit" },
3515  { "show_data", OPT_BOOL, {(void*)&do_show_data}, "show packets data" },
3516  { "show_data_hash", OPT_STRING | HAS_ARG, {(void*)&show_data_hash}, "show packets data hash" },
3517  { "show_error", 0, {(void*)&opt_show_error}, "show probing error" },
3518  { "show_format", 0, {(void*)&opt_show_format}, "show format/container info" },
3519  { "show_frames", 0, {(void*)&opt_show_frames}, "show frames info" },
3520  { "show_format_entry", HAS_ARG, {.func_arg = opt_show_format_entry},
3521  "show a particular entry from the format/container info", "entry" },
3522  { "show_entries", HAS_ARG, {.func_arg = opt_show_entries},
3523  "show a set of specified entries", "entry_list" },
3524 #if HAVE_THREADS
3525  { "show_log", OPT_INT|HAS_ARG, {(void*)&do_show_log}, "show log" },
3526 #endif
3527  { "show_packets", 0, {(void*)&opt_show_packets}, "show packets info" },
3528  { "show_programs", 0, {(void*)&opt_show_programs}, "show programs info" },
3529  { "show_streams", 0, {(void*)&opt_show_streams}, "show streams info" },
3530  { "show_chapters", 0, {(void*)&opt_show_chapters}, "show chapters info" },
3531  { "count_frames", OPT_BOOL, {(void*)&do_count_frames}, "count the number of frames per stream" },
3532  { "count_packets", OPT_BOOL, {(void*)&do_count_packets}, "count the number of packets per stream" },
3533  { "show_program_version", 0, {(void*)&opt_show_program_version}, "show ffprobe version" },
3534  { "show_library_versions", 0, {(void*)&opt_show_library_versions}, "show library versions" },
3535  { "show_versions", 0, {(void*)&opt_show_versions}, "show program and library versions" },
3536  { "show_pixel_formats", 0, {(void*)&opt_show_pixel_formats}, "show pixel format descriptions" },
3537  { "show_private_data", OPT_BOOL, {(void*)&show_private_data}, "show private data" },
3538  { "private", OPT_BOOL, {(void*)&show_private_data}, "same as show_private_data" },
3539  { "bitexact", OPT_BOOL, {&do_bitexact}, "force bitexact output" },
3540  { "read_intervals", HAS_ARG, {.func_arg = opt_read_intervals}, "set read intervals", "read_intervals" },
3541  { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default}, "generic catch all option", "" },
3542  { "i", HAS_ARG, {.func_arg = opt_input_file_i}, "read specified file", "input_file"},
3543  { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
3544  "read and decode the streams to fill missing information with heuristics" },
3545  { NULL, },
3546 };
3547 
3548 static inline int check_section_show_entries(int section_id)
3549 {
3550  int *id;
3551  struct section *section = &sections[section_id];
3552  if (sections[section_id].show_all_entries || sections[section_id].entries_to_show)
3553  return 1;
3554  for (id = section->children_ids; *id != -1; id++)
3555  if (check_section_show_entries(*id))
3556  return 1;
3557  return 0;
3558 }
3559 
3560 #define SET_DO_SHOW(id, varname) do { \
3561  if (check_section_show_entries(SECTION_ID_##id)) \
3562  do_show_##varname = 1; \
3563  } while (0)
3564 
3565 int main(int argc, char **argv)
3566 {
3567  const Writer *w;
3568  WriterContext *wctx;
3569  char *buf;
3570  char *w_name = NULL, *w_args = NULL;
3571  int ret, i;
3572 
3573  init_dynload();
3574 
3575 #if HAVE_THREADS
3576  ret = pthread_mutex_init(&log_mutex, NULL);
3577  if (ret != 0) {
3578  goto end;
3579  }
3580 #endif
3583 
3584  options = real_options;
3585  parse_loglevel(argc, argv, options);
3587  init_opts();
3588 #if CONFIG_AVDEVICE
3590 #endif
3591 
3592  show_banner(argc, argv, options);
3593  parse_options(NULL, argc, argv, options, opt_input_file);
3594 
3595  if (do_show_log)
3597 
3598  /* mark things to show, based on -show_entries */
3599  SET_DO_SHOW(CHAPTERS, chapters);
3601  SET_DO_SHOW(FORMAT, format);
3602  SET_DO_SHOW(FRAMES, frames);
3603  SET_DO_SHOW(LIBRARY_VERSIONS, library_versions);
3604  SET_DO_SHOW(PACKETS, packets);
3605  SET_DO_SHOW(PIXEL_FORMATS, pixel_formats);
3606  SET_DO_SHOW(PIXEL_FORMAT_FLAGS, pixel_format_flags);
3607  SET_DO_SHOW(PIXEL_FORMAT_COMPONENTS, pixel_format_components);
3608  SET_DO_SHOW(PROGRAM_VERSION, program_version);
3609  SET_DO_SHOW(PROGRAMS, programs);
3610  SET_DO_SHOW(STREAMS, streams);
3611  SET_DO_SHOW(STREAM_DISPOSITION, stream_disposition);
3612  SET_DO_SHOW(PROGRAM_STREAM_DISPOSITION, stream_disposition);
3613 
3614  SET_DO_SHOW(CHAPTER_TAGS, chapter_tags);
3615  SET_DO_SHOW(FORMAT_TAGS, format_tags);
3616  SET_DO_SHOW(FRAME_TAGS, frame_tags);
3617  SET_DO_SHOW(PROGRAM_TAGS, program_tags);
3618  SET_DO_SHOW(STREAM_TAGS, stream_tags);
3619  SET_DO_SHOW(PROGRAM_STREAM_TAGS, stream_tags);
3620  SET_DO_SHOW(PACKET_TAGS, packet_tags);
3621 
3624  "-bitexact and -show_program_version or -show_library_versions "
3625  "options are incompatible\n");
3626  ret = AVERROR(EINVAL);
3627  goto end;
3628  }
3629 
3631 
3632  if (!print_format)
3633  print_format = av_strdup("default");
3634  if (!print_format) {
3635  ret = AVERROR(ENOMEM);
3636  goto end;
3637  }
3638  w_name = av_strtok(print_format, "=", &buf);
3639  if (!w_name) {
3641  "No name specified for the output format\n");
3642  ret = AVERROR(EINVAL);
3643  goto end;
3644  }
3645  w_args = buf;
3646 
3647  if (show_data_hash) {
3648  if ((ret = av_hash_alloc(&hash, show_data_hash)) < 0) {
3649  if (ret == AVERROR(EINVAL)) {
3650  const char *n;
3652  "Unknown hash algorithm '%s'\nKnown algorithms:",
3653  show_data_hash);
3654  for (i = 0; (n = av_hash_names(i)); i++)
3655  av_log(NULL, AV_LOG_ERROR, " %s", n);
3656  av_log(NULL, AV_LOG_ERROR, "\n");
3657  }
3658  goto end;
3659  }
3660  }
3661 
3662  w = writer_get_by_name(w_name);
3663  if (!w) {
3664  av_log(NULL, AV_LOG_ERROR, "Unknown output format with name '%s'\n", w_name);
3665  ret = AVERROR(EINVAL);
3666  goto end;
3667  }
3668 
3669  if ((ret = writer_open(&wctx, w, w_args,
3670  sections, FF_ARRAY_ELEMS(sections))) >= 0) {
3671  if (w == &xml_writer)
3673 
3675 
3682 
3683  if (!input_filename &&
3686  show_usage();
3687  av_log(NULL, AV_LOG_ERROR, "You have to specify one input file.\n");
3688  av_log(NULL, AV_LOG_ERROR, "Use -h to get full help or, even better, run 'man %s'.\n", program_name);
3689  ret = AVERROR(EINVAL);
3690  } else if (input_filename) {
3691  ret = probe_file(wctx, input_filename);
3692  if (ret < 0 && do_show_error)
3693  show_error(wctx, ret);
3694  }
3695 
3697  writer_close(&wctx);
3698  }
3699 
3700 end:
3702  av_freep(&read_intervals);
3703  av_hash_freep(&hash);
3704 
3705  uninit_opts();
3706  for (i = 0; i < FF_ARRAY_ELEMS(sections); i++)
3707  av_dict_free(&(sections[i].entries_to_show));
3708 
3710 
3711  return ret < 0;
3712 }
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:701
AVClassCategory parent_category
Definition: ffprobe.c:294
enum AVChromaLocation chroma_location
Definition: avcodec.h:4047
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:1574
AVRational framerate
Definition: avcodec.h:3105
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:4038
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:4045
#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:1839
#define OPT_EXPERT
Definition: cmdutils.h:163
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:336
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:367
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:1590
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:1818
static int opt_input_file_i(void *optctx, const char *opt, const char *arg)
Definition: ffprobe.c:3279
static int opt_format(void *optctx, const char *opt, const char *arg)
Definition: ffprobe.c:3156
int within_tag
Definition: ffprobe.c:1621
#define SHOW_LIB_VERSION(libname, LIBNAME)
Definition: ffprobe.c:3073
#define OPT_VIDEO
Definition: cmdutils.h:165
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:1753
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:3250
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:1497
static const char * xml_escape_str(AVBPrint *dst, const char *src, void *log_ctx)
Definition: ffprobe.c:1668
#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:1972
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:5058
This side data should be associated with a video stream and contains Stereoscopic 3D information in f...
Definition: avcodec.h:1258
void av_opt_set_defaults(void *s)
Set the values of all AVOption fields to their default values.
Definition: opt.c:1305
#define OPT_AUDIO
Definition: cmdutils.h:166
static AVFormatContext * fmt_ctx
static int show_streams(WriterContext *w, InputFile *ifile)
Definition: ffprobe.c:2695
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:3957
AVRational white_point[2]
CIE 1931 xy chromaticity coords of white point.
static const Writer json_writer
Definition: ffprobe.c:1605
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:1478
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:2469
#define us(width, name, range_min, range_max, subs,...)
Definition: cbs_h2645.c:266
#define print_str_opt(k, v)
Definition: ffprobe.c:1815
static int read_packets(WriterContext *w, InputFile *ifile)
Definition: ffprobe.c:2449
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:1180
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:537
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:3937
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:811
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:2112
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:1728
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:2796
static void mark_section_show_entries(SectionID section_id, int show_all_entries, AVDictionary *entries)
Definition: ffprobe.c:3166
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:1070
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:3481
static int open_input_file(InputFile *ifile, const char *filename)
Definition: ffprobe.c:2835
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:2079
This struct describes the properties of an encoded stream.
Definition: avcodec.h:3949
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:467
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:4046
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:1622
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:2258
Mastering display metadata (based on SMPTE-2086:2014).
Definition: avcodec.h:1366
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avcodec.h:1688
#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:1628
#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:1820
#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:3431
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:4023
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:2955
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:496
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:2765
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: avcodec.h:1495
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:1252
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:5265
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:3181
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:2095
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:2321
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:1477
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:2712
uint32_t tag
Definition: movenc.c:1496
int avformat_network_init(void)
Do global initialization of network libraries.
Definition: utils.c:4995
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:1421
static int check_section_show_entries(int section_id)
Definition: ffprobe.c:3548
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:168
static void print_section(SectionID id, int level)
Definition: ffprobe.c:3445
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:519
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:3285
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:1789
static void xml_print_str(WriterContext *wctx, const char *key, const char *value)
Definition: ffprobe.c:1747
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:1857
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:4059
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:3057
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:2136
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: avcodec.h:3986
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1509
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:571
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:2345
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:3119
char * string_validation_replacement
Definition: ffprobe.c:474
double d
Definition: ffprobe.c:361
libswresample public header
static int opt_show_versions(const char *opt, const char *arg)
Definition: ffprobe.c:3474
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:1513
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:1624
#define print_int(k, v)
Definition: ffprobe.c:1812
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:3266
int64_t start
Definition: ffmpeg.h:309
static int opt_pretty(void *optctx, const char *opt, const char *arg)
Definition: ffprobe.c:3436
BYTE * dstp
Definition: avisynth_c.h:908
#define SET_DO_SHOW(id, varname)
Definition: ffprobe.c:3560
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:1630
Display matrix.
enum AVColorPrimaries color_primaries
Definition: avcodec.h:4044
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:4052
#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:740
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:3953
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:1813
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:1423
#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:1489
static int show_log(WriterContext *w, int section_ids, int section_id, int log_level)
Definition: ffprobe.c:1999
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: ffprobe.c:140
const char * long_name
A more descriptive name for this codec.
Definition: avcodec.h:728
The GOP timecode in 25 bit timecode format.
Definition: frame.h:124
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:954
New fields can be added to the end with minor version bumps.
Definition: avformat.h:1275