[FFmpeg-cvslog] ffprobe: add support for subtitle frames
Marton Balint
git at videolan.org
Mon Nov 25 19:52:46 CET 2013
ffmpeg | branch: master | Marton Balint <cus at passwd.hu> | Sun Nov 24 15:09:52 2013 +0100| [a02860351db5e06ff960a77e542b076dde7f6797] | committer: Stefano Sabatini
ffprobe: add support for subtitle frames
Signed-off-by: Marton Balint <cus at passwd.hu>
Signed-off-by: Stefano Sabatini <stefasab at gmail.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a02860351db5e06ff960a77e542b076dde7f6797
---
doc/ffprobe.texi | 6 +++---
doc/ffprobe.xsd | 15 ++++++++++++++-
ffprobe.c | 40 ++++++++++++++++++++++++++++++++++++++--
3 files changed, 55 insertions(+), 6 deletions(-)
diff --git a/doc/ffprobe.texi b/doc/ffprobe.texi
index 2e9bfee..75d1e72 100644
--- a/doc/ffprobe.texi
+++ b/doc/ffprobe.texi
@@ -197,11 +197,11 @@ The information for each single packet is printed within a dedicated
section with name "PACKET".
@item -show_frames
-Show information about each frame contained in the input multimedia
-stream.
+Show information about each frame and subtitle contained in the input
+multimedia stream.
The information for each single frame is printed within a dedicated
-section with name "FRAME".
+section with name "FRAME" or "SUBTITLE".
@item -show_streams
Show information about each media stream contained in the input
diff --git a/doc/ffprobe.xsd b/doc/ffprobe.xsd
index 6a48ff4..cc3d1b6 100644
--- a/doc/ffprobe.xsd
+++ b/doc/ffprobe.xsd
@@ -28,7 +28,10 @@
<xsd:complexType name="framesType">
<xsd:sequence>
- <xsd:element name="frame" type="ffprobe:frameType" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="frame" type="ffprobe:frameType" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="subtitle" type="ffprobe:subtitleType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
</xsd:sequence>
</xsd:complexType>
@@ -82,6 +85,16 @@
<xsd:attribute name="repeat_pict" type="xsd:int" />
</xsd:complexType>
+ <xsd:complexType name="subtitleType">
+ <xsd:attribute name="media_type" type="xsd:string" fixed="subtitle" use="required"/>
+ <xsd:attribute name="pts" type="xsd:long" />
+ <xsd:attribute name="pts_time" type="xsd:float"/>
+ <xsd:attribute name="format" type="xsd:int" />
+ <xsd:attribute name="start_display_time" type="xsd:int" />
+ <xsd:attribute name="end_display_time" type="xsd:int" />
+ <xsd:attribute name="num_rects" type="xsd:int" />
+ </xsd:complexType>
+
<xsd:complexType name="streamsType">
<xsd:sequence>
<xsd:element name="stream" type="ffprobe:streamType" minOccurs="0" maxOccurs="unbounded"/>
diff --git a/ffprobe.c b/ffprobe.c
index 3b6c173..1842452 100644
--- a/ffprobe.c
+++ b/ffprobe.c
@@ -135,6 +135,7 @@ typedef enum {
SECTION_ID_STREAM_DISPOSITION,
SECTION_ID_STREAMS,
SECTION_ID_STREAM_TAGS,
+ SECTION_ID_SUBTITLE,
} SectionID;
static struct section sections[] = {
@@ -144,7 +145,7 @@ static struct section sections[] = {
[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" },
- [SECTION_ID_FRAMES] = { SECTION_ID_FRAMES, "frames", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME, -1 } },
+ [SECTION_ID_FRAMES] = { SECTION_ID_FRAMES, "frames", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME, SECTION_ID_SUBTITLE, -1 } },
[SECTION_ID_FRAME] = { SECTION_ID_FRAME, "frame", 0, { SECTION_ID_FRAME_TAGS, -1 } },
[SECTION_ID_FRAME_TAGS] = { SECTION_ID_FRAME_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "frame_tags" },
[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[] = {
[SECTION_ID_STREAM] = { SECTION_ID_STREAM, "stream", 0, { SECTION_ID_STREAM_DISPOSITION, SECTION_ID_STREAM_TAGS, -1 } },
[SECTION_ID_STREAM_DISPOSITION] = { SECTION_ID_STREAM_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "stream_disposition" },
[SECTION_ID_STREAM_TAGS] = { SECTION_ID_STREAM_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "stream_tags" },
+ [SECTION_ID_SUBTITLE] = { SECTION_ID_SUBTITLE, "subtitle", 0, { -1 } },
};
static const OptionDef *options;
@@ -1675,6 +1677,29 @@ static void show_packet(WriterContext *w, AVFormatContext *fmt_ctx, AVPacket *pk
fflush(stdout);
}
+static void show_subtitle(WriterContext *w, AVSubtitle *sub, AVStream *stream,
+ AVFormatContext *fmt_ctx)
+{
+ AVBPrint pbuf;
+
+ av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
+
+ writer_print_section_header(w, SECTION_ID_SUBTITLE);
+
+ print_str ("media_type", "subtitle");
+ print_ts ("pts", sub->pts);
+ print_time("pts_time", sub->pts, &AV_TIME_BASE_Q);
+ print_int ("format", sub->format);
+ print_int ("start_display_time", sub->start_display_time);
+ print_int ("end_display_time", sub->end_display_time);
+ print_int ("num_rects", sub->num_rects);
+
+ writer_print_section_footer(w);
+
+ av_bprint_finalize(&pbuf, NULL);
+ fflush(stdout);
+}
+
static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
AVFormatContext *fmt_ctx)
{
@@ -1751,6 +1776,7 @@ static av_always_inline int process_frame(WriterContext *w,
AVFrame *frame, AVPacket *pkt)
{
AVCodecContext *dec_ctx = fmt_ctx->streams[pkt->stream_index]->codec;
+ AVSubtitle sub;
int ret = 0, got_frame = 0;
avcodec_get_frame_defaults(frame);
@@ -1763,6 +1789,10 @@ static av_always_inline int process_frame(WriterContext *w,
case AVMEDIA_TYPE_AUDIO:
ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, pkt);
break;
+
+ case AVMEDIA_TYPE_SUBTITLE:
+ ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_frame, pkt);
+ break;
}
}
@@ -1772,9 +1802,15 @@ static av_always_inline int process_frame(WriterContext *w,
pkt->data += ret;
pkt->size -= ret;
if (got_frame) {
+ int is_sub = (dec_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE);
nb_streams_frames[pkt->stream_index]++;
if (do_show_frames)
- show_frame(w, frame, fmt_ctx->streams[pkt->stream_index], fmt_ctx);
+ if (is_sub)
+ show_subtitle(w, &sub, fmt_ctx->streams[pkt->stream_index], fmt_ctx);
+ else
+ show_frame(w, frame, fmt_ctx->streams[pkt->stream_index], fmt_ctx);
+ if (is_sub)
+ avsubtitle_free(&sub);
}
return got_frame;
}
More information about the ffmpeg-cvslog
mailing list