Address trac ticket #2636.
Stefano Sabatini authored on 2013/06/06 16:54:58... | ... |
@@ -209,6 +209,11 @@ multimedia stream. |
209 | 209 |
Each media stream information is printed within a dedicated section |
210 | 210 |
with name "STREAM". |
211 | 211 |
|
212 |
+@item -show_chapters |
|
213 |
+Show information about chapters stored in the format. |
|
214 |
+ |
|
215 |
+Each chapter is printed within a dedicated section with name "CHAPTER". |
|
216 |
+ |
|
212 | 217 |
@item -count_frames |
213 | 218 |
Count the number of frames per stream and report it in the |
214 | 219 |
corresponding stream section. |
... | ... |
@@ -11,6 +11,7 @@ |
11 | 11 |
<xsd:element name="packets" type="ffprobe:packetsType" minOccurs="0" maxOccurs="1" /> |
12 | 12 |
<xsd:element name="frames" type="ffprobe:framesType" minOccurs="0" maxOccurs="1" /> |
13 | 13 |
<xsd:element name="streams" type="ffprobe:streamsType" minOccurs="0" maxOccurs="1" /> |
14 |
+ <xsd:element name="chapters" type="ffprobe:chaptersType" minOccurs="0" maxOccurs="1" /> |
|
14 | 15 |
<xsd:element name="format" type="ffprobe:formatType" minOccurs="0" maxOccurs="1" /> |
15 | 16 |
<xsd:element name="error" type="ffprobe:errorType" minOccurs="0" maxOccurs="1" /> |
16 | 17 |
<xsd:element name="program_version" type="ffprobe:programVersionType" minOccurs="0" maxOccurs="1" /> |
... | ... |
@@ -181,6 +182,25 @@ |
181 | 181 |
<xsd:attribute name="configuration" type="xsd:string" use="required"/> |
182 | 182 |
</xsd:complexType> |
183 | 183 |
|
184 |
+ <xsd:complexType name="chaptersType"> |
|
185 |
+ <xsd:sequence> |
|
186 |
+ <xsd:element name="chapter" type="ffprobe:chapterType" minOccurs="0" maxOccurs="unbounded"/> |
|
187 |
+ </xsd:sequence> |
|
188 |
+ </xsd:complexType> |
|
189 |
+ |
|
190 |
+ <xsd:complexType name="chapterType"> |
|
191 |
+ <xsd:sequence> |
|
192 |
+ <xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/> |
|
193 |
+ </xsd:sequence> |
|
194 |
+ |
|
195 |
+ <xsd:attribute name="id" type="xsd:int" use="required"/> |
|
196 |
+ <xsd:attribute name="time_base" type="xsd:string" use="required"/> |
|
197 |
+ <xsd:attribute name="start" type="xsd:int" use="required"/> |
|
198 |
+ <xsd:attribute name="start_time" type="xsd:float"/> |
|
199 |
+ <xsd:attribute name="end" type="xsd:int" use="required"/> |
|
200 |
+ <xsd:attribute name="end_time" type="xsd:float" use="required"/> |
|
201 |
+ </xsd:complexType> |
|
202 |
+ |
|
184 | 203 |
<xsd:complexType name="libraryVersionType"> |
185 | 204 |
<xsd:attribute name="name" type="xsd:string" use="required"/> |
186 | 205 |
<xsd:attribute name="major" type="xsd:int" use="required"/> |
... | ... |
@@ -52,6 +52,7 @@ static int do_count_frames = 0; |
52 | 52 |
static int do_count_packets = 0; |
53 | 53 |
static int do_read_frames = 0; |
54 | 54 |
static int do_read_packets = 0; |
55 |
+static int do_show_chapters = 0; |
|
55 | 56 |
static int do_show_error = 0; |
56 | 57 |
static int do_show_format = 0; |
57 | 58 |
static int do_show_frames = 0; |
... | ... |
@@ -93,6 +94,9 @@ struct section { |
93 | 93 |
|
94 | 94 |
typedef enum { |
95 | 95 |
SECTION_ID_NONE = -1, |
96 |
+ SECTION_ID_CHAPTER, |
|
97 |
+ SECTION_ID_CHAPTER_TAGS, |
|
98 |
+ SECTION_ID_CHAPTERS, |
|
96 | 99 |
SECTION_ID_ERROR, |
97 | 100 |
SECTION_ID_FORMAT, |
98 | 101 |
SECTION_ID_FORMAT_TAGS, |
... | ... |
@@ -113,6 +117,9 @@ typedef enum { |
113 | 113 |
} SectionID; |
114 | 114 |
|
115 | 115 |
static struct section sections[] = { |
116 |
+ [SECTION_ID_CHAPTERS] = { SECTION_ID_CHAPTERS, "chapters", SECTION_FLAG_IS_ARRAY, { SECTION_ID_CHAPTER, -1 } }, |
|
117 |
+ [SECTION_ID_CHAPTER] = { SECTION_ID_CHAPTER, "chapter", 0, { SECTION_ID_CHAPTER_TAGS, -1 } }, |
|
118 |
+ [SECTION_ID_CHAPTER_TAGS] = { SECTION_ID_CHAPTER_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "chapter_tags" }, |
|
116 | 119 |
[SECTION_ID_ERROR] = { SECTION_ID_ERROR, "error", 0, { -1 } }, |
117 | 120 |
[SECTION_ID_FORMAT] = { SECTION_ID_FORMAT, "format", 0, { SECTION_ID_FORMAT_TAGS, -1 } }, |
118 | 121 |
[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[] = { |
126 | 126 |
[SECTION_ID_PACKET] = { SECTION_ID_PACKET, "packet", 0, { -1 } }, |
127 | 127 |
[SECTION_ID_PROGRAM_VERSION] = { SECTION_ID_PROGRAM_VERSION, "program_version", 0, { -1 } }, |
128 | 128 |
[SECTION_ID_ROOT] = { SECTION_ID_ROOT, "root", SECTION_FLAG_IS_WRAPPER, |
129 |
- { SECTION_ID_FORMAT, SECTION_ID_FRAMES, SECTION_ID_STREAMS, SECTION_ID_PACKETS, |
|
129 |
+ { SECTION_ID_CHAPTERS, SECTION_ID_FORMAT, SECTION_ID_FRAMES, SECTION_ID_STREAMS, SECTION_ID_PACKETS, |
|
130 | 130 |
SECTION_ID_ERROR, SECTION_ID_PROGRAM_VERSION, SECTION_ID_LIBRARY_VERSIONS, -1} }, |
131 | 131 |
[SECTION_ID_STREAMS] = { SECTION_ID_STREAMS, "streams", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM, -1 } }, |
132 | 132 |
[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) |
1751 | 1751 |
writer_print_section_footer(w); |
1752 | 1752 |
} |
1753 | 1753 |
|
1754 |
+static void show_chapters(WriterContext *w, AVFormatContext *fmt_ctx) |
|
1755 |
+{ |
|
1756 |
+ int i; |
|
1757 |
+ |
|
1758 |
+ writer_print_section_header(w, SECTION_ID_CHAPTERS); |
|
1759 |
+ for (i = 0; i < fmt_ctx->nb_chapters; i++) { |
|
1760 |
+ AVChapter *chapter = fmt_ctx->chapters[i]; |
|
1761 |
+ |
|
1762 |
+ writer_print_section_header(w, SECTION_ID_CHAPTER); |
|
1763 |
+ print_int("id", chapter->id); |
|
1764 |
+ print_q ("time_base", chapter->time_base, '/'); |
|
1765 |
+ print_int("start", chapter->start); |
|
1766 |
+ print_time("start_time", chapter->start, &chapter->time_base); |
|
1767 |
+ print_int("end", chapter->end); |
|
1768 |
+ print_time("end_time", chapter->end, &chapter->time_base); |
|
1769 |
+ show_tags(w, chapter->metadata, SECTION_ID_CHAPTER_TAGS); |
|
1770 |
+ writer_print_section_footer(w); |
|
1771 |
+ } |
|
1772 |
+ writer_print_section_footer(w); |
|
1773 |
+} |
|
1774 |
+ |
|
1754 | 1775 |
static void show_format(WriterContext *w, AVFormatContext *fmt_ctx) |
1755 | 1776 |
{ |
1756 | 1777 |
char val_str[128]; |
... | ... |
@@ -1911,6 +1939,8 @@ static int probe_file(WriterContext *wctx, const char *filename) |
1911 | 1911 |
} |
1912 | 1912 |
if (do_show_streams) |
1913 | 1913 |
show_streams(wctx, fmt_ctx); |
1914 |
+ if (do_show_chapters) |
|
1915 |
+ show_chapters(wctx, fmt_ctx); |
|
1914 | 1916 |
if (do_show_format) |
1915 | 1917 |
show_format(wctx, fmt_ctx); |
1916 | 1918 |
|
... | ... |
@@ -2165,6 +2195,7 @@ static int opt_show_versions(const char *opt, const char *arg) |
2165 | 2165 |
return 0; \ |
2166 | 2166 |
} |
2167 | 2167 |
|
2168 |
+DEFINE_OPT_SHOW_SECTION(chapters, CHAPTERS); |
|
2168 | 2169 |
DEFINE_OPT_SHOW_SECTION(error, ERROR); |
2169 | 2170 |
DEFINE_OPT_SHOW_SECTION(format, FORMAT); |
2170 | 2171 |
DEFINE_OPT_SHOW_SECTION(frames, FRAMES); |
... | ... |
@@ -2199,6 +2230,7 @@ static const OptionDef real_options[] = { |
2199 | 2199 |
"show a set of specified entries", "entry_list" }, |
2200 | 2200 |
{ "show_packets", 0, {(void*)&opt_show_packets}, "show packets info" }, |
2201 | 2201 |
{ "show_streams", 0, {(void*)&opt_show_streams}, "show streams info" }, |
2202 |
+ { "show_chapters", 0, {(void*)&opt_show_chapters}, "show chapters info" }, |
|
2202 | 2203 |
{ "count_frames", OPT_BOOL, {(void*)&do_count_frames}, "count the number of frames per stream" }, |
2203 | 2204 |
{ "count_packets", OPT_BOOL, {(void*)&do_count_packets}, "count the number of packets per stream" }, |
2204 | 2205 |
{ "show_program_version", 0, {(void*)&opt_show_program_version}, "show ffprobe version" }, |
... | ... |
@@ -2253,6 +2285,7 @@ int main(int argc, char **argv) |
2253 | 2253 |
parse_options(NULL, argc, argv, options, opt_input_file); |
2254 | 2254 |
|
2255 | 2255 |
/* mark things to show, based on -show_entries */ |
2256 |
+ SET_DO_SHOW(CHAPTERS, chapters); |
|
2256 | 2257 |
SET_DO_SHOW(ERROR, error); |
2257 | 2258 |
SET_DO_SHOW(FORMAT, format); |
2258 | 2259 |
SET_DO_SHOW(FRAMES, frames); |
... | ... |
@@ -2298,7 +2331,7 @@ int main(int argc, char **argv) |
2298 | 2298 |
ffprobe_show_library_versions(wctx); |
2299 | 2299 |
|
2300 | 2300 |
if (!input_filename && |
2301 |
- ((do_show_format || do_show_streams || do_show_packets || do_show_error) || |
|
2301 |
+ ((do_show_format || do_show_streams || do_show_chapters || do_show_packets || do_show_error) || |
|
2302 | 2302 |
(!do_show_program_version && !do_show_library_versions))) { |
2303 | 2303 |
show_usage(); |
2304 | 2304 |
av_log(NULL, AV_LOG_ERROR, "You have to specify one input file.\n"); |