From aed032c25b08a1056c03bd2646d8482f5c0aba73 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Wed, 25 Jul 2012 19:45:16 +0200 Subject: [PATCH] dvbsub: fix encoding of termination packets. The old code generates a termination packet with the same regions as the start packet and page_state set to "only what changed"; the result is that the termination packet is decoded as identical to the start packet. The new code does as found in some DVB broadcasts: produce a packet with no regions. This is done by expecting num_rects to be 0 rather than using a flip-flop. ffmpeg.c is updated accordingly. --- ffmpeg.c | 2 ++ libavcodec/dvbsub.c | 16 +++++----------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index ea90ada0ae..b2963bbad0 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -703,6 +703,8 @@ static void do_subtitle_out(AVFormatContext *s, sub->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q); sub->end_display_time -= sub->start_display_time; sub->start_display_time = 0; + if (i == 1) + sub->num_rects = 0; subtitle_out_size = avcodec_encode_subtitle(enc, subtitle_out, subtitle_out_max_size, sub); if (subtitle_out_size < 0) { diff --git a/libavcodec/dvbsub.c b/libavcodec/dvbsub.c index 8a688d09f1..a9f5e18151 100644 --- a/libavcodec/dvbsub.c +++ b/libavcodec/dvbsub.c @@ -23,7 +23,6 @@ #include "libavutil/colorspace.h" typedef struct DVBSubtitleContext { - int hide_state; int object_version; } DVBSubtitleContext; @@ -259,7 +258,7 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, page_id = 1; - if (h->num_rects == 0 || h->rects == NULL) + if (h->num_rects && h->rects == NULL) return -1; *q++ = 0x00; /* subtitle_stream_id */ @@ -272,10 +271,7 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, pseg_len = q; q += 2; /* segment length */ *q++ = 30; /* page_timeout (seconds) */ - if (s->hide_state) - page_state = 0; /* normal case */ - else - page_state = 2; /* mode change */ + page_state = 2; /* mode change */ /* page_version = 0 + page_state */ *q++ = (s->object_version << 4) | (page_state << 2) | 3; @@ -288,7 +284,7 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, bytestream_put_be16(&pseg_len, q - pseg_len - 2); - if (!s->hide_state) { + if (h->num_rects) { for (clut_id = 0; clut_id < h->num_rects; clut_id++) { /* CLUT segment */ @@ -366,18 +362,17 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, *q++ = 0; /* 8 bit fill colors */ *q++ = 0x03; /* 4 bit and 2 bit fill colors */ - if (!s->hide_state) { + /* TODO reindent */ bytestream_put_be16(&q, region_id); /* object_id == region_id */ *q++ = (0 << 6) | (0 << 4); *q++ = 0; *q++ = 0xf0; *q++ = 0; - } bytestream_put_be16(&pseg_len, q - pseg_len - 2); } - if (!s->hide_state) { + if (h->num_rects) { for (object_id = 0; object_id < h->num_rects; object_id++) { void (*dvb_encode_rle)(uint8_t **pq, @@ -446,7 +441,6 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, *q++ = 0xff; /* end of PES data */ s->object_version = (s->object_version + 1) & 0xf; - s->hide_state = !s->hide_state; return q - outbuf; }