[FFmpeg-devel] [PATCH] ffprobe: show chapter and chapter metadata information

Stefano Sabatini stefasab at gmail.com
Thu Jun 6 11:23:13 CEST 2013


Address trac ticket #2636.
---
 doc/ffprobe.xsd |   18 ++++++++++++++++++
 ffprobe.c       |   29 +++++++++++++++++++++++++++--
 2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/doc/ffprobe.xsd b/doc/ffprobe.xsd
index eab97fb..559b62a 100644
--- a/doc/ffprobe.xsd
+++ b/doc/ffprobe.xsd
@@ -148,6 +148,7 @@
 
     <xsd:complexType name="formatType">
       <xsd:sequence>
+        <xsd:element name="chapters" type="ffprobe:chaptersType" minOccurs="0" maxOccurs="1"/>
         <xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
       </xsd:sequence>
 
@@ -161,6 +162,23 @@
       <xsd:attribute name="bit_rate"         type="xsd:long"/>
     </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="end"       type="xsd:int" use="required"/>
+    </xsd:complexType>
+
     <xsd:complexType name="tagType">
       <xsd:attribute name="key"   type="xsd:string" use="required"/>
       <xsd:attribute name="value" type="xsd:string" use="required"/>
diff --git a/ffprobe.c b/ffprobe.c
index 4d2d3e1..b5f4773 100644
--- a/ffprobe.c
+++ b/ffprobe.c
@@ -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,8 +117,11 @@ 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] =             { SECTION_ID_FORMAT, "format", 0, { SECTION_ID_FORMAT_TAGS, SECTION_ID_CHAPTERS, -1 } },
     [SECTION_ID_FORMAT_TAGS] =        { SECTION_ID_FORMAT_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "format_tags" },
     [SECTION_ID_FRAMES] =             { SECTION_ID_FRAMES, "frames", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME, -1 } },
     [SECTION_ID_FRAME] =              { SECTION_ID_FRAME, "frame", 0, { SECTION_ID_FRAME_TAGS, -1 } },
@@ -1733,7 +1740,6 @@ static void show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_i
     PRINT_DISPOSITION(ATTACHED_PIC,     "attached_pic");
     writer_print_section_footer(w);
     }
-
     show_tags(w, stream->metadata, SECTION_ID_STREAM_TAGS);
 
     writer_print_section_footer(w);
@@ -1770,6 +1776,24 @@ static void show_format(WriterContext *w, AVFormatContext *fmt_ctx)
     else           print_str_opt("size", "N/A");
     if (fmt_ctx->bit_rate > 0) print_val    ("bit_rate", fmt_ctx->bit_rate, unit_bit_per_second_str);
     else                       print_str_opt("bit_rate", "N/A");
+
+    if (do_show_chapters) {
+        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_int("end", chapter->end);
+            show_tags(w, chapter->metadata, SECTION_ID_CHAPTER_TAGS);
+            writer_print_section_footer(w);
+        }
+        writer_print_section_footer(w);
+    }
     show_tags(w, fmt_ctx->metadata, SECTION_ID_FORMAT_TAGS);
 
     writer_print_section_footer(w);
@@ -2254,6 +2278,7 @@ int main(int argc, char **argv)
 
     /* mark things to show, based on -show_entries */
     SET_DO_SHOW(ERROR, error);
+    SET_DO_SHOW(CHAPTERS, chapters);
     SET_DO_SHOW(FORMAT, format);
     SET_DO_SHOW(FRAMES, frames);
     SET_DO_SHOW(LIBRARY_VERSIONS, library_versions);
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list