Permalink
Browse files

DVB Subtitles: Fix display of subs with no display segment.

The DVB subtitle standard reads:

'Within a display set the sequence of segments (when present) is:
- page composition;
- region composition;
- CLUT definition;
- object data;
- end of display segment;'

In the samples provided in #9373, the end of display segment is not
seen. The 'when present' above suggests that it is not required but the
ffmpeg code assumes it is. The workaround is to check that the previous
4 segments have been seen and, if so, process a dummy display segment.

mplayer and ffplay both appear to have the same problem.

Cherry-picked from master d27bedf

Closes #9373
  • Loading branch information...
Mark Kendall
Mark Kendall committed Jun 13, 2011
1 parent 40a3124 commit 18ab626bb4de9a487dc36f481b2d93badef30160
Showing with 11 additions and 0 deletions.
  1. +11 −0 mythtv/external/FFmpeg/libavcodec/dvbsubdec.c
@@ -1456,6 +1456,7 @@ static int dvbsub_decode(AVCodecContext *avctx,
p = buf;
p_end = buf + buf_size;
+ int gotpage, gotregion, gotclut, gotobject, gotdisplay = 0;
while (p < p_end && *p == 0x0f) {
p += 1;
segment_type = *p++;
@@ -1469,21 +1470,26 @@ static int dvbsub_decode(AVCodecContext *avctx,
switch (segment_type) {
case DVBSUB_PAGE_SEGMENT:
dvbsub_parse_page_segment(avctx, p, segment_length);
+ gotpage = 1;
break;
case DVBSUB_REGION_SEGMENT:
dvbsub_parse_region_segment(avctx, p, segment_length);
+ gotregion = 1;
break;
case DVBSUB_CLUT_SEGMENT:
dvbsub_parse_clut_segment(avctx, p, segment_length);
+ gotclut = 1;
break;
case DVBSUB_OBJECT_SEGMENT:
dvbsub_parse_object_segment(avctx, p, segment_length);
+ gotobject = 1;
break;
case DVBSUB_DISPLAYDEFINITION_SEGMENT:
dvbsub_parse_display_definition_segment(avctx, p, segment_length);
break;
case DVBSUB_DISPLAY_SEGMENT:
*data_size = dvbsub_display_end_segment(avctx, p, segment_length, sub);
+ gotdisplay = 1;
break;
default:
dprintf(avctx, "Subtitling segment type 0x%x, page id %d, length %d\n",
@@ -1495,6 +1501,11 @@ static int dvbsub_decode(AVCodecContext *avctx,
p += segment_length;
}
+ // Some streams do not send a display segment but if we have all the other
+ // segments then we need no further data. see #9373
+ if ((gotpage & gotregion & gotclut & gotobject) && !gotdisplay && sub)
+ *data_size = dvbsub_display_end_segment(avctx, p, 0, sub);
+
if (p != p_end) {
dprintf(avctx, "Junk at end of packet\n");
return -1;

0 comments on commit 18ab626

Please sign in to comment.