27 #include "libavutil/ffversion.h" 
   97 #define SECTION_MAX_NB_CHILDREN 10 
  103 #define SECTION_FLAG_IS_WRAPPER      1  
  104 #define SECTION_FLAG_IS_ARRAY        2 
 
  105 #define SECTION_FLAG_HAS_VARIABLE_FIELDS 4 
 
  206     union { 
double d; 
long long int i; } 
val;
 
  220         vald = vali = uv.
val.
i;
 
  227         mins  = (int)secs / 60;
 
  228         secs  = secs - mins * 60;
 
  231         snprintf(buf, buf_size, 
"%d:%02d:%09.6f", hours, mins, secs);
 
  233         const char *prefix_string = 
"";
 
  239                 index = (
long long int) (
log2(vald)) / 10;
 
  241                 vald /= 
exp2(index * 10);
 
  244                 index = (
long long int) (log10(vald)) / 3;
 
  246                 vald /= pow(10, index * 3);
 
  252             snprintf(buf, buf_size, 
"%f", vald);
 
  254             snprintf(buf, buf_size, 
"%lld", vali);
 
  266 #define WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS 1 
  267 #define WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER 2 
  292 #define SECTION_MAX_NB_LEVELS 10 
  328 #define OFFSET(x) offsetof(WriterContext, x) 
  331     { 
"string_validation", 
"set string validation mode",
 
  333     { 
"sv", 
"set string validation mode",
 
  338     { 
"string_validation_replacement", 
"set string validation replacement string", 
OFFSET(string_validation_replacement), 
AV_OPT_TYPE_STRING, {.str=
""}},
 
  339     { 
"svr", 
"set string validation replacement string", 
OFFSET(string_validation_replacement), 
AV_OPT_TYPE_STRING, {.str=
""}},
 
  366     if ((*wctx)->writer->uninit)
 
  367         (*wctx)->writer->uninit(*wctx);
 
  370     if ((*wctx)->writer->priv_class)
 
  381     for (i = 0; i < ubuf_size; i++)
 
  387                        const struct section *sections, 
int nb_sections)
 
  402     (*wctx)->writer = writer;
 
  405     (*wctx)->nb_sections = nb_sections;
 
  410         void *priv_ctx = (*wctx)->priv;
 
  421             av_log(*wctx, 
AV_LOG_ERROR, 
"Failed to parse option string '%s' provided to writer context\n", args);
 
  428                 av_log(*wctx, 
AV_LOG_ERROR, 
"Failed to set option '%s' with value '%s' provided to writer context\n",
 
  440         const uint8_t *p = (*wctx)->string_validation_replacement;
 
  441         const uint8_t *endp = p + strlen(p);
 
  445             ret = 
av_utf8_decode(&code, &p, endp, (*wctx)->string_validation_utf8_flags);
 
  451                            "Invalid UTF8 sequence %s found in string validation replace '%s'\n",
 
  452                            bp.str, (*wctx)->string_validation_replacement);
 
  461     if ((*wctx)->writer->init)
 
  462         ret = (*wctx)->writer->init(*wctx);
 
  476     int parent_section_id;
 
  479     parent_section_id = wctx->
level ?
 
  500     int parent_section_id = wctx->
level ?
 
  515                                         const char *key, 
long long int val)
 
  529     int invalid_chars_nb = 0, 
ret = 0;
 
  533     endp = src + strlen(src);
 
  534     for (p = (
uint8_t *)src; *p;) {
 
  544                    "Invalid UTF-8 sequence %s found in string '%s'\n", bp.str, src);
 
  554                        "Invalid UTF-8 sequence found in string '%s'\n", src);
 
  571                "%d invalid UTF-8 sequence(s) found in string '%s', replaced with '%s'\n",
 
  580 #define PRINT_STRING_OPT      1 
  581 #define PRINT_STRING_VALIDATE 2 
  584                                       const char *key, 
const char *
val, 
int flags)
 
  595             char *key1 = NULL, *val1 = NULL;
 
  597             if (ret < 0) 
goto end;
 
  599             if (ret < 0) 
goto end;
 
  604                        "Invalid key=value string combination %s=%s in section %s\n",
 
  629                               int64_t ts, 
const AVRational *time_base, 
int is_duration)
 
  633     if ((!is_duration && ts == 
AV_NOPTS_VALUE) || (is_duration && ts == 0)) {
 
  636         double d = ts * 
av_q2d(*time_base);
 
  647     if ((!is_duration && ts == 
AV_NOPTS_VALUE) || (is_duration && ts == 0)) {
 
  665         for (i = 0; i < l; i++) {
 
  671         for (i = 0; i < l; i++)
 
  682 #define MAX_REGISTERED_WRITERS_NB 64 
  688     static int next_registered_writer_idx = 0;
 
  693     registered_writers[next_registered_writer_idx++] = writer;
 
  701     for (i = 0; registered_writers[
i]; i++)
 
  702         if (!strcmp(registered_writers[i]->name, name))
 
  703             return registered_writers[
i];
 
  711 #define DEFINE_WRITER_CLASS(name)                   \ 
  712 static const char *name##_get_name(void *ctx)       \ 
  716 static const AVClass name##_class = {               \ 
  717     .class_name = #name,                            \ 
  718     .item_name  = name##_get_name,                  \ 
  719     .option     = name##_options                    \ 
  732 #define OFFSET(x) offsetof(DefaultContext, x) 
  735     { 
"noprint_wrappers", 
"do not print headers and footers", 
OFFSET(noprint_wrappers), 
AV_OPT_TYPE_INT, {.i64=0}, 0, 1 },
 
  736     { 
"nw",               
"do not print headers and footers", 
OFFSET(noprint_wrappers), 
AV_OPT_TYPE_INT, {.i64=0}, 0, 1 },
 
  748     for (i = 0; src[i] && i < dst_size-1; i++)
 
  759     const struct section *parent_section = wctx->
level ?
 
  763     if (parent_section &&
 
  798     printf(
"%s\n", value);
 
  807     printf(
"%lld\n", value);
 
  818     .priv_class            = &default_class,
 
  830     for (p = src; *p; p++) {
 
  832         case '\b': 
av_bprintf(dst, 
"%s", 
"\\b");  
break;
 
  833         case '\f': 
av_bprintf(dst, 
"%s", 
"\\f");  
break;
 
  834         case '\n': 
av_bprintf(dst, 
"%s", 
"\\n");  
break;
 
  835         case '\r': 
av_bprintf(dst, 
"%s", 
"\\r");  
break;
 
  836         case '\\': 
av_bprintf(dst, 
"%s", 
"\\\\"); 
break;
 
  851     char meta_chars[] = { sep, 
'"', 
'\n', 
'\r', 
'\0' };
 
  852     int needs_quoting = !!src[strcspn(src, meta_chars)];
 
  857     for (; *
src; src++) {
 
  879     const char * (*escape_str)(
AVBPrint *dst, 
const char *
src, 
const char sep, 
void *log_ctx);
 
  886 #define OFFSET(x) offsetof(CompactContext, x) 
  907         av_log(wctx, 
AV_LOG_ERROR, 
"Item separator '%s' specified, but must contain a single character\n",
 
  928     const struct section *parent_section = wctx->
level ?
 
  984     printf(
"%lld", value);
 
  996     .priv_class           = &compact_class,
 
 1002 #define OFFSET(x) offsetof(CompactContext, x) 
 1027     .priv_class           = &csv_class,
 
 1040 #define OFFSET(x) offsetof(FlatContext, x) 
 1045     {
"hierarchical", 
"specify if the section specification should be hierarchical", 
OFFSET(hierarchical), 
AV_OPT_TYPE_INT, {.i64=1}, 0, 1 },
 
 1046     {
"h",           
"specify if the section specification should be hierarchical", 
OFFSET(hierarchical), 
AV_OPT_TYPE_INT, {.i64=1}, 0, 1 },
 
 1056     if (strlen(flat->
sep_str) != 1) {
 
 1057         av_log(wctx, 
AV_LOG_ERROR, 
"Item separator '%s' specified, but must contain a single character\n",
 
 1070     for (p = src; *p; p++) {
 
 1071         if (!((*p >= 
'0' && *p <= 
'9') ||
 
 1072               (*p >= 
'a' && *p <= 
'z') ||
 
 1073               (*p >= 
'A' && *p <= 
'Z')))
 
 1085     for (p = src; *p; p++) {
 
 1087         case '\n': 
av_bprintf(dst, 
"%s", 
"\\n");  
break;
 
 1088         case '\r': 
av_bprintf(dst, 
"%s", 
"\\r");  
break;
 
 1089         case '\\': 
av_bprintf(dst, 
"%s", 
"\\\\"); 
break;
 
 1090         case '"':  
av_bprintf(dst, 
"%s", 
"\\\""); 
break;
 
 1091         case '`':  
av_bprintf(dst, 
"%s", 
"\\`");  
break;
 
 1092         case '$':  
av_bprintf(dst, 
"%s", 
"\\$");  
break;
 
 1104     const struct section *parent_section = wctx->
level ?
 
 1109     if (!parent_section)
 
 1151     .priv_class            = &flat_class,
 
 1162 #define OFFSET(x) offsetof(INIContext, x) 
 1165     {
"hierarchical", 
"specify if the section specification should be hierarchical", 
OFFSET(hierarchical), 
AV_OPT_TYPE_INT, {.i64=1}, 0, 1 },
 
 1166     {
"h",           
"specify if the section specification should be hierarchical", 
OFFSET(hierarchical), 
AV_OPT_TYPE_INT, {.i64=1}, 0, 1 },
 
 1177     while (c = src[i++]) {
 
 1179         case '\b': 
av_bprintf(dst, 
"%s", 
"\\b"); 
break;
 
 1180         case '\f': 
av_bprintf(dst, 
"%s", 
"\\f"); 
break;
 
 1181         case '\n': 
av_bprintf(dst, 
"%s", 
"\\n"); 
break;
 
 1182         case '\r': 
av_bprintf(dst, 
"%s", 
"\\r"); 
break;
 
 1183         case '\t': 
av_bprintf(dst, 
"%s", 
"\\t"); 
break;
 
 1189             if ((
unsigned char)c < 32)
 
 1204     const struct section *parent_section = wctx->
level ?
 
 1208     if (!parent_section) {
 
 1209         printf(
"# ffprobe output\n\n");
 
 1229         printf(
"[%s]\n", buf->str);
 
 1245     printf(
"%s=%lld\n", key, value);
 
 1255     .priv_class            = &ini_class,
 
 1268 #define OFFSET(x) offsetof(JSONContext, x) 
 1290     static const char json_escape[] = {
'"', 
'\\', 
'\b', 
'\f', 
'\n', 
'\r', 
'\t', 0};
 
 1291     static const char json_subst[]  = {
'"', 
'\\',  
'b',  
'f',  
'n',  
'r',  
't', 0};
 
 1294     for (p = src; *p; p++) {
 
 1295         char *
s = strchr(json_escape, *p);
 
 1299         } 
else if ((
unsigned char)*p < 32) {
 
 1308 #define JSON_INDENT() printf("%*c", json->indent_level * 4, ' ') 
 1315     const struct section *parent_section = wctx->
level ?
 
 1331             printf(
"\"%s\": [\n", buf.str);
 
 1341                 printf(
"\"type\": \"%s\"%s", section->
name, json->
item_sep);
 
 1353     if (wctx->
level == 0) {
 
 1371                                        const char *key, 
const char *
value)
 
 1417     .priv_class           = &json_class,
 
 1431 #define OFFSET(x) offsetof(XMLContext, x) 
 1434     {
"fully_qualified", 
"specify if the output should be fully qualified", 
OFFSET(fully_qualified), 
AV_OPT_TYPE_INT, {.i64=0},  0, 1 },
 
 1435     {
"q",               
"specify if the output should be fully qualified", 
OFFSET(fully_qualified), 
AV_OPT_TYPE_INT, {.i64=0},  0, 1 },
 
 1436     {
"xsd_strict",      
"ensure that the output is XSD compliant",         
OFFSET(xsd_strict),      
AV_OPT_TYPE_INT, {.i64=0},  0, 1 },
 
 1437     {
"x",               
"ensure that the output is XSD compliant",         
OFFSET(xsd_strict),      
AV_OPT_TYPE_INT, {.i64=0},  0, 1 },
 
 1449 #define CHECK_COMPLIANCE(opt, opt_name)                                 \ 
 1451             av_log(wctx, AV_LOG_ERROR,                                  \ 
 1452                    "XSD-compliant output selected but option '%s' was selected, XML output may be non-compliant.\n" \ 
 1453                    "You need to disable such option with '-no%s'\n", opt_name, opt_name); \ 
 1454             return AVERROR(EINVAL);                                     \ 
 1462                    "Interleaved frames and packets are not allowed in XSD. " 
 1463                    "Select only one between the -show_frames and the -show_packets options.\n");
 
 1475     for (p = src; *p; p++) {
 
 1477         case '&' : 
av_bprintf(dst, 
"%s", 
"&");  
break;
 
 1478         case '<' : 
av_bprintf(dst, 
"%s", 
"<");   
break;
 
 1479         case '>' : 
av_bprintf(dst, 
"%s", 
">");   
break;
 
 1480         case '"' : 
av_bprintf(dst, 
"%s", 
"""); 
break;
 
 1481         case '\'': 
av_bprintf(dst, 
"%s", 
"'"); 
break;
 
 1489 #define XML_INDENT() printf("%*c", xml->indent_level * 4, ' ') 
 1495     const struct section *parent_section = wctx->
level ?
 
 1498     if (wctx->
level == 0) {
 
 1499         const char *qual = 
" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " 
 1500             "xmlns:ffprobe='http://www.ffmpeg.org/schema/ffprobe' " 
 1501             "xsi:schemaLocation='http://www.ffmpeg.org/schema/ffprobe ffprobe.xsd'";
 
 1503         printf(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
 
 1504         printf(
"<%sffprobe%s>\n",
 
 1536     if (wctx->
level == 0) {
 
 1560         printf(
"<%s key=\"%s\"",
 
 1577     printf(
"%s=\"%lld\"", key, value);
 
 1589     .priv_class           = &xml_class,
 
 1594     static int initialized;
 
 1609 #define print_fmt(k, f, ...) do {              \ 
 1610     av_bprint_clear(&pbuf);                    \ 
 1611     av_bprintf(&pbuf, f, __VA_ARGS__);         \ 
 1612     writer_print_string(w, k, pbuf.str, 0);    \ 
 1615 #define print_int(k, v)         writer_print_integer(w, k, v) 
 1616 #define print_q(k, v, s)        writer_print_rational(w, k, v, s) 
 1617 #define print_str(k, v)         writer_print_string(w, k, v, 0) 
 1618 #define print_str_opt(k, v)     writer_print_string(w, k, v, PRINT_STRING_OPT) 
 1619 #define print_str_validate(k, v) writer_print_string(w, k, v, PRINT_STRING_VALIDATE) 
 1620 #define print_time(k, v, tb)    writer_print_time(w, k, v, tb, 0) 
 1621 #define print_ts(k, v)          writer_print_ts(w, k, v, 0) 
 1622 #define print_duration_time(k, v, tb) writer_print_time(w, k, v, tb, 1) 
 1623 #define print_duration_ts(k, v)       writer_print_ts(w, k, v, 1) 
 1624 #define print_val(k, v, u) do {                                     \ 
 1625     struct unit_value uv;                                           \ 
 1628     writer_print_string(w, k, value_string(val_str, sizeof(val_str), uv), 0); \ 
 1631 #define print_section_header(s) writer_print_section_header(w, s) 
 1632 #define print_section_footer(s) writer_print_section_footer(w, s) 
 1748             print_q(
"sample_aspect_ratio", sar, 
':');
 
 1790     int ret = 0, got_frame = 0;
 
 1792     if (dec_ctx->
codec) {
 
 1829     av_log(log_ctx, log_level, 
"id:%d", interval->
id);
 
 1835         av_log(log_ctx, log_level, 
" start:N/A");
 
 1841             av_log(log_ctx, log_level, 
"#%"PRId64, interval->
end);
 
 1845         av_log(log_ctx, log_level, 
" end:N/A");
 
 1848     av_log(log_ctx, log_level, 
"\n");
 
 1870                        "Could not seek to relative position since current " 
 1871                        "timestamp is not defined\n");
 
 1875             target = *cur_ts + interval->
start;
 
 1877             target = interval->
start;
 
 1907                 end = start + interval->
end;
 
 1914             } 
else if (has_end && *cur_ts != 
AV_NOPTS_VALUE && *cur_ts >= end) {
 
 1986     if ((dec_ctx = stream->
codec)) {
 
 1987         const char *profile = NULL;
 
 1988         dec = dec_ctx->
codec;
 
 2024                 print_q(
"sample_aspect_ratio", sar, 
':');
 
 2029                 print_q(
"display_aspect_ratio", dar, 
':');
 
 2083             if (opt->
flags) 
continue;
 
 2113 #define PRINT_DISPOSITION(flagname, name) do {                                \ 
 2114         print_int(name, !!(stream->disposition & AV_DISPOSITION_##flagname)); \ 
 2267     const char *errbuf_ptr = errbuf;
 
 2280     int err, i, orig_nb_streams;
 
 2303     for (i = 0; i < orig_nb_streams; i++)
 
 2316                    "Failed to probe codec for input stream %d\n",
 
 2320                     "Unsupported codec with id %d for input stream %d\n",
 
 2324                                                    fmt_ctx, stream, codec);
 
 2367 #define CHECK_END if (ret < 0) goto end 
 2444     print_fmt(
"copyright", 
"Copyright (c) %d-%d the FFmpeg developers",
 
 2449     print_str(
"configuration", FFMPEG_CONFIGURATION);
 
 2455 #define SHOW_LIB_VERSION(libname, LIBNAME)                              \ 
 2457         if (CONFIG_##LIBNAME) {                                         \ 
 2458             unsigned int version = libname##_version();                 \ 
 2459             writer_print_section_header(w, SECTION_ID_LIBRARY_VERSION); \ 
 2460             print_str("name",    "lib" #libname);                       \ 
 2461             print_int("major",   LIB##LIBNAME##_VERSION_MAJOR);         \ 
 2462             print_int("minor",   LIB##LIBNAME##_VERSION_MINOR);         \ 
 2463             print_int("micro",   LIB##LIBNAME##_VERSION_MICRO);         \ 
 2464             print_int("version", version);                              \ 
 2465             print_str("ident",   LIB##LIBNAME##_IDENT);                 \ 
 2466             writer_print_section_footer(w);                             \ 
 2500     if (show_all_entries) {
 
 2516         if (!strcmp(section_name, section->
name) ||
 
 2519                    "'%s' matches section with unique name '%s'\n", section_name,
 
 2530     const char *p = 
arg;
 
 2538         if (!section_name) {
 
 2540                    "Missing section name for option '%s'\n", opt);
 
 2546             while (*p && *p != 
':') {
 
 2551                        "Adding '%s' to the entries to show in section '%s'\n",
 
 2552                        entry, section_name);
 
 2558             show_all_entries = 1;
 
 2561         ret = 
match_section(section_name, show_all_entries, entries);
 
 2584            "Option '%s' is deprecated, use '-show_entries format=%s' instead\n",
 
 2595                 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
 
 2599     if (!strcmp(arg, 
"-"))
 
 2629     char *next, *p, *spec = 
av_strdup(interval_spec);
 
 2640     next = strchr(spec, 
'%');
 
 2682             lli = strtoll(p, &tail, 10);
 
 2683             if (*tail || lli < 0) {
 
 2685                        "Invalid or negative value '%s' for duration number of frames\n", p);
 
 2688             interval->
end = lli;
 
 2709     char *p, *spec = 
av_strdup(intervals_spec);
 
 2714     for (n = 0, p = spec; *p; p++)
 
 2719     read_intervals = 
av_malloc(n * 
sizeof(*read_intervals));
 
 2720     if (!read_intervals) {
 
 2728     for (i = 0; p; i++) {
 
 2732         next = strchr(p, 
',');
 
 2736         read_intervals[i].
id = i;
 
 2776     printf(
"%*c  %s", level * 4, 
' ', section->
name);
 
 2787     printf(
"Sections:\n" 
 2788            "W.. = Section is a wrapper (contains other sections, no local entries)\n" 
 2789            ".A. = Section contains an array of elements of the same type\n" 
 2790            "..V = Section may contain a variable number of fields with variable keys\n" 
 2791            "FLAGS NAME/UNIQUE_NAME\n" 
 2804 #define DEFINE_OPT_SHOW_SECTION(section, target_section_id)             \ 
 2805     static int opt_show_##section(const char *opt, const char *arg)     \ 
 2807         mark_section_show_entries(SECTION_ID_##target_section_id, 1, NULL); \ 
 2827       "use binary prefixes for byte units" },
 
 2829       "use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" },
 
 2831       "prettify the format of displayed values, make it more human readable" },
 
 2833       "set the output printing format (available formats are: default, compact, csv, flat, ini, json, xml)", 
"format" },
 
 2836     { 
"sections", 
OPT_EXIT, {.func_arg = 
opt_sections}, 
"print sections structure and section information, and exit" },
 
 2838     { 
"show_error",   0, {(
void*)&opt_show_error},  
"show probing error" },
 
 2839     { 
"show_format",  0, {(
void*)&opt_show_format}, 
"show format/container info" },
 
 2840     { 
"show_frames",  0, {(
void*)&opt_show_frames}, 
"show frames info" },
 
 2842       "show a particular entry from the format/container info", 
"entry" },
 
 2844       "show a set of specified entries", 
"entry_list" },
 
 2845     { 
"show_packets", 0, {(
void*)&opt_show_packets}, 
"show packets info" },
 
 2846     { 
"show_programs", 0, {(
void*)&opt_show_programs}, 
"show programs info" },
 
 2847     { 
"show_streams", 0, {(
void*)&opt_show_streams}, 
"show streams info" },
 
 2848     { 
"show_chapters", 0, {(
void*)&opt_show_chapters}, 
"show chapters info" },
 
 2851     { 
"show_program_version",  0, {(
void*)&opt_show_program_version},  
"show ffprobe version" },
 
 2852     { 
"show_library_versions", 0, {(
void*)&opt_show_library_versions}, 
"show library versions" },
 
 2853     { 
"show_versions",         0, {(
void*)&
opt_show_versions}, 
"show program and library versions" },
 
 2875 #define SET_DO_SHOW(id, varname) do {                                   \ 
 2876         if (check_section_show_entries(SECTION_ID_##id))                \ 
 2877             do_show_##varname = 1;                                      \ 
 2885     char *w_name = NULL, *w_args = NULL;
 
 2913     SET_DO_SHOW(STREAM_DISPOSITION, stream_disposition);
 
 2914     SET_DO_SHOW(PROGRAM_STREAM_DISPOSITION, stream_disposition);
 
 2924                "-bitexact and -show_program_version or -show_library_versions " 
 2925                "options are incompatible\n");
 
 2950         if (w == &xml_writer)