Make dvbsubs more compliant among stb's
|Reported by:||Tommy2d||Owned by:|
|Blocking:||Reproduced by developer:||no|
|Analyzed by developer:||no|
Description (last modified by )
For a project I'm using avcodec to encode various dvbsubtitles and mux them in an mpeg transport stream using a self-made multiplexer.
The dvdsubtitles that are produced by avcodec are not working on some stubborn set-top-boxes (STBs). About 80% of the boxes i used to test are working. 20% is not.
I was able to create my own encoder, but with some minor changes in the dvbsubenc.c code, i was able to use ffmpeg to produce subtitles that work on 100% of the STBs we used to test. These changes are:
- Make sure all reserved bits, especially in the region composition segment, are set to 0 rather than 1:
- *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03; + *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x00; - *q++ = 0xf0 | ((y >> 8) & 0xf); + *q++ = 0x00 | ((y >> 8) & 0xf);
- Make sure all dvb-subtitles are ordered as described in the spec:
0x10 page composition segment 0x11 region composition segment 0x12 CLUT 0x13 Object data segment 0x14 DDS 0x80 end of display
Failing to do so will cause some STBs to fail selecting the proper colours from the CLUT.
- Define / calculate fixed regions that can be used again and again. Defining and/or using new regions for each subtitle, like avcodec does by default, causes some serious graphical distortion, most notably in high-end professional tandberg decoders.
- Implement subtitle clear packets that only contain a page composition segment (no end of display segment) and use page_state = 0x01;.
- Make sure actual subtitle payload packets use page_state = 0x02.
- add display defintion segments for low res subs that are muxed with HD video:
*p++ = 0x0F; //sync_byte *p++ = 0x14; //segment_type *p++ = 0x00; //page_id 1 *p++ = 0x01; //page_id 2 *p++ = 0x00; //segment_length 1 *p++ = 0x05; //segment_length 2 *p++ = 0x00;//dds_version_number + display_window_flag + reserved *p++ = (ddsWidth >> 8) & 0xFF; *p++ = ddsWidth & 0xFF; *p++ = (ddsHeight >> 8) & 0xFF; *p++ = ddsHeight & 0xFF;
That's about it. I know this feature is not used a lot, especially since the mpeg-ts muxer provided by ffmpeg is not really suitable for broadcasting purposes, but these minor changes really contribute to the compatibility of the dvbsubs that avcodec encodes.
F.y.i: this information is based on reverse-engineering highly-compatbile broadcast TS files that contain dvbsubtitles. If necessary i can deliver some raw dvbsub payloads that are tested on multiple STBs and that can used in further research and/or development.