static AVDictionary *fmt_entries_to_show = NULL;
static int do_show_packets = 0;
static int do_show_streams = 0;
+static int do_show_data = 0;
static int do_show_program_version = 0;
static int do_show_library_versions = 0;
void (*print_section_header)(WriterContext *wctx, const char *);
void (*print_section_footer)(WriterContext *wctx, const char *);
void (*print_integer) (WriterContext *wctx, const char *, long long int);
+ void (*print_rational) (WriterContext *wctx, AVRational *q, char *sep);
void (*print_string) (WriterContext *wctx, const char *, const char *);
void (*show_tags) (WriterContext *wctx, AVDictionary *dict);
int flags; ///< a combination or WRITER_FLAG_*
void *priv; ///< private data for use by the filter
unsigned int nb_item; ///< number of the item printed in the given section, starting at 0
unsigned int nb_section; ///< number of the section printed in the given section sequence, starting at 0
+ unsigned int nb_section_packet; ///< number of the packet section in case we are in "packets_and_frames" section
+ unsigned int nb_section_frame; ///< number of the frame section in case we are in "packets_and_frames" section
+ unsigned int nb_section_packet_frame; ///< nb_section_packet or nb_section_frame according if is_packets_and_frames
unsigned int nb_chapter; ///< number of the chapter, starting at 0
int multiple_sections; ///< tells if the current chapter can contain multiple sections
int is_fmt_chapter; ///< tells if the current chapter is "format", required by the print_format_entry option
+ int is_packets_and_frames; ///< tells if the current section is "packets_and_frames"
};
static const char *writer_get_name(void *p)
static inline void writer_print_chapter_header(WriterContext *wctx,
const char *chapter)
{
- if (wctx->writer->print_chapter_header)
- wctx->writer->print_chapter_header(wctx, chapter);
- wctx->nb_section = 0;
-
+ wctx->nb_section =
+ wctx->nb_section_packet = wctx->nb_section_frame =
+ wctx->nb_section_packet_frame = 0;
+ wctx->is_packets_and_frames = !strcmp(chapter, "packets_and_frames");
wctx->multiple_sections = !strcmp(chapter, "packets") || !strcmp(chapter, "frames" ) ||
- !strcmp(chapter, "packets_and_frames") ||
+ wctx->is_packets_and_frames ||
!strcmp(chapter, "streams") || !strcmp(chapter, "library_versions");
wctx->is_fmt_chapter = !strcmp(chapter, "format");
+
+ if (wctx->writer->print_chapter_header)
+ wctx->writer->print_chapter_header(wctx, chapter);
}
static inline void writer_print_chapter_footer(WriterContext *wctx,
static inline void writer_print_section_header(WriterContext *wctx,
const char *section)
{
+ if (wctx->is_packets_and_frames)
+ wctx->nb_section_packet_frame = !strcmp(section, "packet") ? wctx->nb_section_packet
+ : wctx->nb_section_frame;
if (wctx->writer->print_section_header)
wctx->writer->print_section_header(wctx, section);
wctx->nb_item = 0;
{
if (wctx->writer->print_section_footer)
wctx->writer->print_section_footer(wctx, section);
+ if (wctx->is_packets_and_frames) {
+ if (!strcmp(section, "packet")) wctx->nb_section_packet++;
+ else wctx->nb_section_frame++;
+ }
wctx->nb_section++;
}
}
}
+static inline void writer_print_rational(WriterContext *wctx,
+ const char *key, AVRational q, char sep)
+{
+ AVBPrint buf;
+ av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
+ av_bprintf(&buf, "%d%c%d", q.num, sep, q.den);
+ wctx->writer->print_string(wctx, key, buf.str);
+ wctx->nb_item++;
+}
+
static inline void writer_print_string(WriterContext *wctx,
const char *key, const char *val, int opt)
{
}
static void writer_print_time(WriterContext *wctx, const char *key,
- int64_t ts, const AVRational *time_base)
+ int64_t ts, const AVRational *time_base, int is_duration)
{
char buf[128];
if (!wctx->is_fmt_chapter || !fmt_entries_to_show || av_dict_get(fmt_entries_to_show, key, NULL, 0)) {
- if (ts == AV_NOPTS_VALUE) {
+ if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) {
writer_print_string(wctx, key, "N/A", 1);
} else {
double d = ts * av_q2d(*time_base);
}
}
-static void writer_print_ts(WriterContext *wctx, const char *key, int64_t ts)
+static void writer_print_ts(WriterContext *wctx, const char *key, int64_t ts, int is_duration)
{
- if (ts == AV_NOPTS_VALUE) {
+ if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) {
writer_print_string(wctx, key, "N/A", 1);
} else {
writer_print_integer(wctx, key, ts);
wctx->writer->show_tags(wctx, dict);
}
+static void writer_print_data(WriterContext *wctx, const char *name,
+ uint8_t *data, int size)
+{
+ AVBPrint bp;
+ int offset = 0, l, i;
+
+ av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
+ av_bprintf(&bp, "\n");
+ while (size) {
+ av_bprintf(&bp, "%08x: ", offset);
+ l = FFMIN(size, 16);
+ for (i = 0; i < l; i++) {
+ av_bprintf(&bp, "%02x", data[i]);
+ if (i & 1)
+ av_bprintf(&bp, " ");
+ }
+ av_bprint_chars(&bp, ' ', 41 - 2 * i - i / 2);
+ for (i = 0; i < l; i++)
+ av_bprint_chars(&bp, data[i] - 32U < 95 ? data[i] : '.', 1);
+ av_bprintf(&bp, "\n");
+ offset += l;
+ data += l;
+ size -= l;
+ }
+ writer_print_string(wctx, name, bp.str, 0);
+ av_bprint_finalize(&bp, NULL);
+}
+
#define MAX_REGISTERED_WRITERS_NB 64
static const Writer *registered_writers[MAX_REGISTERED_WRITERS_NB + 1];
const char *p;
for (p = src; *p; p++) {
- switch (*src) {
+ switch (*p) {
case '\b': av_bprintf(dst, "%s", "\\b"); break;
case '\f': av_bprintf(dst, "%s", "\\f"); break;
case '\n': av_bprintf(dst, "%s", "\\n"); break;
.flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS,
};
+/* Flat output */
+
+typedef struct FlatContext {
+ const AVClass *class;
+ const char *section, *chapter;
+ const char *sep_str;
+ char sep;
+ int hierarchical;
+} FlatContext;
+
+#undef OFFSET
+#define OFFSET(x) offsetof(FlatContext, x)
+
+static const AVOption flat_options[]= {
+ {"sep_char", "set separator", OFFSET(sep_str), AV_OPT_TYPE_STRING, {.str="."}, CHAR_MIN, CHAR_MAX },
+ {"s", "set separator", OFFSET(sep_str), AV_OPT_TYPE_STRING, {.str="."}, CHAR_MIN, CHAR_MAX },
+ {"hierarchical", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_INT, {.dbl=1}, 0, 1 },
+ {"h", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_INT, {.dbl=1}, 0, 1 },
+ {NULL},
+};
+
+static const char *flat_get_name(void *ctx)
+{
+ return "flat";
+}
+
+static const AVClass flat_class = {
+ "FlatContext",
+ flat_get_name,
+ flat_options
+};
+
+static av_cold int flat_init(WriterContext *wctx, const char *args, void *opaque)
+{
+ FlatContext *flat = wctx->priv;
+ int err;
+
+ flat->class = &flat_class;
+ av_opt_set_defaults(flat);
+
+ if (args &&
+ (err = (av_set_options_string(flat, args, "=", ":"))) < 0) {
+ av_log(wctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
+ return err;
+ }
+ if (strlen(flat->sep_str) != 1) {
+ av_log(wctx, AV_LOG_ERROR, "Item separator '%s' specified, but must contain a single character\n",
+ flat->sep_str);
+ return AVERROR(EINVAL);
+ }
+ flat->sep = flat->sep_str[0];
+ return 0;
+}
+
+static const char *flat_escape_key_str(AVBPrint *dst, const char *src, const char sep)
+{
+ const char *p;
+
+ for (p = src; *p; p++) {
+ if (!((*p >= '0' && *p <= '9') ||
+ (*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z')))
+ av_bprint_chars(dst, '_', 1);
+ else
+ av_bprint_chars(dst, *p, 1);
+ }
+ return dst->str;
+}
+
+static const char *flat_escape_value_str(AVBPrint *dst, const char *src)
+{
+ const char *p;
+
+ for (p = src; *p; p++) {
+ switch (*p) {
+ case '\n': av_bprintf(dst, "%s", "\\n"); break;
+ case '\r': av_bprintf(dst, "%s", "\\r"); break;
+ case '\\': av_bprintf(dst, "%s", "\\\\"); break;
+ case '"': av_bprintf(dst, "%s", "\\\""); break;
+ case '`': av_bprintf(dst, "%s", "\\`"); break;
+ case '$': av_bprintf(dst, "%s", "\\$"); break;
+ default: av_bprint_chars(dst, *p, 1); break;
+ }
+ }
+ return dst->str;
+}
+
+static void flat_print_chapter_header(WriterContext *wctx, const char *chapter)
+{
+ FlatContext *flat = wctx->priv;
+ flat->chapter = chapter;
+}
+
+static void flat_print_section_header(WriterContext *wctx, const char *section)
+{
+ FlatContext *flat = wctx->priv;
+ flat->section = section;
+}
+
+static void flat_print_section(WriterContext *wctx)
+{
+ FlatContext *flat = wctx->priv;
+ int n = wctx->is_packets_and_frames ? wctx->nb_section_packet_frame
+ : wctx->nb_section;
+
+ if (flat->hierarchical && wctx->multiple_sections)
+ printf("%s%c", flat->chapter, flat->sep);
+ printf("%s%c", flat->section, flat->sep);
+ if (wctx->multiple_sections)
+ printf("%d%c", n, flat->sep);
+}
+
+static void flat_print_int(WriterContext *wctx, const char *key, long long int value)
+{
+ flat_print_section(wctx);
+ printf("%s=%lld\n", key, value);
+}
+
+static void flat_print_str(WriterContext *wctx, const char *key, const char *value)
+{
+ FlatContext *flat = wctx->priv;
+ AVBPrint buf;
+
+ flat_print_section(wctx);
+ av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
+ printf("%s=", flat_escape_key_str(&buf, key, flat->sep));
+ av_bprint_clear(&buf);
+ printf("\"%s\"\n", flat_escape_value_str(&buf, value));
+ av_bprint_finalize(&buf, NULL);
+}
+
+static void flat_show_tags(WriterContext *wctx, AVDictionary *dict)
+{
+ FlatContext *flat = wctx->priv;
+ AVBPrint buf;
+ AVDictionaryEntry *tag = NULL;
+
+ av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
+ while ((tag = av_dict_get(dict, "", tag, AV_DICT_IGNORE_SUFFIX))) {
+ flat_print_section(wctx);
+ av_bprint_clear(&buf);
+ printf("tags%c%s=", flat->sep, flat_escape_key_str(&buf, tag->key, flat->sep));
+ av_bprint_clear(&buf);
+ printf("\"%s\"\n", flat_escape_value_str(&buf, tag->value));
+ }
+ av_bprint_finalize(&buf, NULL);
+}
+
+static const Writer flat_writer = {
+ .name = "flat",
+ .priv_size = sizeof(FlatContext),
+ .init = flat_init,
+ .print_chapter_header = flat_print_chapter_header,
+ .print_section_header = flat_print_section_header,
+ .print_integer = flat_print_int,
+ .print_string = flat_print_str,
+ .show_tags = flat_show_tags,
+ .flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS|WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER,
+};
+
+/* INI format output */
+
+typedef struct {
+ const AVClass *class;
+ AVBPrint chapter_name, section_name;
+ int hierarchical;
+} INIContext;
+
+#undef OFFSET
+#define OFFSET(x) offsetof(INIContext, x)
+
+static const AVOption ini_options[] = {
+ {"hierarchical", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_INT, {.dbl=1}, 0, 1 },
+ {"h", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_INT, {.dbl=1}, 0, 1 },
+ {NULL},
+};
+
+static const char *ini_get_name(void *ctx)
+{
+ return "ini";
+}
+
+static const AVClass ini_class = {
+ "INIContext",
+ ini_get_name,
+ ini_options
+};
+
+static av_cold int ini_init(WriterContext *wctx, const char *args, void *opaque)
+{
+ INIContext *ini = wctx->priv;
+ int err;
+
+ av_bprint_init(&ini->chapter_name, 1, AV_BPRINT_SIZE_UNLIMITED);
+ av_bprint_init(&ini->section_name, 1, AV_BPRINT_SIZE_UNLIMITED);
+
+ ini->class = &ini_class;
+ av_opt_set_defaults(ini);
+
+ if (args && (err = av_set_options_string(ini, args, "=", ":")) < 0) {
+ av_log(wctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
+ return err;
+ }
+
+ return 0;
+}
+
+static av_cold void ini_uninit(WriterContext *wctx)
+{
+ INIContext *ini = wctx->priv;
+ av_bprint_finalize(&ini->chapter_name, NULL);
+ av_bprint_finalize(&ini->section_name, NULL);
+}
+
+static void ini_print_header(WriterContext *wctx)
+{
+ printf("# ffprobe output\n\n");
+}
+
+static char *ini_escape_str(AVBPrint *dst, const char *src)
+{
+ int i = 0;
+ char c = 0;
+
+ while (c = src[i++]) {
+ switch (c) {
+ case '\b': av_bprintf(dst, "%s", "\\b"); break;
+ case '\f': av_bprintf(dst, "%s", "\\f"); break;
+ case '\n': av_bprintf(dst, "%s", "\\n"); break;
+ case '\r': av_bprintf(dst, "%s", "\\r"); break;
+ case '\t': av_bprintf(dst, "%s", "\\t"); break;
+ case '\\':
+ case '#' :
+ case '=' :
+ case ':' : av_bprint_chars(dst, '\\', 1);
+ default:
+ if ((unsigned char)c < 32)
+ av_bprintf(dst, "\\x00%02x", c & 0xff);
+ else
+ av_bprint_chars(dst, c, 1);
+ break;
+ }
+ }
+ return dst->str;
+}
+
+static void ini_print_chapter_header(WriterContext *wctx, const char *chapter)
+{
+ INIContext *ini = wctx->priv;
+
+ av_bprint_clear(&ini->chapter_name);
+ av_bprintf(&ini->chapter_name, "%s", chapter);
+
+ if (wctx->nb_chapter)
+ printf("\n");
+}
+
+static void ini_print_section_header(WriterContext *wctx, const char *section)
+{
+ INIContext *ini = wctx->priv;
+ int n = wctx->is_packets_and_frames ? wctx->nb_section_packet_frame
+ : wctx->nb_section;
+ if (wctx->nb_section)
+ printf("\n");
+ av_bprint_clear(&ini->section_name);
+
+ if (ini->hierarchical && wctx->multiple_sections)
+ av_bprintf(&ini->section_name, "%s.", ini->chapter_name.str);
+ av_bprintf(&ini->section_name, "%s", section);
+
+ if (wctx->multiple_sections)
+ av_bprintf(&ini->section_name, ".%d", n);
+ printf("[%s]\n", ini->section_name.str);
+}
+
+static void ini_print_str(WriterContext *wctx, const char *key, const char *value)
+{
+ AVBPrint buf;
+
+ av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
+ printf("%s=", ini_escape_str(&buf, key));
+ av_bprint_clear(&buf);
+ printf("%s\n", ini_escape_str(&buf, value));
+ av_bprint_finalize(&buf, NULL);
+}
+
+static void ini_print_int(WriterContext *wctx, const char *key, long long int value)
+{
+ printf("%s=%lld\n", key, value);
+}
+
+static void ini_show_tags(WriterContext *wctx, AVDictionary *dict)
+{
+ INIContext *ini = wctx->priv;
+ AVDictionaryEntry *tag = NULL;
+ int is_first = 1;
+
+ while ((tag = av_dict_get(dict, "", tag, AV_DICT_IGNORE_SUFFIX))) {
+ if (is_first) {
+ printf("\n[%s.tags]\n", ini->section_name.str);
+ is_first = 0;
+ }
+ writer_print_string(wctx, tag->key, tag->value, 0);
+ }
+}
+
+static const Writer ini_writer = {
+ .name = "ini",
+ .priv_size = sizeof(INIContext),
+ .init = ini_init,
+ .uninit = ini_uninit,
+ .print_header = ini_print_header,
+ .print_chapter_header = ini_print_chapter_header,
+ .print_section_header = ini_print_section_header,
+ .print_integer = ini_print_int,
+ .print_string = ini_print_str,
+ .show_tags = ini_show_tags,
+ .flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS|WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER,
+};
+
/* JSON output */
typedef struct {
const AVClass *class;
- int print_packets_and_frames;
int indent_level;
int compact;
const char *item_sep, *item_start_end;
av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
printf("\"%s\": [\n", json_escape_str(&buf, chapter, wctx));
av_bprint_finalize(&buf, NULL);
- json->print_packets_and_frames = !strcmp(chapter, "packets_and_frames");
json->indent_level++;
}
}
printf("{%s", json->item_start_end);
json->indent_level++;
/* this is required so the parser can distinguish between packets and frames */
- if (json->print_packets_and_frames) {
+ if (wctx->is_packets_and_frames) {
if (!json->compact)
JSON_INDENT();
printf("\"type\": \"%s\"%s", section, json->item_sep);
typedef struct {
const AVClass *class;
int within_tag;
- int multiple_entries; ///< tells if the given chapter requires multiple entries
int indent_level;
int fully_qualified;
int xsd_strict;
if (wctx->nb_chapter)
printf("\n");
- xml->multiple_entries = !strcmp(chapter, "packets") || !strcmp(chapter, "frames") ||
- !strcmp(chapter, "packets_and_frames") ||
- !strcmp(chapter, "streams") || !strcmp(chapter, "library_versions");
-
- if (xml->multiple_entries) {
+ if (wctx->multiple_sections) {
XML_INDENT(); printf("<%s>\n", chapter);
xml->indent_level++;
}
{
XMLContext *xml = wctx->priv;
- if (xml->multiple_entries) {
+ if (wctx->multiple_sections) {
xml->indent_level--;
XML_INDENT(); printf("</%s>\n", chapter);
}
writer_register(&default_writer);
writer_register(&compact_writer);
writer_register(&csv_writer);
+ writer_register(&flat_writer);
+ writer_register(&ini_writer);
writer_register(&json_writer);
writer_register(&xml_writer);
}
} while (0)
#define print_int(k, v) writer_print_integer(w, k, v)
+#define print_q(k, v, s) writer_print_rational(w, k, v, s)
#define print_str(k, v) writer_print_string(w, k, v, 0)
#define print_str_opt(k, v) writer_print_string(w, k, v, 1)
-#define print_time(k, v, tb) writer_print_time(w, k, v, tb)
-#define print_ts(k, v) writer_print_ts(w, k, v)
+#define print_time(k, v, tb) writer_print_time(w, k, v, tb, 0)
+#define print_ts(k, v) writer_print_ts(w, k, v, 0)
+#define print_duration_time(k, v, tb) writer_print_time(w, k, v, tb, 1)
+#define print_duration_ts(k, v) writer_print_ts(w, k, v, 1)
#define print_val(k, v, u) writer_print_string(w, k, \
value_string(val_str, sizeof(val_str), (struct unit_value){.val.i = v, .unit=u}), 0)
#define print_section_header(s) writer_print_section_header(w, s)
print_time("pts_time", pkt->pts, &st->time_base);
print_ts ("dts", pkt->dts);
print_time("dts_time", pkt->dts, &st->time_base);
- print_ts ("duration", pkt->duration);
- print_time("duration_time", pkt->duration, &st->time_base);
+ print_duration_ts("duration", pkt->duration);
+ print_duration_time("duration_time", pkt->duration, &st->time_base);
+ print_duration_ts("convergence_duration", pkt->convergence_duration);
+ print_duration_time("convergence_duration_time", pkt->convergence_duration, &st->time_base);
print_val("size", pkt->size, unit_byte_str);
if (pkt->pos != -1) print_fmt ("pos", "%"PRId64, pkt->pos);
else print_str_opt("pos", "N/A");
print_fmt("flags", "%c", pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_');
+ if (do_show_data)
+ writer_print_data(w, "data", pkt->data, pkt->size);
print_section_footer("packet");
av_bprint_finalize(&pbuf, NULL);
print_time("pkt_pts_time", frame->pkt_pts, &stream->time_base);
print_ts ("pkt_dts", frame->pkt_dts);
print_time("pkt_dts_time", frame->pkt_dts, &stream->time_base);
+ print_duration_ts ("pkt_duration", frame->pkt_duration);
+ print_duration_time("pkt_duration_time", frame->pkt_duration, &stream->time_base);
if (frame->pkt_pos != -1) print_fmt ("pkt_pos", "%"PRId64, frame->pkt_pos);
else print_str_opt("pkt_pos", "N/A");
if (s) print_str ("pix_fmt", s);
else print_str_opt("pix_fmt", "unknown");
if (frame->sample_aspect_ratio.num) {
- print_fmt("sample_aspect_ratio", "%d:%d",
- frame->sample_aspect_ratio.num,
- frame->sample_aspect_ratio.den);
+ print_q("sample_aspect_ratio", frame->sample_aspect_ratio, ':');
} else {
print_str_opt("sample_aspect_ratio", "N/A");
}
print_int("nb_samples", frame->nb_samples);
break;
}
+ show_tags(av_frame_get_metadata(frame));
print_section_footer("frame");
int ret = 0;
*got_frame = 0;
- switch (dec_ctx->codec_type) {
- case AVMEDIA_TYPE_VIDEO:
- ret = avcodec_decode_video2(dec_ctx, frame, got_frame, pkt);
- break;
+ if (dec_ctx->codec) {
+ switch (dec_ctx->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ ret = avcodec_decode_video2(dec_ctx, frame, got_frame, pkt);
+ break;
- case AVMEDIA_TYPE_AUDIO:
- ret = avcodec_decode_audio4(dec_ctx, frame, got_frame, pkt);
- break;
+ case AVMEDIA_TYPE_AUDIO:
+ ret = avcodec_decode_audio4(dec_ctx, frame, got_frame, pkt);
+ break;
+ }
}
return ret;
s = av_get_media_type_string(dec_ctx->codec_type);
if (s) print_str ("codec_type", s);
else print_str_opt("codec_type", "unknown");
- print_fmt("codec_time_base", "%d/%d", dec_ctx->time_base.num, dec_ctx->time_base.den);
+ print_q("codec_time_base", dec_ctx->time_base, '/');
/* print AVI/FourCC tag */
av_get_codec_tag_string(val_str, sizeof(val_str), dec_ctx->codec_tag);
print_int("height", dec_ctx->height);
print_int("has_b_frames", dec_ctx->has_b_frames);
if (dec_ctx->sample_aspect_ratio.num) {
- print_fmt("sample_aspect_ratio", "%d:%d",
- dec_ctx->sample_aspect_ratio.num,
- dec_ctx->sample_aspect_ratio.den);
+ print_q("sample_aspect_ratio", dec_ctx->sample_aspect_ratio, ':');
av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
dec_ctx->width * dec_ctx->sample_aspect_ratio.num,
dec_ctx->height * dec_ctx->sample_aspect_ratio.den,
1024*1024);
- print_fmt("display_aspect_ratio", "%d:%d",
- display_aspect_ratio.num,
- display_aspect_ratio.den);
+ print_q("display_aspect_ratio", display_aspect_ratio, ':');
} else {
print_str_opt("sample_aspect_ratio", "N/A");
print_str_opt("display_aspect_ratio", "N/A");
if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS) print_fmt ("id", "0x%x", stream->id);
else print_str_opt("id", "N/A");
- print_fmt("r_frame_rate", "%d/%d", stream->r_frame_rate.num, stream->r_frame_rate.den);
- print_fmt("avg_frame_rate", "%d/%d", stream->avg_frame_rate.num, stream->avg_frame_rate.den);
- print_fmt("time_base", "%d/%d", stream->time_base.num, stream->time_base.den);
+ print_q("r_frame_rate", stream->r_frame_rate, '/');
+ print_q("avg_frame_rate", stream->avg_frame_rate, '/');
+ print_q("time_base", stream->time_base, '/');
print_time("start_time", stream->start_time, &stream->time_base);
print_time("duration", stream->duration, &stream->time_base);
if (dec_ctx->bit_rate > 0) print_val ("bit_rate", dec_ctx->bit_rate, unit_bit_per_second_str);
if (nb_streams_packets[stream_idx]) print_fmt ("nb_read_packets", "%"PRIu64, nb_streams_packets[stream_idx]);
else print_str_opt("nb_read_packets", "N/A");
show_tags(stream->metadata);
+ if (do_show_data)
+ writer_print_data(w, "extradata", dec_ctx->extradata,
+ dec_ctx->extradata_size);
print_section_footer("stream");
av_bprint_finalize(&pbuf, NULL);
AVStream *stream = fmt_ctx->streams[i];
AVCodec *codec;
- if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) {
+ if (stream->codec->codec_id == CODEC_ID_PROBE) {
+ av_log(NULL, AV_LOG_ERROR,
+ "Failed to probe codec for input stream %d\n",
+ stream->index);
+ } else if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) {
av_log(NULL, AV_LOG_ERROR,
"Unsupported codec with id %d for input stream %d\n",
stream->codec->codec_id, stream->index);
program_birth_year, this_year);
print_str("build_date", __DATE__);
print_str("build_time", __TIME__);
- print_str("compiler_type", CC_TYPE);
- print_str("compiler_version", CC_VERSION);
+ print_str("compiler_ident", CC_IDENT);
print_str("configuration", FFMPEG_CONFIGURATION);
print_section_footer("program_version");
writer_print_chapter_footer(w, "program_version");
{ "pretty", 0, {(void*)&opt_pretty},
"prettify the format of displayed values, make it more human readable" },
{ "print_format", OPT_STRING | HAS_ARG, {(void*)&print_format},
- "set the output printing format (available formats are: default, compact, csv, json, xml)", "format" },
+ "set the output printing format (available formats are: default, compact, csv, flat, ini, json, xml)", "format" },
+ { "of", OPT_STRING | HAS_ARG, {(void*)&print_format}, "alias for -print_format", "format" },
+ { "show_data", OPT_BOOL, {(void*)&do_show_data}, "show packets data" },
{ "show_error", OPT_BOOL, {(void*)&do_show_error} , "show probing error" },
{ "show_format", OPT_BOOL, {(void*)&do_show_format} , "show format/container info" },
{ "show_frames", OPT_BOOL, {(void*)&do_show_frames} , "show frames info" },