From patchwork Wed Apr 27 08:49:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Baykalov <4rusxg@gmail.com> X-Patchwork-Id: 35445 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:3b9e:b0:7d:cfb5:dc7c with SMTP id b30csp2863560pzh; Wed, 27 Apr 2022 01:50:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxwUZ9VZrLj+vxLIAircQMB5HDS84mrT2vAnKAaWD0dD0SdU8mDIF4sBIDjvUDawSIq3A08 X-Received: by 2002:a05:6402:1d4a:b0:425:e356:36e7 with SMTP id dz10-20020a0564021d4a00b00425e35636e7mr16488182edb.172.1651049413827; Wed, 27 Apr 2022 01:50:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1651049413; cv=none; d=google.com; s=arc-20160816; b=rqq9MaqMxLmp9HEy37pjn3rOEgwAuBZzDuyGDPPSsvNjT/HLekhpoyc7aHZhGZ6O53 H/UCQUCZPRsU76n8pwoYf9suEGTvZuBfMw3MiiW2j2S5drRnp6wPPsDzn2e47ZJnreX9 bQoO0+YgAADiavoUa+P39yXc/dotGAEFrFIISS4HyhpaAcOY9hE0DxOfcN5t7vnbrii0 UWOlFpPYAcd06CXvMGvF8TVDXsOQrDQIdd20VbQ/YbLKK00n3goEiXg2b9BDeuZYij/E vdDZ3ogW+tf+3u+mLG/hsq+t3sP28J6w0obYcLxP7ni8jH131w7rdrVamzFqsyrNNowf cjkg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=8nRN5rwn4/iAhftn+Vj+k5fszz1DpiNz2EIrDO6he2E=; b=hn8iOadymB+g0EkN2SL7SdLIjJZ0pC5rD9RCjwsM/J9KZ0sFdamyBUMOgNADWBYTlC zbXJqOlACrR4rvWnVewKndExfU7QCQM2+GX7+lIzkFGbivVMzvMcwaY2r6xzSMStBz/W vEkMemMxI1ZpLDa8nx+GAhf8jf2jatK4QZLs59aXTSJNfPLQpbmbv0HfVF4HK0bdpmzJ dsa5Ovbl2aQ7xrQif/jpfGfbl6m45kYeQnAnheM8bt20x/89h9rjiTQ3Z4aN0xNDdryA g1fmuS+t1bOB9mdOSLuqzCtOsOfyAfv/tQWJAux1Vaih/C+CeVrqjxRTPs02KRXFLnSU 5z6Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=qZWNz9Bk; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id mc9-20020a170906eb4900b006e8a20ff3e7si627716ejb.297.2022.04.27.01.50.13; Wed, 27 Apr 2022 01:50:13 -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; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=qZWNz9Bk; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 84C3668B3A8; Wed, 27 Apr 2022 11:50:10 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf1-f53.google.com (mail-lf1-f53.google.com [209.85.167.53]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4069F68B384 for ; Wed, 27 Apr 2022 11:50:04 +0300 (EEST) Received: by mail-lf1-f53.google.com with SMTP id k12so1899309lfr.9 for ; Wed, 27 Apr 2022 01:50:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=h1rAj1FR8Oq0y979Hz01xpQAhZBQphY99MdC8QSLKxM=; b=qZWNz9BkTctjeIEhSffR1EkiaeB33Z38QBpd3pVmPoVzxTjAd058YvQm4T/1A4i+IN GQBaGYQeP+JYVUa4YrrmkYPZOzMc7w55jOeCDOFyuMb/UCkU25/onx1yHTx9ooQq3lzx wyFxjQWOm33+eWskgS2FGx6+ENA+nOnSju4JAmjqBFt2zoUFdeg+/z3WVgovGRRIJquD iiPZtCO/dvdZ+IgxqsRcKizTxRvhZBeq5ZgLT9jIXTSIKZMbD4HoWYl/KioGRryhzbu6 rvpzcmLgYbVH7Y+jVVkL4CeUQnssEkXtzwfTlciLISR9fqVBXnE/2V8+PXOBYlHSs6dm xYjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=h1rAj1FR8Oq0y979Hz01xpQAhZBQphY99MdC8QSLKxM=; b=3cUmV+jufC6AurP4DcRWejb6FaSz58+4ZcxukSZeUiW2MRgTkomFulk3RWu86jdTPs sms6OnCkYPwljBOY0qglx4BPMUdM/lfuLBo4B77YOtHnQVpqB2e21BrLlNOHdr9bB9il y170DgnBdp/EKqhCsQFaX/pvNO380+ncfSMn2cq97b2weqhRH585nAeBFYenKD7W406p jzLyv0SWK++4hdmuxgJCqZD944bIEJEBF4t1+7hZPyRlh2Szd43jfjerlNG2AT5gNCIY +y7zueI+j/mU/YMwbz3/lPLDc/q9BLGmt5U63G248P/9khaOryOHkGtxHjVK+VUPn0DC 6dqQ== X-Gm-Message-State: AOAM5317KsOaB1kHHnKzC4ZExoHgO2HQcsjnFMDcd1U6de5R1TxT0dKJ tJfKYN0R2C5jgC2AVXsv3f6XRfbKdsA= X-Received: by 2002:a19:dc0f:0:b0:439:702c:d83b with SMTP id t15-20020a19dc0f000000b00439702cd83bmr19769539lfg.192.1651049403143; Wed, 27 Apr 2022 01:50:03 -0700 (PDT) Received: from localhost.localdomain ([95.188.97.28]) by smtp.gmail.com with ESMTPSA id n17-20020a19d611000000b00471b3db1166sm1991346lfg.119.2022.04.27.01.50.02 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Wed, 27 Apr 2022 01:50:02 -0700 (PDT) From: Ivan Baykalov <4rusxg@gmail.com> To: ffmpeg-devel@ffmpeg.org Date: Wed, 27 Apr 2022 15:49:49 +0700 Message-Id: <20220427084949.73931-1-4rusxg@gmail.com> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] libavcodec/mpeg12dec: extract embedded CC of particular type only X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Cc: Ivan Baykalov <4rusxg@gmail.com> Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 6xuxpquYyvdK Some streams contain closed caption data embedded using several wrapping types. For example stream can contain CC wrapped as ATSC A53 packets + the same data wrapped as SCTE-20 packets. Prior to the patch CC data was extracted from both types of packets, so it gave duplicated character pairs on the output. Now we calculate some statistics which CC types appear more often in the stream and extract the data from a single type only. If at some point the other CC type becomes more active, we switch to this new type. Fixes ticket #9724. --- libavcodec/mpeg12dec.c | 44 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index e9bde48f7a..f7e54ef0a9 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -58,6 +58,14 @@ #define A53_MAX_CC_COUNT 2000 +typedef enum CcType { + CC_TYPE_UNKNOWN = -1, + CC_TYPE_A53 = 0, + CC_TYPE_SCTE20, + CC_TYPE_DVD, + CC_TYPE_COUNT +} CcType; + typedef struct Mpeg1Context { MpegEncContext mpeg_enc_ctx; int mpeg_enc_ctx_allocated; /* true if decoding context allocated */ @@ -81,6 +89,7 @@ typedef struct Mpeg1Context { int first_slice; int extradata_decoded; int64_t timecode_frame_start; /*< GOP timecode frame start number, in non drop frame format */ + int cc_packet_count[CC_TYPE_COUNT]; } Mpeg1Context; #define MB_TYPE_ZERO_MV 0x20000000 @@ -2198,6 +2207,32 @@ static int vcr2_init_sequence(AVCodecContext *avctx) return 0; } +static int cc_type_is_selected(Mpeg1Context *s1, CcType type) +{ + int max = 0; + int max_index = -1; + int sum = 0; + av_assert0(type >= 0 && type < CC_TYPE_COUNT); + s1->cc_packet_count[type]++; + + for (int i = 0; i < CC_TYPE_COUNT; i++) { + if (s1->cc_packet_count[i] > max) { + max = s1->cc_packet_count[i]; + max_index = i; + } + sum += s1->cc_packet_count[i]; + } + + if (sum < 2 || sum > 20) { + // reset statistics, but give some advantage to the current selection + // to avoid frequent switching between the types + memset(s1->cc_packet_count, 0, sizeof(s1->cc_packet_count)); + s1->cc_packet_count[max_index] = 2; + } + + return type == max_index; +} + static int mpeg_decode_a53_cc(AVCodecContext *avctx, const uint8_t *p, int buf_size) { @@ -2217,6 +2252,9 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, if (new_size > 3*A53_MAX_CC_COUNT) return AVERROR(EINVAL); + if (!cc_type_is_selected(s1, CC_TYPE_A53)) + return 0; + ret = av_buffer_realloc(&s1->a53_buf_ref, new_size); if (ret >= 0) memcpy(s1->a53_buf_ref->data + old_size, p + 7, cc_count * UINT64_C(3)); @@ -2240,6 +2278,9 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, if (new_size > 3*A53_MAX_CC_COUNT) return AVERROR(EINVAL); + if (!cc_type_is_selected(s1, CC_TYPE_SCTE20)) + return 0; + ret = av_buffer_realloc(&s1->a53_buf_ref, new_size); if (ret >= 0) { uint8_t field, cc1, cc2; @@ -2310,6 +2351,9 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, if (new_size > 3*A53_MAX_CC_COUNT) return AVERROR(EINVAL); + if (!cc_type_is_selected(s1, CC_TYPE_DVD)) + return 0; + ret = av_buffer_realloc(&s1->a53_buf_ref, new_size); if (ret >= 0) { uint8_t field1 = !!(p[4] & 0x80);