diff options
author | Stefano Sabatini <stefasab@gmail.com> | 2013-06-06 09:54:58 +0200 |
---|---|---|
committer | Stefano Sabatini <stefasab@gmail.com> | 2013-06-06 16:49:53 +0200 |
commit | 4da5402256cf01bf130169ff30fdc13d097a0508 (patch) | |
tree | 67409eeb9634a81b07f8c9c49889c43b4c359780 | |
parent | 21d0f75f29ca97b2ca31bd4451f488163a27e24f (diff) | |
download | ffmpeg-4da5402256cf01bf130169ff30fdc13d097a0508.tar.gz |
ffprobe: show chapter and chapter metadata information
Address trac ticket #2636.
-rw-r--r-- | Changelog | 1 | ||||
-rw-r--r-- | doc/ffprobe.texi | 5 | ||||
-rw-r--r-- | doc/ffprobe.xsd | 20 | ||||
-rw-r--r-- | ffprobe.c | 37 |
4 files changed, 61 insertions, 2 deletions
@@ -64,6 +64,7 @@ version <next>: - Go2Webinar decoder - mcdeint filter ported from libmpcodecs - sab filter ported from libmpcodecs +- ffprobe -show_chapters option version 1.2: diff --git a/doc/ffprobe.texi b/doc/ffprobe.texi index 01e9829148..38517a8890 100644 --- a/doc/ffprobe.texi +++ b/doc/ffprobe.texi @@ -209,6 +209,11 @@ multimedia stream. Each media stream information is printed within a dedicated section with name "STREAM". +@item -show_chapters +Show information about chapters stored in the format. + +Each chapter is printed within a dedicated section with name "CHAPTER". + @item -count_frames Count the number of frames per stream and report it in the corresponding stream section. diff --git a/doc/ffprobe.xsd b/doc/ffprobe.xsd index eab97fb4c4..bd890b1fd0 100644 --- a/doc/ffprobe.xsd +++ b/doc/ffprobe.xsd @@ -11,6 +11,7 @@ <xsd:element name="packets" type="ffprobe:packetsType" minOccurs="0" maxOccurs="1" /> <xsd:element name="frames" type="ffprobe:framesType" minOccurs="0" maxOccurs="1" /> <xsd:element name="streams" type="ffprobe:streamsType" minOccurs="0" maxOccurs="1" /> + <xsd:element name="chapters" type="ffprobe:chaptersType" minOccurs="0" maxOccurs="1" /> <xsd:element name="format" type="ffprobe:formatType" minOccurs="0" maxOccurs="1" /> <xsd:element name="error" type="ffprobe:errorType" minOccurs="0" maxOccurs="1" /> <xsd:element name="program_version" type="ffprobe:programVersionType" minOccurs="0" maxOccurs="1" /> @@ -181,6 +182,25 @@ <xsd:attribute name="configuration" type="xsd:string" use="required"/> </xsd:complexType> + <xsd:complexType name="chaptersType"> + <xsd:sequence> + <xsd:element name="chapter" type="ffprobe:chapterType" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="chapterType"> + <xsd:sequence> + <xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + + <xsd:attribute name="id" type="xsd:int" use="required"/> + <xsd:attribute name="time_base" type="xsd:string" use="required"/> + <xsd:attribute name="start" type="xsd:int" use="required"/> + <xsd:attribute name="start_time" type="xsd:float"/> + <xsd:attribute name="end" type="xsd:int" use="required"/> + <xsd:attribute name="end_time" type="xsd:float" use="required"/> + </xsd:complexType> + <xsd:complexType name="libraryVersionType"> <xsd:attribute name="name" type="xsd:string" use="required"/> <xsd:attribute name="major" type="xsd:int" use="required"/> @@ -52,6 +52,7 @@ static int do_count_frames = 0; static int do_count_packets = 0; static int do_read_frames = 0; static int do_read_packets = 0; +static int do_show_chapters = 0; static int do_show_error = 0; static int do_show_format = 0; static int do_show_frames = 0; @@ -93,6 +94,9 @@ struct section { typedef enum { SECTION_ID_NONE = -1, + SECTION_ID_CHAPTER, + SECTION_ID_CHAPTER_TAGS, + SECTION_ID_CHAPTERS, SECTION_ID_ERROR, SECTION_ID_FORMAT, SECTION_ID_FORMAT_TAGS, @@ -113,6 +117,9 @@ typedef enum { } SectionID; static struct section sections[] = { + [SECTION_ID_CHAPTERS] = { SECTION_ID_CHAPTERS, "chapters", SECTION_FLAG_IS_ARRAY, { SECTION_ID_CHAPTER, -1 } }, + [SECTION_ID_CHAPTER] = { SECTION_ID_CHAPTER, "chapter", 0, { SECTION_ID_CHAPTER_TAGS, -1 } }, + [SECTION_ID_CHAPTER_TAGS] = { SECTION_ID_CHAPTER_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "chapter_tags" }, [SECTION_ID_ERROR] = { SECTION_ID_ERROR, "error", 0, { -1 } }, [SECTION_ID_FORMAT] = { SECTION_ID_FORMAT, "format", 0, { SECTION_ID_FORMAT_TAGS, -1 } }, [SECTION_ID_FORMAT_TAGS] = { SECTION_ID_FORMAT_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "format_tags" }, @@ -126,7 +133,7 @@ static struct section sections[] = { [SECTION_ID_PACKET] = { SECTION_ID_PACKET, "packet", 0, { -1 } }, [SECTION_ID_PROGRAM_VERSION] = { SECTION_ID_PROGRAM_VERSION, "program_version", 0, { -1 } }, [SECTION_ID_ROOT] = { SECTION_ID_ROOT, "root", SECTION_FLAG_IS_WRAPPER, - { SECTION_ID_FORMAT, SECTION_ID_FRAMES, SECTION_ID_STREAMS, SECTION_ID_PACKETS, + { SECTION_ID_CHAPTERS, SECTION_ID_FORMAT, SECTION_ID_FRAMES, SECTION_ID_STREAMS, SECTION_ID_PACKETS, SECTION_ID_ERROR, SECTION_ID_PROGRAM_VERSION, SECTION_ID_LIBRARY_VERSIONS, -1} }, [SECTION_ID_STREAMS] = { SECTION_ID_STREAMS, "streams", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM, -1 } }, [SECTION_ID_STREAM] = { SECTION_ID_STREAM, "stream", 0, { SECTION_ID_STREAM_DISPOSITION, SECTION_ID_STREAM_TAGS, -1 } }, @@ -1751,6 +1758,27 @@ static void show_streams(WriterContext *w, AVFormatContext *fmt_ctx) writer_print_section_footer(w); } +static void show_chapters(WriterContext *w, AVFormatContext *fmt_ctx) +{ + int i; + + writer_print_section_header(w, SECTION_ID_CHAPTERS); + for (i = 0; i < fmt_ctx->nb_chapters; i++) { + AVChapter *chapter = fmt_ctx->chapters[i]; + + writer_print_section_header(w, SECTION_ID_CHAPTER); + print_int("id", chapter->id); + print_q ("time_base", chapter->time_base, '/'); + print_int("start", chapter->start); + print_time("start_time", chapter->start, &chapter->time_base); + print_int("end", chapter->end); + print_time("end_time", chapter->end, &chapter->time_base); + show_tags(w, chapter->metadata, SECTION_ID_CHAPTER_TAGS); + writer_print_section_footer(w); + } + writer_print_section_footer(w); +} + static void show_format(WriterContext *w, AVFormatContext *fmt_ctx) { char val_str[128]; @@ -1911,6 +1939,8 @@ static int probe_file(WriterContext *wctx, const char *filename) } if (do_show_streams) show_streams(wctx, fmt_ctx); + if (do_show_chapters) + show_chapters(wctx, fmt_ctx); if (do_show_format) show_format(wctx, fmt_ctx); @@ -2165,6 +2195,7 @@ static int opt_show_versions(const char *opt, const char *arg) return 0; \ } +DEFINE_OPT_SHOW_SECTION(chapters, CHAPTERS); DEFINE_OPT_SHOW_SECTION(error, ERROR); DEFINE_OPT_SHOW_SECTION(format, FORMAT); DEFINE_OPT_SHOW_SECTION(frames, FRAMES); @@ -2199,6 +2230,7 @@ static const OptionDef real_options[] = { "show a set of specified entries", "entry_list" }, { "show_packets", 0, {(void*)&opt_show_packets}, "show packets info" }, { "show_streams", 0, {(void*)&opt_show_streams}, "show streams info" }, + { "show_chapters", 0, {(void*)&opt_show_chapters}, "show chapters info" }, { "count_frames", OPT_BOOL, {(void*)&do_count_frames}, "count the number of frames per stream" }, { "count_packets", OPT_BOOL, {(void*)&do_count_packets}, "count the number of packets per stream" }, { "show_program_version", 0, {(void*)&opt_show_program_version}, "show ffprobe version" }, @@ -2253,6 +2285,7 @@ int main(int argc, char **argv) parse_options(NULL, argc, argv, options, opt_input_file); /* mark things to show, based on -show_entries */ + SET_DO_SHOW(CHAPTERS, chapters); SET_DO_SHOW(ERROR, error); SET_DO_SHOW(FORMAT, format); SET_DO_SHOW(FRAMES, frames); @@ -2298,7 +2331,7 @@ int main(int argc, char **argv) ffprobe_show_library_versions(wctx); if (!input_filename && - ((do_show_format || do_show_streams || do_show_packets || do_show_error) || + ((do_show_format || do_show_streams || do_show_chapters || do_show_packets || do_show_error) || (!do_show_program_version && !do_show_library_versions))) { show_usage(); av_log(NULL, AV_LOG_ERROR, "You have to specify one input file.\n"); |