Signed-off-by: Marton Balint <cus@passwd.hu>
Signed-off-by: Stefano Sabatini <stefasab@gmail.com>
... | ... |
@@ -197,11 +197,11 @@ The information for each single packet is printed within a dedicated |
197 | 197 |
section with name "PACKET". |
198 | 198 |
|
199 | 199 |
@item -show_frames |
200 |
-Show information about each frame contained in the input multimedia |
|
201 |
-stream. |
|
200 |
+Show information about each frame and subtitle contained in the input |
|
201 |
+multimedia stream. |
|
202 | 202 |
|
203 | 203 |
The information for each single frame is printed within a dedicated |
204 |
-section with name "FRAME". |
|
204 |
+section with name "FRAME" or "SUBTITLE". |
|
205 | 205 |
|
206 | 206 |
@item -show_streams |
207 | 207 |
Show information about each media stream contained in the input |
... | ... |
@@ -28,7 +28,10 @@ |
28 | 28 |
|
29 | 29 |
<xsd:complexType name="framesType"> |
30 | 30 |
<xsd:sequence> |
31 |
- <xsd:element name="frame" type="ffprobe:frameType" minOccurs="0" maxOccurs="unbounded"/> |
|
31 |
+ <xsd:choice minOccurs="0" maxOccurs="unbounded"> |
|
32 |
+ <xsd:element name="frame" type="ffprobe:frameType" minOccurs="0" maxOccurs="unbounded"/> |
|
33 |
+ <xsd:element name="subtitle" type="ffprobe:subtitleType" minOccurs="0" maxOccurs="unbounded"/> |
|
34 |
+ </xsd:choice> |
|
32 | 35 |
</xsd:sequence> |
33 | 36 |
</xsd:complexType> |
34 | 37 |
|
... | ... |
@@ -82,6 +85,16 @@ |
82 | 82 |
<xsd:attribute name="repeat_pict" type="xsd:int" /> |
83 | 83 |
</xsd:complexType> |
84 | 84 |
|
85 |
+ <xsd:complexType name="subtitleType"> |
|
86 |
+ <xsd:attribute name="media_type" type="xsd:string" fixed="subtitle" use="required"/> |
|
87 |
+ <xsd:attribute name="pts" type="xsd:long" /> |
|
88 |
+ <xsd:attribute name="pts_time" type="xsd:float"/> |
|
89 |
+ <xsd:attribute name="format" type="xsd:int" /> |
|
90 |
+ <xsd:attribute name="start_display_time" type="xsd:int" /> |
|
91 |
+ <xsd:attribute name="end_display_time" type="xsd:int" /> |
|
92 |
+ <xsd:attribute name="num_rects" type="xsd:int" /> |
|
93 |
+ </xsd:complexType> |
|
94 |
+ |
|
85 | 95 |
<xsd:complexType name="streamsType"> |
86 | 96 |
<xsd:sequence> |
87 | 97 |
<xsd:element name="stream" type="ffprobe:streamType" minOccurs="0" maxOccurs="unbounded"/> |
... | ... |
@@ -135,6 +135,7 @@ typedef enum { |
135 | 135 |
SECTION_ID_STREAM_DISPOSITION, |
136 | 136 |
SECTION_ID_STREAMS, |
137 | 137 |
SECTION_ID_STREAM_TAGS, |
138 |
+ SECTION_ID_SUBTITLE, |
|
138 | 139 |
} SectionID; |
139 | 140 |
|
140 | 141 |
static struct section sections[] = { |
... | ... |
@@ -144,7 +145,7 @@ static struct section sections[] = { |
144 | 144 |
[SECTION_ID_ERROR] = { SECTION_ID_ERROR, "error", 0, { -1 } }, |
145 | 145 |
[SECTION_ID_FORMAT] = { SECTION_ID_FORMAT, "format", 0, { SECTION_ID_FORMAT_TAGS, -1 } }, |
146 | 146 |
[SECTION_ID_FORMAT_TAGS] = { SECTION_ID_FORMAT_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "format_tags" }, |
147 |
- [SECTION_ID_FRAMES] = { SECTION_ID_FRAMES, "frames", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME, -1 } }, |
|
147 |
+ [SECTION_ID_FRAMES] = { SECTION_ID_FRAMES, "frames", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME, SECTION_ID_SUBTITLE, -1 } }, |
|
148 | 148 |
[SECTION_ID_FRAME] = { SECTION_ID_FRAME, "frame", 0, { SECTION_ID_FRAME_TAGS, -1 } }, |
149 | 149 |
[SECTION_ID_FRAME_TAGS] = { SECTION_ID_FRAME_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "frame_tags" }, |
150 | 150 |
[SECTION_ID_LIBRARY_VERSIONS] = { SECTION_ID_LIBRARY_VERSIONS, "library_versions", SECTION_FLAG_IS_ARRAY, { SECTION_ID_LIBRARY_VERSION, -1 } }, |
... | ... |
@@ -167,6 +168,7 @@ static struct section sections[] = { |
167 | 167 |
[SECTION_ID_STREAM] = { SECTION_ID_STREAM, "stream", 0, { SECTION_ID_STREAM_DISPOSITION, SECTION_ID_STREAM_TAGS, -1 } }, |
168 | 168 |
[SECTION_ID_STREAM_DISPOSITION] = { SECTION_ID_STREAM_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "stream_disposition" }, |
169 | 169 |
[SECTION_ID_STREAM_TAGS] = { SECTION_ID_STREAM_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "stream_tags" }, |
170 |
+ [SECTION_ID_SUBTITLE] = { SECTION_ID_SUBTITLE, "subtitle", 0, { -1 } }, |
|
170 | 171 |
}; |
171 | 172 |
|
172 | 173 |
static const OptionDef *options; |
... | ... |
@@ -1675,6 +1677,29 @@ static void show_packet(WriterContext *w, AVFormatContext *fmt_ctx, AVPacket *pk |
1675 | 1675 |
fflush(stdout); |
1676 | 1676 |
} |
1677 | 1677 |
|
1678 |
+static void show_subtitle(WriterContext *w, AVSubtitle *sub, AVStream *stream, |
|
1679 |
+ AVFormatContext *fmt_ctx) |
|
1680 |
+{ |
|
1681 |
+ AVBPrint pbuf; |
|
1682 |
+ |
|
1683 |
+ av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED); |
|
1684 |
+ |
|
1685 |
+ writer_print_section_header(w, SECTION_ID_SUBTITLE); |
|
1686 |
+ |
|
1687 |
+ print_str ("media_type", "subtitle"); |
|
1688 |
+ print_ts ("pts", sub->pts); |
|
1689 |
+ print_time("pts_time", sub->pts, &AV_TIME_BASE_Q); |
|
1690 |
+ print_int ("format", sub->format); |
|
1691 |
+ print_int ("start_display_time", sub->start_display_time); |
|
1692 |
+ print_int ("end_display_time", sub->end_display_time); |
|
1693 |
+ print_int ("num_rects", sub->num_rects); |
|
1694 |
+ |
|
1695 |
+ writer_print_section_footer(w); |
|
1696 |
+ |
|
1697 |
+ av_bprint_finalize(&pbuf, NULL); |
|
1698 |
+ fflush(stdout); |
|
1699 |
+} |
|
1700 |
+ |
|
1678 | 1701 |
static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, |
1679 | 1702 |
AVFormatContext *fmt_ctx) |
1680 | 1703 |
{ |
... | ... |
@@ -1751,6 +1776,7 @@ static av_always_inline int process_frame(WriterContext *w, |
1751 | 1751 |
AVFrame *frame, AVPacket *pkt) |
1752 | 1752 |
{ |
1753 | 1753 |
AVCodecContext *dec_ctx = fmt_ctx->streams[pkt->stream_index]->codec; |
1754 |
+ AVSubtitle sub; |
|
1754 | 1755 |
int ret = 0, got_frame = 0; |
1755 | 1756 |
|
1756 | 1757 |
avcodec_get_frame_defaults(frame); |
... | ... |
@@ -1763,6 +1789,10 @@ static av_always_inline int process_frame(WriterContext *w, |
1763 | 1763 |
case AVMEDIA_TYPE_AUDIO: |
1764 | 1764 |
ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, pkt); |
1765 | 1765 |
break; |
1766 |
+ |
|
1767 |
+ case AVMEDIA_TYPE_SUBTITLE: |
|
1768 |
+ ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_frame, pkt); |
|
1769 |
+ break; |
|
1766 | 1770 |
} |
1767 | 1771 |
} |
1768 | 1772 |
|
... | ... |
@@ -1772,9 +1802,15 @@ static av_always_inline int process_frame(WriterContext *w, |
1772 | 1772 |
pkt->data += ret; |
1773 | 1773 |
pkt->size -= ret; |
1774 | 1774 |
if (got_frame) { |
1775 |
+ int is_sub = (dec_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE); |
|
1775 | 1776 |
nb_streams_frames[pkt->stream_index]++; |
1776 | 1777 |
if (do_show_frames) |
1777 |
- show_frame(w, frame, fmt_ctx->streams[pkt->stream_index], fmt_ctx); |
|
1778 |
+ if (is_sub) |
|
1779 |
+ show_subtitle(w, &sub, fmt_ctx->streams[pkt->stream_index], fmt_ctx); |
|
1780 |
+ else |
|
1781 |
+ show_frame(w, frame, fmt_ctx->streams[pkt->stream_index], fmt_ctx); |
|
1782 |
+ if (is_sub) |
|
1783 |
+ avsubtitle_free(&sub); |
|
1778 | 1784 |
} |
1779 | 1785 |
return got_frame; |
1780 | 1786 |
} |