From patchwork Sun Dec 22 13:27:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lance Wang X-Patchwork-Id: 16922 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 6BD5844AE04 for ; Sun, 22 Dec 2019 15:27:18 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 41C886883A2; Sun, 22 Dec 2019 15:27:18 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg1-f193.google.com (mail-pg1-f193.google.com [209.85.215.193]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A60596880BD for ; Sun, 22 Dec 2019 15:27:11 +0200 (EET) Received: by mail-pg1-f193.google.com with SMTP id a33so7433754pgm.5 for ; Sun, 22 Dec 2019 05:27:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=KR/EmqHcP7Zi5rQsvcGVHa8Otc542wmKii0RZZOE9ic=; b=pcnY5nTcJ7I7UOLPYLhFWtFCV465XAg3+9lxHUvK47hVpFY1G26GLDf52SCX0YY8QU Ka+obKVOeDLgSqnoLVDKWWOL2cDZ7MCQ2mXD1Nxv76gOPyvW6tCruwrpjq+ojKWGtQHL 7B2nkv4CGoxWX0RBSZ2WR8QsGOgnGMhCnshx8b8UP1K/1sVpnE4mW095aR90A/dZ6zTS Lr9fhWnlXNj6qcgMLgy4AR670f9Y4PTC+SCdEtzlMEFR8r04aqtISuLqR0M5aMQr3FGz qBPXrn0SIx+HRkEQjfgjESVRpkh7+sq/t1MleH+2Etr6oCEF3IK4y+AagdDLBQNcB/MY KerA== 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=KR/EmqHcP7Zi5rQsvcGVHa8Otc542wmKii0RZZOE9ic=; b=QCgX/A0DQp0rw1stg8+45U+KHD1d7DSEbPAV0DdFo5Rbgoco4E3Yxg5OnJsdaZpupU OjTV2ro7izEmi5gAFjG7Up9tD7+Fd3qMd9iMjG71TAZBc+wMdFqHzuLm4FocvyNWhYK2 EQq6tr77VGGEkn0vXV86RMIxvqxDbWm179+QJ787qzcawdPvXXhW3OFt4iC1/Glz3+zH 51UNcmDAG33AukUUhqoLJVwFqtjNPHMdP91lQ6gTRDnKivVkAk1lcjwJZvG1Rsydc/ub dz2/b6Id/Ogfl+BjyRYFc0LPFjfOI30fgJpml+4EZclLcdOAipnjcI+0ybUr+/yFSuBm rKmQ== X-Gm-Message-State: APjAAAWVEcdFMotUOCm+Yq7stga5sspGfRyTBb8STkQxbbyiDO+stALV q7jN6cH34X5QWbUaDmy1N6/NQ39z X-Google-Smtp-Source: APXvYqyZaIitNqrIbyfvKKJRpLRGa2kMpNC6R3nP9sGwrKstsYW+a11dT8mlDgoc2GMhqUVsbtq7cg== X-Received: by 2002:a63:7705:: with SMTP id s5mr25568515pgc.379.1577021229227; Sun, 22 Dec 2019 05:27:09 -0800 (PST) Received: from vpn.localdomain ([47.90.99.151]) by smtp.gmail.com with ESMTPSA id e14sm21321597pfm.97.2019.12.22.05.27.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 22 Dec 2019 05:27:08 -0800 (PST) From: lance.lmwang@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Sun, 22 Dec 2019 21:27:05 +0800 Message-Id: <20191222132705.15271-1-lance.lmwang@gmail.com> X-Mailer: git-send-email 2.9.5 Subject: [FFmpeg-devel] [PATCH v1] 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 --- libavcodec/mpeg12dec.c | 73 +++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index 775579f..86cdebd 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; @@ -1630,13 +1629,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) { @@ -2238,14 +2237,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) { - av_freep(&s1->a53_caption); - s1->a53_caption_size = cc_count * 3; - s1->a53_caption = av_malloc(s1->a53_caption_size); - if (!s1->a53_caption) { - s1->a53_caption_size = 0; - } else { - memcpy(s1->a53_caption, p + 7, s1->a53_caption_size); - } + 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; @@ -2254,19 +2257,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); @@ -2318,21 +2323,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; @@ -2871,7 +2878,7 @@ static av_cold int mpeg_decode_end(AVCodecContext *avctx) if (s->mpeg_enc_ctx_allocated) ff_mpv_common_end(&s->mpeg_enc_ctx); - av_freep(&s->a53_caption); + av_buffer_unref(&s->a53_buf_ref); return 0; }