From patchwork Tue Nov 19 16:12:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 16338 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 53C41443FDB for ; Tue, 19 Nov 2019 18:24:52 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 3DB5C68A2C6; Tue, 19 Nov 2019 18:24:52 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f68.google.com (mail-wr1-f68.google.com [209.85.221.68]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id CFCAE68812A for ; Tue, 19 Nov 2019 18:24:45 +0200 (EET) Received: by mail-wr1-f68.google.com with SMTP id e6so24639213wrw.1 for ; Tue, 19 Nov 2019 08:24:45 -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:in-reply-to:references :mime-version:content-transfer-encoding; bh=B9G8F7B/BZ8PCIgButh4mHchFLmfjVx7zSf70nTG9eI=; b=jz9LTP+tyKOBQlyin4xxMVIcoCQVZp/0BD2dnvkvmVfo9p7Lgkf1iv2QAQBL3Gz8xy FCv0Rz3ghLXI0OlKGUImCPa888elsMR6P531fQcNzk8RR+Gzu1TSM5g+G0zR8A/gnDS9 6bmb3dM6JFuxkf3vGizLXcQZyeXIpCseLOKjSLEk5BavrMHLerNWk9aUNS7qT2vTvFjS Pz4lBgmyEwlPnPw/UX561Od4yIrW7DGeltKMPK233qPohjL1nJ0QPL5HjKYlYApxu7vl dd/jKNdxMh2dxLkBaUQ0B+GVXNnz1mcRRHwuAAGbIt3J3HS/xTBbu5PcbCJXOZFkpEzs dnsg== 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:in-reply-to :references:mime-version:content-transfer-encoding; bh=B9G8F7B/BZ8PCIgButh4mHchFLmfjVx7zSf70nTG9eI=; b=Qm5VItdHcGBlSt1nXg9GQbgsALXeABxCjnivTTTb3YvcnBfjeYVswzESp01y33isGW mEv3f1xzXAvHBhxS+arM/PfULIkfQ6mBnnFsl3CYsEKj9wXZ8r+mKZ+VE3j4zLdG6jMH /Txgp06HnJD7Va9OwfXN22vQocAmm2vihkdB1PwXGQ26vax831dh02tuQwuElf1ce7NS Z4yon6JkJK5mLA04OUzLzeZ5Id+P/OkieejcNCjv3abbCcnKuWCD3VZSMsiga718twbv xpUJGaVZMcseA7WxtLKCJnTAO7/U2tl7HNte3oTbB2PB/US2BDDvIA+G5McTuVQ5GQe6 J4+A== X-Gm-Message-State: APjAAAXaz0x2XAepHOxqtd5PQIPeZHBjpULI+nt0tOZjv+pJ3d3yI8+Q 51E4KZcxV/tr7zv3HCpTqUcVMUKk X-Google-Smtp-Source: APXvYqxN/8C3Pj73pFkMqd0MzRamEybUCxzedAjasaj2r9snVkG8Xbqy+TvLygv5iPlcLg1aY8JgaA== X-Received: by 2002:adf:e881:: with SMTP id d1mr29058271wrm.296.1574180290072; Tue, 19 Nov 2019 08:18:10 -0800 (PST) Received: from sblaptop.fritz.box (ipbcc08e23.dynamic.kabel-deutschland.de. [188.192.142.35]) by smtp.gmail.com with ESMTPSA id f188sm3611784wmf.3.2019.11.19.08.18.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Nov 2019 08:18:09 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Tue, 19 Nov 2019 17:12:33 +0100 Message-Id: <20191119161234.3766-6-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191119161234.3766-1-andreas.rheinhardt@gmail.com> References: <20191119161234.3766-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 6/6] avcodec/cbs_av1: Write tile data directly 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: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" This commit makes use of the fact that the final unit buffer is now allocated within write_unit to avoid a memcpy of tile data: It is now no longer copied into an intermediate buffer before being written into the final buffer, but directly written into the final buffer. Signed-off-by: Andreas Rheinhardt --- libavcodec/cbs_av1.c | 89 +++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 47 deletions(-) diff --git a/libavcodec/cbs_av1.c b/libavcodec/cbs_av1.c index 7ff5539fb8..54687f93d2 100644 --- a/libavcodec/cbs_av1.c +++ b/libavcodec/cbs_av1.c @@ -1060,28 +1060,9 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx, CodedBitstreamAV1Context *priv = ctx->priv_data; AV1RawOBU *obu = unit->content; PutBitContext pbc_tmp; - AV1RawTileData *td; - size_t header_size; - int err, start_pos, end_pos, data_pos; - - // OBUs in the normal bitstream format must contain a size field - // in every OBU (in annex B it is optional, but we don't support - // writing that). - obu->header.obu_has_size_field = 1; - - err = cbs_av1_write_obu_header(ctx, pbc, &obu->header); - if (err < 0) - return err; - - if (obu->header.obu_has_size_field) { - pbc_tmp = *pbc; - // Add space for the size field to fill later. - put_bits32(pbc, 0); - put_bits32(pbc, 0); - } - - td = NULL; - start_pos = put_bits_count(pbc); + AV1RawTileData *td = NULL; + size_t header_size, obu_header_size, size, td_offset; + int err, end_pos; priv->ref = (AV1ReferenceFrameState *)&priv->write_ref; @@ -1168,8 +1149,9 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx, } end_pos = put_bits_count(pbc); - header_size = (end_pos - start_pos + 7) / 8; + header_size = (end_pos + 7) / 8; if (td) { + // The possible overflow here is checked below. obu->obu_size = header_size + td->data_size; } else if (header_size > 0) { // Add trailing bits and recalculate. @@ -1177,47 +1159,60 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx, if (err < 0) return err; end_pos = put_bits_count(pbc); - obu->obu_size = header_size = (end_pos - start_pos + 7) / 8; + obu->obu_size = header_size = (end_pos + 7) / 8; } else { // Empty OBU. obu->obu_size = 0; } - end_pos = put_bits_count(pbc); // Must now be byte-aligned. av_assert0(end_pos % 8 == 0); flush_put_bits(pbc); - start_pos /= 8; - end_pos /= 8; - *pbc = pbc_tmp; - err = cbs_av1_write_leb128(ctx, pbc, "obu_size", obu->obu_size); + obu_header_size = 1 + !!obu->header.obu_extension_flag + + (av_log2(obu->obu_size) + 7) / 7; + + // The size of everything except the tile data. + size = td_offset = obu_header_size + header_size; + + if (td) { + if (td->data_size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE + - size) + return AVERROR(ENOMEM); + + // If we are here, header_size + td->data_size fits into an int, + // so a fortiori no overflow happened in the calculation of + // obu->obu_size which also fits in an int. + size += td->data_size; + } + + err = ff_cbs_alloc_unit_data(ctx, unit, size); if (err < 0) return err; - data_pos = put_bits_count(pbc) / 8; - flush_put_bits(pbc); - av_assert0(data_pos <= start_pos); + unit->data_bit_padding = 0; - if (8 * obu->obu_size > put_bits_left(pbc)) - return AVERROR(ENOSPC); + init_put_bits(&pbc_tmp, unit->data, obu_header_size); - if (obu->obu_size > 0) { - memmove(pbc->buf + data_pos, - pbc->buf + start_pos, header_size); - skip_put_bytes(pbc, header_size); + // OBUs in the normal bitstream format must contain a size field + // in every OBU (in annex B it is optional, but we don't support + // writing that). + obu->header.obu_has_size_field = 1; - if (td) { - memcpy(pbc->buf + data_pos + header_size, - td->data, td->data_size); - skip_put_bytes(pbc, td->data_size); - } - } + err = cbs_av1_write_obu_header(ctx, &pbc_tmp, &obu->header); + if (err < 0) + return err; - // OBU data must be byte-aligned. - av_assert0(put_bits_count(pbc) % 8 == 0); + err = cbs_av1_write_leb128(ctx, &pbc_tmp, "obu_size", obu->obu_size); + av_assert0(err >= 0 && put_bits_left(&pbc_tmp) == 0); + flush_put_bits(&pbc_tmp); - return ff_cbs_default_write_unit_data(ctx, unit, pbc); + memcpy(unit->data + obu_header_size, pbc->buf, header_size); + + if (td) + memcpy(unit->data + td_offset, td->data, td->data_size); + + return 0; } static int cbs_av1_assemble_fragment(CodedBitstreamContext *ctx,