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