From patchwork Sun Jun 21 13:30:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lance Wang X-Patchwork-Id: 20538 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id DF55A44B65B for ; Sun, 21 Jun 2020 16:30:26 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id BD03C68B737; Sun, 21 Jun 2020 16:30:26 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf1-f195.google.com (mail-pf1-f195.google.com [209.85.210.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B2B4A68B5E8 for ; Sun, 21 Jun 2020 16:30:19 +0300 (EEST) Received: by mail-pf1-f195.google.com with SMTP id d66so7051365pfd.6 for ; Sun, 21 Jun 2020 06:30:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=Wt/ThiMnI6PyvAqWiaPiZL8/mBQeM51UJN8WKDoaEWg=; b=AvMvKWX2M3H9Mpp+hKtD9bEH2HMCJbN0+ug4pZ1j8uMEn9CXcdD5HVCPyF02drVqnL CbPtLwRhNtfzFeSfTYknMEbLtFMlWaiMWXH9IXoD5I2t6m+ArPtp6erfZT0NBL0dZtdj HL1EnHoYmYqlqPGhoYNbgbDWUdvsc4K6Pax4GetBqgMopsSmJ/5701Yze9kWk9r5/k+S ETOA48GgBAHUFbXE5ghAnG1Ar7+PBtXh+Ctb4D/g5URgdwlhwO4fV0FDwkC7z6Bn3bks p9dm/LVYMtneuhiDxYfVJakvwJ9g0whguVa5uVAT77DjRFnpOcsnXsfVrkP2U1+tIlyA hCeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=Wt/ThiMnI6PyvAqWiaPiZL8/mBQeM51UJN8WKDoaEWg=; b=FYlmUCj0/6+7l3zTVGLNaZQRmh3H9Hu7nG8QOHjbzTTtfl8t/e1vEC6GVOZvocEDbt o9a7REDze6Y4Y8cAn8dTqi6eJsqM2/UoRA+GxVW0ZewWJqY5nVCrIjuTcvbplysTNtsV OK3DfWRl+7e2J5jNswwCPRROzgCewvJWmzyJNSHYOI+E+XRv/AGBPVXniz7Y75J+8V/U 9QiY/hGXpUPmcRgn7c66YtoznJeaTHZCUu1jXlTA5wfDcRBJYEoFxzTftRJ8sKH6thQz HYRNCBROkIeBWNyNEmcGFz0s6EB40vri9i3hLAPzh1U5Aeorpu0XXWAntd64GMUbb3cr jJ3A== X-Gm-Message-State: AOAM531JQPEI+yhcJScwrW1SeYWoFwjU2d89ELhZ81oGF1dRjrXKBI8F qcRXijry+as9CUynO8+5qZLaHW0M X-Google-Smtp-Source: ABdhPJwaCnXr/a6ZPgZAtNLrOZRRDRnFKWGM8PuGU4in2REJVIRw98UzirVmkLAJN8Ts3B8A/qEFxw== X-Received: by 2002:a63:4e62:: with SMTP id o34mr9562617pgl.208.1592746217327; Sun, 21 Jun 2020 06:30:17 -0700 (PDT) Received: from vpn2.localdomain ([161.117.202.209]) by smtp.gmail.com with ESMTPSA id p12sm8899420pgk.40.2020.06.21.06.30.15 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 21 Jun 2020 06:30:16 -0700 (PDT) From: lance.lmwang@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Sun, 21 Jun 2020 21:30:12 +0800 Message-Id: <1592746212-28284-1-git-send-email-lance.lmwang@gmail.com> X-Mailer: git-send-email 1.8.3.1 Subject: [FFmpeg-devel] [PATCH v2] avcodec/mpeg12dec: switch to AVBufferRef buffer for a53 caption 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 Cc: Limin Wang MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Limin Wang Signed-off-by: Limin Wang --- It's old patch, rebase with master, now have tested with the mpeg2 sample for ticket 6105, the output srt is same. libavcodec/mpeg12dec.c | 85 ++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 45 deletions(-) diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index 1253bde..f0f92ac 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -57,8 +57,7 @@ typedef struct Mpeg1Context { AVPanScan pan_scan; /* some temporary storage for the panscan */ AVStereo3D stereo3d; int has_stereo3d; - uint8_t *a53_caption; - int a53_caption_size; + AVBufferRef *a53_buf_ref; uint8_t afd; int has_afd; int slice_count; @@ -1635,13 +1634,13 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size) return AVERROR(ENOMEM); memcpy(pan_scan->data, &s1->pan_scan, sizeof(s1->pan_scan)); - if (s1->a53_caption) { - AVFrameSideData *sd = av_frame_new_side_data( + if (s1->a53_buf_ref) { + AVFrameSideData *sd = av_frame_new_side_data_from_buf( s->current_picture_ptr->f, AV_FRAME_DATA_A53_CC, - s1->a53_caption_size); - if (sd) - memcpy(sd->data, s1->a53_caption, s1->a53_caption_size); - av_freep(&s1->a53_caption); + s1->a53_buf_ref); + if (!sd) + av_buffer_unref(&s1->a53_buf_ref); + s1->a53_buf_ref = NULL; } if (s1->has_stereo3d) { @@ -2242,26 +2241,18 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, /* extract A53 Part 4 CC data */ int cc_count = p[5] & 0x1f; if (cc_count > 0 && buf_size >= 7 + cc_count * 3) { - if (s1->a53_caption && s1->a53_caption_size > 0) { - uint8_t *old_a53_caption = s1->a53_caption; - int old_a53_caption_size = s1->a53_caption_size; - - s1->a53_caption_size = old_a53_caption_size + cc_count * 3; - s1->a53_caption = av_malloc(s1->a53_caption_size); - if (s1->a53_caption) { - memcpy(s1->a53_caption, old_a53_caption, old_a53_caption_size); - memcpy(s1->a53_caption + old_a53_caption_size, p + 7, cc_count * 3); - } - av_freep(&old_a53_caption); - } else { - s1->a53_caption_size = cc_count * 3; - s1->a53_caption = av_malloc(s1->a53_caption_size); - if (s1->a53_caption) - memcpy(s1->a53_caption, p + 7, s1->a53_caption_size); - } - if (!s1->a53_caption) { - s1->a53_caption_size = 0; - } + int old_size = s1->a53_buf_ref ? s1->a53_buf_ref->size : 0; + const uint64_t new_size = (old_size + cc_count + * UINT64_C(3)); + int ret; + + if (new_size > INT_MAX) + return AVERROR(EINVAL); + + 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)); + avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; } return 1; @@ -2270,19 +2261,21 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, /* extract SCTE-20 CC data */ GetBitContext gb; int cc_count = 0; - int i; + int i, ret; init_get_bits(&gb, p + 2, buf_size - 2); cc_count = get_bits(&gb, 5); if (cc_count > 0) { - av_freep(&s1->a53_caption); - s1->a53_caption_size = cc_count * 3; - s1->a53_caption = av_mallocz(s1->a53_caption_size); - if (!s1->a53_caption) { - s1->a53_caption_size = 0; - } else { + int old_size = s1->a53_buf_ref ? s1->a53_buf_ref->size : 0; + const uint64_t new_size = (old_size + cc_count + * UINT64_C(3)); + if (new_size > INT_MAX) + return AVERROR(EINVAL); + + ret = av_buffer_realloc(&s1->a53_buf_ref, new_size); + if (ret >= 0) { uint8_t field, cc1, cc2; - uint8_t *cap = s1->a53_caption; + uint8_t *cap = s1->a53_buf_ref->data; for (i = 0; i < cc_count && get_bits_left(&gb) >= 26; i++) { skip_bits(&gb, 2); // priority field = get_bits(&gb, 2); @@ -2334,21 +2327,23 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, * 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 i; + int i, ret; // 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) 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 = av_malloc(s1->a53_caption_size); - if (!s1->a53_caption) { - s1->a53_caption_size = 0; - } else { + int old_size = s1->a53_buf_ref ? s1->a53_buf_ref->size : 0; + const uint64_t new_size = (old_size + cc_count + * UINT64_C(6)); + if (new_size > INT_MAX) + return AVERROR(EINVAL); + + ret = av_buffer_realloc(&s1->a53_buf_ref, new_size); + if (ret >= 0) { uint8_t field1 = !!(p[4] & 0x80); - uint8_t *cap = s1->a53_caption; + uint8_t *cap = s1->a53_buf_ref->data; p += 5; for (i = 0; i < cc_count; i++) { cap[0] = (p[0] == 0xff && field1) ? 0xfc : 0xfd; @@ -2886,7 +2881,7 @@ static av_cold int mpeg_decode_end(AVCodecContext *avctx) Mpeg1Context *s = avctx->priv_data; ff_mpv_common_end(&s->mpeg_enc_ctx); - av_freep(&s->a53_caption); + av_buffer_unref(&s->a53_buf_ref); return 0; }