From patchwork Wed Sep 14 18:04:08 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Campbell X-Patchwork-Id: 572 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.140.134 with SMTP id o128csp2797571vsd; Wed, 14 Sep 2016 11:16:44 -0700 (PDT) X-Received: by 10.28.215.67 with SMTP id o64mr4617010wmg.98.1473877004658; Wed, 14 Sep 2016 11:16:44 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 203si89215wmq.5.2016.09.14.11.16.43; Wed, 14 Sep 2016 11:16:44 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 26B8068A056; Wed, 14 Sep 2016 21:16:29 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from p3plsmtps2ded03.prod.phx3.secureserver.net (p3plsmtps2ded03.prod.phx3.secureserver.net [208.109.80.60]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4E8D5689F32 for ; Wed, 14 Sep 2016 21:16:22 +0300 (EEST) Received: from ip-192-169-235-64.secureserver.net ([192.169.235.64]) by : HOSTING RELAY : with SMTP id kEXZbXNRBmuNMkEXZbCb1c; Wed, 14 Sep 2016 11:04:10 -0700 x-originating-ip: 192.169.235.64 Received: from 50-245-141-73-static.hfc.comcastbusiness.net ([50.245.141.73]:34333 helo=[172.19.233.34]) by ip-192-169-235-64.secureserver.net with esmtpsa (TLSv1:DHE-RSA-CAMELLIA256-SHA:256) (Exim 4.82) (envelope-from ) id 1bkEXZ-0000oW-9R for ffmpeg-devel@ffmpeg.org; Wed, 14 Sep 2016 11:04:09 -0700 Message-ID: <57D99118.9030607@impactstudiopro.com> Date: Wed, 14 Sep 2016 11:04:08 -0700 From: Jonathan Campbell User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0 MIME-Version: 1.0 To: FFmpeg development discussions and patches References: <57D72C08.4020808@impactstudiopro.com> <20160912235650.GX4975@nb4> <57D7542F.5060103@impactstudiopro.com> <20160913025821.GZ4975@nb4> <57D83276.4030207@impactstudiopro.com> <20160914010148.GJ4975@nb4> In-Reply-To: <20160914010148.GJ4975@nb4> X-CMAE-Envelope: MS4wfOWCvnnTC6DkNPFkZbyiAqdf+zDXmBt+hLWP0USu/SiK7ks368pxo882GjbUeSWkD6B0FDsOrMfUdwukBdNlp20PaUjAhXdPQoInMMKYxYg+5l29wOSG 8bl0OWRJONOm5ChdhQ1vQOH6GjzZbqktImwd1IQ/0zcOZlp1O9HSqZpNvdJBaHtho5RYLnxSXY7rTvVPyVaCa1eVoIqJEzCI5LodPypvA0pg7yrBjI8hXALx Subject: Re: [FFmpeg-devel] mpeg12dec fix up DVD caption handling X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" > yes, please resbmit the remaining patch/changes with any comments > from everyone taken care of or with explanation why not > > thx Here you go, squashed into one patch. Sentences ending with a period have been capitalized and printf typecasts removed (Moritz). Jonathan Campbell From 8d64027573588a62728faebba55d67c00a3d4e3f Mon Sep 17 00:00:00 2001 From: Jonathan Campbell Date: Wed, 14 Sep 2016 10:57:04 -0700 Subject: [PATCH] Read cc words field-wise, limit to cc_count and support extra field. This code validates the cc words the same as the prior code this replaced in case cc_count is too large. Field counting is used in case caption source does not use the LSB to signal even/odd field. --- libavcodec/mpeg12dec.c | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index ca51c97..7c65f77 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -2265,6 +2265,7 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, /* extract DVD CC data * * uint32_t user_data_start_code 0x000001B2 (big endian) + * -------------------- p[0] starts here --------------------- * uint16_t user_identifier 0x4343 "CC" * uint8_t user_data_type_code 0x01 * uint8_t caption_block_size 0xF8 @@ -2273,7 +2274,7 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, * bit 6 caption_filler 0 * bit 5:1 caption_block_count number of caption blocks (pairs of caption words = frames). Most DVDs use 15 per start of GOP. * bit 0 caption_extra_field_added 1=one additional caption word - * + * -------------------- p[5] starts here --------------------- * struct caption_field_block { * uint8_t * bit 7:1 caption_filler 0x7F (all 1s) @@ -2287,30 +2288,48 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, * Don't assume that the first caption word is the odd field. There do exist MPEG files in the wild that start * on the even field. There also exist DVDs in the wild that encode an odd field count and the * caption_extra_field_added/caption_odd_field_first bits change per packet to allow that. */ - int cc_count = 0; + int caption_block_count = p[4] & 0x3F; /* you can treat bits 5:0 as number of fields */ + int cc_count = 0; /* number of caption fields */ int i; - // There is a caption count field in the data, but it is often - // incorrect. So count the number of captions present. - for (i = 5; i + 6 <= buf_size && ((p[i] & 0xfe) == 0xfe); i += 6) + + for (i = 5; cc_count < caption_block_count && (i + 3) <= buf_size; i += 3) { + if ((p[i] & 0xfe) != 0xfe) { + av_log(avctx, AV_LOG_DEBUG, "cc_count is too large (%d > %d) or junk data in DVD caption packet\n",caption_block_count,cc_count); + break; + } + cc_count++; + } + // Transform the DVD format into A53 Part 4 format if (cc_count > 0) { av_freep(&s1->a53_caption); - s1->a53_caption_size = cc_count * 6; + s1->a53_caption_size = cc_count * 3; s1->a53_caption = av_malloc(s1->a53_caption_size); if (s1->a53_caption) { - uint8_t field1 = !!(p[4] & 0x80); + uint8_t field1 = (p[4] >> 7) & 1; /* caption_odd_field_first */ + uint8_t pfield = 0xFF; /* DVDs that don't use the caption_field_odd bit always seem to leave it on */ uint8_t *cap = s1->a53_caption; + p += 5; for (i = 0; i < cc_count; i++) { - cap[0] = (p[0] == 0xff && field1) ? 0xfc : 0xfd; + /* If the source actually uses the caption_odd_field bit, then use that to determine the field. + * Else, toggle between fields to keep track for DVDs where p[0] == 0xFF at all times. */ + if (p[0] != pfield) + field1 = p[0] & 1; /* caption_field_odd */ + + /* in A53 part 4, 0xFC = odd field, 0xFD = even field */ + cap[0] = field1 ? 0xFC : 0xFD; cap[1] = p[1]; cap[2] = p[2]; - cap[3] = (p[3] == 0xff && !field1) ? 0xfc : 0xfd; - cap[4] = p[4]; - cap[5] = p[5]; - cap += 6; - p += 6; + + av_log(avctx, AV_LOG_DEBUG, "DVD CC field1=%u(%s) 0x%02x%02x prev=0x%02x cur=0x%02x\n", + field1,field1?"odd":"even",cap[1],cap[2],pfield,p[0]); + + pfield = p[0]; + field1 ^= 1; + cap += 3; + p += 3; } } }