[FFmpeg-devel] [PATCH/RFC] Fix dvbsub framing inconsistencies/add dvbsub bsf

Tomas Härdin tomas.hardin
Fri Sep 24 16:28:45 CEST 2010


As you may know from IRC and my last thread on this list, I'm working on
fixing mpegts subtitle remuxing. The extradata problem was easy enough
to fix, but while writing the bitstream filter I discovered some
inconsistencies regarding the framing bytes surrounding the data the
decoder wants.

Since I don't have the specs at hand, I have been figuring this out by
looking at the code and hex dumps, and testing my results in ffplay and

I'll be using a PES packet containing 14 B of subtitle essence data as
an example. It looks like this:

00 00 01 BD 00 19 85 80 05 21 01 AB 9D CD
20 00 0F 10 00 02 00 02 01 94 0F 80 00 02 00 00 FF

That second line (20 00 ... FF) is what the demuxer outputs. That gets
stripped by dvbsub_parser to the fourteen bytes below:

0F 10 00 02 00 02 01 94 0f 80 00 02 00 00

This is the format that the decoder expects (starts with 0x0F). However,
this is not what the dvbsub encoder outputs. See dvbsub.c lines 211 and

    *q++ = 0x00; /* subtitle_stream_id */

    /* page composition segment */

    *q++ = 0x0f; /* sync_byte */
    *q++ = 0x10; /* segment_type */


    *q++ = 0xff; /* end of PES data */

In other words, the output from the encoder can not be fed into the
decoder. It also does not match what is output by the parser, but you
could also say that the parser's output does not match the encoder's.

Since the output from the encoder is typically fed straight to a muxer,
the missing 0x20 byte needs to be written before the data is written.
The hackish code relating to private_code in mpegtsenc.c takes care of

    if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
        private_code = 0x20;


    if (private_code != 0)
        *q++ = private_code;

As I understand it, there are a number of ways to fix this:

1. Add a bitstream filter that adds a 0x00 to the start and 0xFF to the
end of the subtitle packets
2. Make the encoder not add said bytes and require its output to be fed
to a bitstream filter that adds 20 00 .. FF (to which the parsed packets
are also fed). This allows simplifying the muxer (remove the
private_code stuff)
3. Patch the decoder to accept leading null bytes, and have the parser
only strip the leading 0x20 byte
4. Remove the parser and the muxer hack and have the encoder output
packets with the 20 00 .. FF framing and accept them in the decoder

I am unsure which of these solution would be most suitable. Maybe
there's a better one?

A patch that implements option 1 is attached. It passes the regtests,
and paired with the extradata patch the remuxed output is playable in
both ffplay and vlc. The downside is that the encoded packets can't be
sent to the decoder without stripping those two bytes.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: dvbsub_reformat.patch
Type: text/x-patch
Size: 4429 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100924/14c2a44c/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100924/14c2a44c/attachment.pgp>

More information about the ffmpeg-devel mailing list