[FFmpeg-devel] [PATCH] ffprobe: decode and dump subtitles.

Stefano Sabatini stefasab at gmail.com
Wed Jul 25 01:40:54 CEST 2012


On date Tuesday 2012-07-24 18:35:56 +0200, Nicolas George encoded:
> 
> Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
> ---
>  doc/ffprobe.texi |    2 +-
>  doc/ffprobe.xsd  |   33 ++++++++++++++++++++++++-
>  ffprobe.c        |   70 ++++++++++++++++++++++++++++++++++++++++++++++++++----
>  3 files changed, 98 insertions(+), 7 deletions(-)
> 
> diff --git a/doc/ffprobe.texi b/doc/ffprobe.texi
> index cbe48a7..2fa2cdf 100644
> --- a/doc/ffprobe.texi
> +++ b/doc/ffprobe.texi
> @@ -130,7 +130,7 @@ Show information about each frame 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" for subtitles.
>  
>  @item -show_streams
>  Show information about each media stream contained in the input
> diff --git a/doc/ffprobe.xsd b/doc/ffprobe.xsd
> index 3a4a8cc..254c801 100644
> --- a/doc/ffprobe.xsd
> +++ b/doc/ffprobe.xsd
> @@ -26,7 +26,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>
>  
> @@ -77,6 +80,34 @@
>        <xsd:attribute name="reference"              type="xsd:int"   />
>      </xsd:complexType>
>  
> +    <xsd:complexType name="subtitleType">
> +        <xsd:sequence>
> +            <xsd:element name="subtitle_header" type="ffprobe:subtitleHeaderType" minOccurs="1" maxOccurs="1"/>
> +            <xsd:element name="subtitle_rectangle" type="ffprobe:subtitleRectangleType" minOccurs="0" maxOccurs="unbounded"/>
> +        </xsd:sequence>
> +    </xsd:complexType>
> +
> +    <xsd:complexType name="subtitleHeaderType">
> +      <xsd:attribute name="format"             type="xsd:int" use="required"/>
> +      <xsd:attribute name="start_display_time" type="xsd:int" use="required"/>
> +      <xsd:attribute name="end_display_time"   type="xsd:int" />
> +      <xsd:attribute name="pts"                type="xsd:long" />
> +      <xsd:attribute name="pts_time"           type="xsd:float"/>
> +      <xsd:attribute name="pkt_pts"            type="xsd:long" />
> +      <xsd:attribute name="pkt_pts_time"       type="xsd:float"/>
> +    </xsd:complexType>
> +
> +    <xsd:complexType name="subtitleRectangleType">
> +      <xsd:attribute name="type"     type="xsd:string" use="required"/>
> +      <xsd:attribute name="x"        type="xsd:int"/>
> +      <xsd:attribute name="y"        type="xsd:int" />
> +      <xsd:attribute name="w"        type="xsd:int" />
> +      <xsd:attribute name="h"        type="xsd:int" />
> +      <xsd:attribute name="text_len" type="xsd:int" />
> +      <xsd:attribute name="ass_len"  type="xsd:int" />
> +      <xsd:attribute name="forced"   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 531cea2..d7639c6 100644
> --- a/ffprobe.c
> +++ b/ffprobe.c
> @@ -263,6 +263,7 @@ static inline void writer_print_chapter_header(WriterContext *wctx,
>      wctx->nb_section_packet_frame = 0;
>      wctx->is_packets_and_frames = !strcmp(chapter, "packets_and_frames");
>      wctx->multiple_sections = !strcmp(chapter, "packets") || !strcmp(chapter, "frames" ) ||
> +                              !strcmp(chapter, "subtitle") ||
>                                wctx->is_packets_and_frames ||
>                                !strcmp(chapter, "streams") || !strcmp(chapter, "library_versions");
>      wctx->is_fmt_chapter = !strcmp(chapter, "format");
> @@ -1653,12 +1654,65 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream)
>      fflush(stdout);
>  }
>  
> +static void show_subtitle(WriterContext *w, AVSubtitle *sub, AVPacket *pkt,
> +                          AVStream *stream)
> +{
> +    AVRational tb = AV_TIME_BASE_Q;
> +    unsigned i;
> +    static const char *const type_map[] = {
> +        [SUBTITLE_NONE]   = "none",
> +        [SUBTITLE_BITMAP] = "bitmap",
> +        [SUBTITLE_TEXT]   = "text",
> +        [SUBTITLE_ASS]    = "ass",
> +    };
> +
> +    writer_print_chapter_header(w, "subtitle");

Unfortunately I believe this can't work, printing a chapter inside a
chapter may result in borken output.

What we would need are print_subsection_* hooks, a more generalized
alternative would be to implement some sort of generic
*print_section_*(..., int level) but that's much more work.

[...]
-- 
FFmpeg = Fierce & Furious Minimal Programmable Elfic Ghost


More information about the ffmpeg-devel mailing list