Opened 3 years ago

Last modified 3 years ago

#2909 new enhancement

Make dvbsubs more compliant among stb's

Reported by: tommy2d Owned by:
Priority: normal Component: avcodec
Version: 1.2.2 Keywords: dvbsub
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description (last modified by ubitux)

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:

  1. 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);
  1. 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.

  1. 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.
  1. Implement subtitle clear packets that only contain a page composition segment (no end of display segment) and use page_state = 0x01;.
  1. Make sure actual subtitle payload packets use page_state = 0x02.
  1. 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.

Change History (8)

comment:1 Changed 3 years ago by tommy2d

  • Type changed from defect to enhancement

In bullet two, ofcource i mean dvb-subtitles 'segments'.

comment:2 in reply to: ↑ description Changed 3 years ago by cehoyos

  • Keywords dvbsub added; dvbsubs stb broadcast removed

Replying to tommy2d:

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.

Please send your changes against current git head (formatted with git format-patch to the ffmpeg-devel mailing list.
As it is, this ticket is unfortunately not very useful, sorry.

comment:3 Changed 3 years ago by ubitux

  • Description modified (diff)

Added some code quotation in the description to make it readable.

comment:4 in reply to: ↑ description Changed 3 years ago by ubitux

Replying to tommy2d:

[...]

  1. 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);

I can't find the second chunk in our codebase. For the record, the first one is from lavc/dvbsub.c.

[...]
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.

You are talking about a lot of changes, could you just send a patch? As Carl said, we can't really make much sense about what you are sharing.

And you are wrong about FFmpeg not being suitable for broadcasting purposes BTW. But OTOH the DVB subtitles support is definitely in need of some improvements, so your changes will be really appreciated.

comment:5 Changed 3 years ago by tommy2d

Thank you for the code quotations. I based the pseudo-diff on my checkout of ffmpeg 1.3, and the code can indeed be found in dvbsub.c like you mentioned.

I will try to write a patch against the current ffmpeg codebase as soon as I have the time to do so. This will most likely be after the aforementioned project is finished. Furthermore, I think I will be needing some assistance incorporating some of the more advanced features I mentioned. Especially those that require somewhat 'external' information about the encoding settings, such as video resolution and PAR/SAR.

If somebody else is willing to do some coding on the dvb subtitle encoder in the meanwhile, I will be more than happy to clarify the six todo's I mentioned in my initial post:).

I did not mean to state that ffmpeg is is not useable for broadcasting purposes. What I actually meant is that the specific inner workings of the muxer did not suit our needs. Needless to say, ffmpeg is awesome:)!

comment:6 follow-up: Changed 3 years ago by kierank

Reserved bits in DVB should be set to 1, so your first point is weird. I appreciate though that there are some very bad implementations that expect them to be 0.

comment:7 in reply to: ↑ 6 Changed 3 years ago by tommy2d

Replying to kierank:

Reserved bits in DVB should be set to 1, so your first point is weird. I appreciate though that there are some very bad implementations that expect them to be 0.

Can you point where exactly in the spec it says they should be set to 1? From what I understand, it shouldn't matter how they are set. Setting them to 0 however fixes them for all STB's I tested with.

comment:8 Changed 3 years ago by kierank

It doesn't mention it in that document but in other DVB documents you are told to set reserved bits to 1. This is what I assume the original author did.

Note: See TracTickets for help on using tickets.