From patchwork Fri Mar 29 16:59:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 47655 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:9f96:b0:1a3:b6bb:3029 with SMTP id mm22csp2100175pzb; Fri, 29 Mar 2024 09:59:47 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUjmqD66XiNiqZabTrpSu3LQIOLyHxO+vNU45mAkLomUC03zXZf3t0RsnScWJ7RMqIU8W3Zt/TU3Zal6jiCIkwKGHlu8/gRvyWKJA== X-Google-Smtp-Source: AGHT+IF/aHmPNtrPIDUyek/dM/VNDf+hMXAyGLygVJd1BSq/iCjiyy+6hSAQMTpozzMxh5vGdyWi X-Received: by 2002:a05:6512:752:b0:513:1a9c:ae77 with SMTP id c18-20020a056512075200b005131a9cae77mr1772107lfs.52.1711731586967; Fri, 29 Mar 2024 09:59:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1711731586; cv=none; d=google.com; s=arc-20160816; b=FOiNBBHVuBg0UX1ffmQdmaDeLBW3jvHAz3pvivKTlTvmWGNN4nJfJYZm0TxTeYI3i/ R5jdSd/J71bAuAnd9Xzc3+CHEDfuZHZugCSf3sj1jgzuqL9MBpGV9WiGKdMnArqeP6A+ NHz9OH9TIitechbQQmODtaFBjdvLD9FTk3XCwtpFNtME+3M0AoRshEfoVX9NLFtoyM8i 1IlxvPD1OgtbspfEQ0SpBZxE4u9KnZt4vSn59uz7OLP+Lm1zGxxHZppBmFY6hYltreUq kq3KQ0/Z37GF7sHei81oxsSGrkV6EIzPEH2BaB0sfEa2bzcwf1lggXTZyAeqbwYFYOrV 0/aA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=RWMpC5WVqlbSHH8GUaUzxfG3bYNKDGRg5O2FdWw3HUM=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=O2QJ7RwGHo4e/k7EKdYb1cBx+TVURld62Ull1ZW9qwyrDjbK3nBrUQl7s7kiPG2vsK 6Zdls9Q3oH2n+pM7wI62jfwvzNIuue7wyY6l2cg+X17I5Cq8u5qqGnna7zHt6pb2+mXt hau3pgBnVZAm8wfu9hvccXf5NnxdqTBYkDF62PBnGxayEFXpV+cWkix9rYj8xo5OLeho AvovjSIwkLrccKmXbfQSVsIs9bxqIh7I53z5sDDm8sFT2rWJ7DO2lUKVoV6qqYkl8TYF pZbnLnvOhles+eaxtuU4ocnHXT2/zvwmF3zdaPhzOj1zZBMxelrj2XrIJOQ0hzLJSdjd nDhw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=jZUB8LGa; 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 o8-20020a509b08000000b0056b9efb2407si1995215edi.432.2024.03.29.09.59.46; Fri, 29 Mar 2024 09:59:46 -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=20230601 header.b=jZUB8LGa; 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 983A468D75A; Fri, 29 Mar 2024 18:59:43 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-il1-f173.google.com (mail-il1-f173.google.com [209.85.166.173]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 464C968CF14 for ; Fri, 29 Mar 2024 18:59:37 +0200 (EET) Received: by mail-il1-f173.google.com with SMTP id e9e14a558f8ab-3684faf6286so8545175ab.1 for ; Fri, 29 Mar 2024 09:59:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1711731575; x=1712336375; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=ZtM6Pp9AyiSQ+xqB5JRrmcL6IrZvJ01aforw88Q9yfQ=; b=jZUB8LGaiPNr5KwCb+AZ2CynEjx+xTmHA+BrwaI2y/diyTkju/6HnvuhTYzVJ9ZroE nx+3pBVcivZW1A9PS5UM+Nd3pcaGAySXPU01h/VTvQUggz+wpwsdubfJDUMNYUlLcvnF /CrLXxmSJNcmYfKxUQbVxb2THIk44grT90zN7c99uXSdG21l+sZksjHtkivhkkexs7k8 FXaqtD4Ne4ZvYSMS/C4/NAuHKMP520HvyVD04WcZ+zAIK/Mq8JN53fn8vKCqwHj8x+I6 IN2vTW5+jtH6cYA9K9p+IR1L6aeqAHrpV++uZ6c3yM+OPuJKSmykG7YnhqPzHrU1IdaV SZ0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711731575; x=1712336375; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZtM6Pp9AyiSQ+xqB5JRrmcL6IrZvJ01aforw88Q9yfQ=; b=MxxVtbvfeTJk43qnbwEwFAa+eeiGzJKju0k5hhf1TWUdDyGeyj5R/+dE+2Bc1u/1NQ ourNCSm06EXzRq0DpDXrRPct0Nfa36iSGs+AafSOWNsFwZPpqgL4dx1qrfTQjU/zKD26 LJIsF4J8j4Lk3XzV4K1AnEP0zmkvqlOeWqAP9wQpwEO1jKidyxNG5aLUIHiHQtnz6WbZ M0c4CiTjnwYi9cauO2uS59ITdg4WB/R2CalZezqDOBDZCJOH8ljMxhQ92uF8PxePPG24 mk/2yJZXd2L34ILOjxk8eA0hp4n7sJlMrbs9UDfqwl/nQBUAxWYrqdNI1kdl0SJK6e31 koTQ== X-Gm-Message-State: AOJu0YzMZQNDhLoYfrovBWMq6ERXNBe2STwSojJHs+EqiDybLbYDz/Lv 6VwQj9o+NGlpd+UzKtw/OLG3Zk34y8o/1Z//vrFmktjiIKkrYRfyEJnDWZm9 X-Received: by 2002:a05:6e02:1a0d:b0:368:4a3d:e8c5 with SMTP id s13-20020a056e021a0d00b003684a3de8c5mr3209817ild.15.1711731575075; Fri, 29 Mar 2024 09:59:35 -0700 (PDT) Received: from localhost.localdomain ([190.194.167.233]) by smtp.gmail.com with ESMTPSA id bw28-20020a056a02049c00b005dcaa45d87esm2793678pgb.42.2024.03.29.09.59.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Mar 2024 09:59:34 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Fri, 29 Mar 2024 13:59:10 -0300 Message-ID: <20240329165910.24999-1-jamrial@gmail.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: References: MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2] avocdec/hevc_ps: don't use a fixed sized buffer for parameter set raw data 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: T9HgbHo5PYFN Allocate it instead, and use it to compare sets instead of the parsed struct. Signed-off-by: James Almer --- libavcodec/hevc_ps.c | 127 +++++++++++++++++++++++-------------------- libavcodec/hevc_ps.h | 14 +++-- 2 files changed, 77 insertions(+), 64 deletions(-) diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 6475d86d7d..7f74553fc1 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -442,47 +442,42 @@ static int decode_hrd(GetBitContext *gb, int common_inf_present, return 0; } -static void uninit_vps(FFRefStructOpaque opaque, void *obj) +static void hevc_vps_free(FFRefStructOpaque opaque, void *obj) { HEVCVPS *vps = obj; av_freep(&vps->hdr); -} - -static int compare_vps(const HEVCVPS *vps1, const HEVCVPS *vps2) -{ - if (!memcmp(vps1, vps2, offsetof(HEVCVPS, hdr))) - return !vps1->vps_num_hrd_parameters || - !memcmp(vps1->hdr, vps2->hdr, vps1->vps_num_hrd_parameters * sizeof(*vps1->hdr)); - - return 0; + av_freep(&vps->data); } int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, HEVCParamSets *ps) { int i,j; - int vps_id = 0; - ptrdiff_t nal_size; - HEVCVPS *vps = ff_refstruct_alloc_ext(sizeof(*vps), 0, NULL, uninit_vps); + int vps_id = get_bits(gb, 4); + int ret = AVERROR_INVALIDDATA; + HEVCVPS *vps; + if (ps->pps_list[vps_id]) { + const HEVCVPS *vps1 = ps->vps_list[vps_id]; + if (vps1->data_size == gb->buffer_end - gb->buffer && + !memcmp(vps1->data, gb->buffer, vps1->data_size)) + return 0; + } + + vps = ff_refstruct_alloc_ext(sizeof(*vps), 0, NULL, hevc_vps_free); if (!vps) return AVERROR(ENOMEM); av_log(avctx, AV_LOG_DEBUG, "Decoding VPS\n"); - nal_size = gb->buffer_end - gb->buffer; - if (nal_size > sizeof(vps->data)) { - av_log(avctx, AV_LOG_WARNING, "Truncating likely oversized VPS " - "(%"PTRDIFF_SPECIFIER" > %"SIZE_SPECIFIER")\n", - nal_size, sizeof(vps->data)); - vps->data_size = sizeof(vps->data); - } else { - vps->data_size = nal_size; + vps->data_size = gb->buffer_end - gb->buffer; + vps->data = av_memdup(gb->buffer, vps->data_size); + if (!vps->data) { + ret = AVERROR(ENOMEM); + goto err; } - memcpy(vps->data, gb->buffer, vps->data_size); - - vps_id = vps->vps_id = get_bits(gb, 4); + vps->vps_id = vps_id; if (get_bits(gb, 2) != 3) { // vps_reserved_three_2bits av_log(avctx, AV_LOG_ERROR, "vps_reserved_three_2bits is not three\n"); @@ -579,19 +574,14 @@ int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, goto err; } - if (ps->vps_list[vps_id] && - compare_vps(ps->vps_list[vps_id], vps)) { - ff_refstruct_unref(&vps); - } else { remove_vps(ps, vps_id); ps->vps_list[vps_id] = vps; - } return 0; err: ff_refstruct_unref(&vps); - return AVERROR_INVALIDDATA; + return ret; } static void decode_vui(GetBitContext *gb, AVCodecContext *avctx, @@ -1294,36 +1284,43 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, return 0; } +static void hevc_sps_free(FFRefStructOpaque opaque, void *obj) +{ + HEVCSPS *sps = obj; + + av_freep(&sps->data); +} + +static int compare_sps(const HEVCSPS *sps1, const HEVCSPS *sps2) +{ + return sps1->data_size == sps2->data_size && + !memcmp(sps1->data, sps2->data, sps1->data_size); +} + int ff_hevc_decode_nal_sps(GetBitContext *gb, AVCodecContext *avctx, HEVCParamSets *ps, int apply_defdispwin) { - HEVCSPS *sps = ff_refstruct_allocz(sizeof(*sps)); + HEVCSPS *sps = ff_refstruct_alloc_ext(sizeof(*sps), 0, NULL, hevc_sps_free); unsigned int sps_id; int ret; - ptrdiff_t nal_size; if (!sps) return AVERROR(ENOMEM); av_log(avctx, AV_LOG_DEBUG, "Decoding SPS\n"); - nal_size = gb->buffer_end - gb->buffer; - if (nal_size > sizeof(sps->data)) { - av_log(avctx, AV_LOG_WARNING, "Truncating likely oversized SPS " - "(%"PTRDIFF_SPECIFIER" > %"SIZE_SPECIFIER")\n", - nal_size, sizeof(sps->data)); - sps->data_size = sizeof(sps->data); - } else { - sps->data_size = nal_size; + sps->data_size = gb->buffer_end - gb->buffer; + sps->data = av_memdup(gb->buffer, sps->data_size); + if (!sps->data) { + ret = AVERROR(ENOMEM); + goto err; } - memcpy(sps->data, gb->buffer, sps->data_size); ret = ff_hevc_parse_sps(sps, gb, &sps_id, apply_defdispwin, ps->vps_list, avctx); if (ret < 0) { - ff_refstruct_unref(&sps); - return ret; + goto err; } if (avctx->debug & FF_DEBUG_BITSTREAM) { @@ -1340,7 +1337,7 @@ int ff_hevc_decode_nal_sps(GetBitContext *gb, AVCodecContext *avctx, * original one. * otherwise drop all PPSes that depend on it */ if (ps->sps_list[sps_id] && - !memcmp(ps->sps_list[sps_id], sps, sizeof(*sps))) { + compare_sps(ps->sps_list[sps_id], sps)) { ff_refstruct_unref(&sps); } else { remove_sps(ps, sps_id); @@ -1348,6 +1345,9 @@ int ff_hevc_decode_nal_sps(GetBitContext *gb, AVCodecContext *avctx, } return 0; +err: + ff_refstruct_unref(&sps); + return ret; } static void hevc_pps_free(FFRefStructOpaque unused, void *obj) @@ -1364,6 +1364,7 @@ static void hevc_pps_free(FFRefStructOpaque unused, void *obj) av_freep(&pps->tile_pos_rs); av_freep(&pps->tile_id); av_freep(&pps->min_tb_addr_zs_tab); + av_freep(&pps->data); } static void colour_mapping_octants(GetBitContext *gb, HEVCPPS *pps, int inp_depth, @@ -1762,27 +1763,35 @@ int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx, const HEVCSPS *sps = NULL; const HEVCVPS *vps = NULL; int i, ret = 0; - unsigned int pps_id = 0; - ptrdiff_t nal_size; + unsigned int pps_id = get_ue_golomb_long(gb); unsigned log2_parallel_merge_level_minus2; + HEVCPPS *pps; + + av_log(avctx, AV_LOG_DEBUG, "Decoding PPS\n"); + + if (pps_id >= HEVC_MAX_PPS_COUNT) { + av_log(avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", pps_id); + ret = AVERROR_INVALIDDATA; + goto err; + } - HEVCPPS *pps = ff_refstruct_alloc_ext(sizeof(*pps), 0, NULL, hevc_pps_free); + if (ps->pps_list[pps_id]) { + const HEVCPPS *pps1 = ps->pps_list[pps_id]; + if (pps1->data_size == gb->buffer_end - gb->buffer && + !memcmp(pps1->data, gb->buffer, pps1->data_size)) + return 0; + } + pps = ff_refstruct_alloc_ext(sizeof(*pps), 0, NULL, hevc_pps_free); if (!pps) return AVERROR(ENOMEM); - av_log(avctx, AV_LOG_DEBUG, "Decoding PPS\n"); - - nal_size = gb->buffer_end - gb->buffer; - if (nal_size > sizeof(pps->data)) { - av_log(avctx, AV_LOG_WARNING, "Truncating likely oversized PPS " - "(%"PTRDIFF_SPECIFIER" > %"SIZE_SPECIFIER")\n", - nal_size, sizeof(pps->data)); - pps->data_size = sizeof(pps->data); - } else { - pps->data_size = nal_size; + pps->data_size = gb->buffer_end - gb->buffer; + pps->data = av_memdup(gb->buffer, pps->data_size); + if (!pps->data) { + ret = AVERROR_INVALIDDATA; + goto err; } - memcpy(pps->data, gb->buffer, pps->data_size); // Default values pps->loop_filter_across_tiles_enabled_flag = 1; @@ -1795,7 +1804,7 @@ int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx, pps->log2_max_transform_skip_block_size = 2; // Coded parameters - pps_id = pps->pps_id = get_ue_golomb_long(gb); + pps->pps_id = pps_id; if (pps_id >= HEVC_MAX_PPS_COUNT) { av_log(avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", pps_id); ret = AVERROR_INVALIDDATA; diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h index 0d8eaf2b3e..bed406770f 100644 --- a/libavcodec/hevc_ps.h +++ b/libavcodec/hevc_ps.h @@ -172,11 +172,11 @@ typedef struct HEVCVPS { int vps_num_ticks_poc_diff_one; ///< vps_num_ticks_poc_diff_one_minus1 + 1 int vps_num_hrd_parameters; - uint8_t data[4096]; - int data_size; - /* Put this at the end of the structure to make it easier to calculate the + /* Keep this at the end of the structure to make it easier to calculate the * size before this pointer, which is used for memcmp */ HEVCHdrParams *hdr; + uint8_t *data; + int data_size; } HEVCVPS; typedef struct ScalingList { @@ -299,7 +299,9 @@ typedef struct HEVCSPS { int qp_bd_offset; - uint8_t data[4096]; + /* Keep this at the end of the structure to make it easier to calculate the + * size before this pointer, which is used for memcmp */ + uint8_t *data; int data_size; } HEVCSPS; @@ -434,7 +436,9 @@ typedef struct HEVCPPS { int *min_tb_addr_zs; ///< MinTbAddrZS int *min_tb_addr_zs_tab;///< MinTbAddrZS - uint8_t data[4096]; + /* Keep this at the end of the structure to make it easier to calculate the + * size before this pointer, which is used for memcmp */ + uint8_t *data; int data_size; } HEVCPPS;