From patchwork Tue Nov 19 16:12:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 16337 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 42490443FDB for ; Tue, 19 Nov 2019 18:24:10 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2314E689AB4; Tue, 19 Nov 2019 18:24:10 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f67.google.com (mail-wr1-f67.google.com [209.85.221.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 115006881A5 for ; Tue, 19 Nov 2019 18:24:04 +0200 (EET) Received: by mail-wr1-f67.google.com with SMTP id i12so24594796wro.5 for ; Tue, 19 Nov 2019 08:24:04 -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=Vlw35QVIMREejELRpFvkQ+n+hnSfgTOI1bFmgMF3wDY=; b=RDtP0S15geI0KHM4qxTdXyNn9yoqY6o0rONjaLca/YH+lombcUtU4huNcypFhslcQk 6iEBtZ6P7YKMPBgTVSOqTZ+w5c0WWo7Fdp2tJ5v8eL2Rqxu/yEw57ZpxmIQbVtuJu8NS 3prYEK3J0BoMMsV49vJ65Sq5xC1NDC/41qxicmhjiwzeYm5oR5YYdF8na3IPZJNKTfvj gUcAgH0VwAa1kY+Zp2HQCNOsNMTzbb85ZJcO2kEpCRxl2D0XJL7s7gXFLcxVxhmiVjuZ mIwLTA4h8THNRYjTjtsGIgL5Uh2+zD3weBUaRcYEKReevnJrnyC+RTn8eLyYRZIn1V7+ i9jw== 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=Vlw35QVIMREejELRpFvkQ+n+hnSfgTOI1bFmgMF3wDY=; b=duIJSFOtD2nXu2TNQBXKEE86+iDqN7IO6Rf7SiH9HutTiN1K4IJZU5HIRV8rlRppMV cH35ED1rm51LWFg7JWhYLImhqSerY5usL/VGQfXJKIym9NjzFCJdV27Uo9mgqVBk+lXa 2E9Jf5+h+4VOoIM81ldfptBBZyvgFgBj1Ys3fs8L5DP47ZC/rPHmClVUciuGNgSlN4Wr 7fYkB5mqPYp/Ug9U3VjgYMbj66604RBtSQmwVOY1TgC+Il3qDIt5dANYUlBXhpY3W6an gRlKphP2lkXcXqQxNuCtgicBLAjACjGFndXW3zLYG9r+2VUsi99sGtzRfPqLYr0TpIu+ Zwsw== X-Gm-Message-State: APjAAAW73Wq45+Mk47LtanO9uWIgYGBaS6pk3Zzv3amGJCyRyyqXZavE c4EGrCEzyJT+D5Dl/t3DqkuL0WQK X-Google-Smtp-Source: APXvYqycIBr1I/Dq0eAWyR7hBSCIhPCjmJsPuQ38wxvkQyiI2R4SNwnxsj88dRp20A8UvOYK5dKUDg== X-Received: by 2002:adf:9786:: with SMTP id s6mr26115133wrb.188.1574180287479; Tue, 19 Nov 2019 08:18:07 -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.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Nov 2019 08:18:06 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Tue, 19 Nov 2019 17:12:31 +0100 Message-Id: <20191119161234.3766-4-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 4/6] avcodec/cbs_h2645: Write slice 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" Up until now, writing the data of a slice uses an intermediate buffer into which the unit (both header as well as the rest) is assembled before being copied into a freshly allocated buffer. But given that one has a very good upper bound on the size needed before one starts copying the slice data, one can allocate the buffer in advance, copy the already written header into it and directly assemble the rest of the unit in this buffer. It proved easier to potentially allocate one byte more and decrement the size afterwards if it needs to be decremented than to calculate the exact amount in advance. It is even easier than the current way of determining whether the last byte needs to be written or not. Signed-off-by: Andreas Rheinhardt --- libavcodec/cbs_h2645.c | 64 ++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index d3d5342bad..81d0c478ec 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -1094,24 +1094,33 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, } static int cbs_h2645_write_slice_data(CodedBitstreamContext *ctx, + CodedBitstreamUnit *unit, PutBitContext *pbc, const uint8_t *data, size_t data_size, int data_bit_start) { size_t rest = data_size - (data_bit_start + 7) / 8; + int size = (put_bits_count(pbc) - data_bit_start + 7) / 8; const uint8_t *pos = data + data_bit_start / 8; + int err; av_assert0(data_bit_start >= 0 && data_size > data_bit_start / 8); - if (data_size * 8 + 8 > put_bits_left(pbc)) - return AVERROR(ENOSPC); + if (data_size > INT_MAX / 8 - size) + return AVERROR(ENOMEM); + + // size might be one too big if in- and output are misaligned. + size += data_size; + + err = ff_cbs_alloc_unit_data(ctx, unit, size); + if (err < 0) + return err; - if (!rest) - goto rbsp_stop_one_bit; + // Rebase pbc onto the new buffer. + memcpy(unit->data, pbc->buf, put_bits_ptr(pbc) - pbc->buf); + rebase_put_bits(pbc, unit->data, size); - // First copy the remaining bits of the first byte - // The above check ensures that we do not accidentally - // copy beyond the rbsp_stop_one_bit. + // First copy the remaining bits of the first byte. if (data_bit_start % 8) put_bits(pbc, 8 - data_bit_start % 8, *pos++ & MAX_UINT_BITS(8 - data_bit_start % 8)); @@ -1122,32 +1131,25 @@ static int cbs_h2645_write_slice_data(CodedBitstreamContext *ctx, // This happens normally for CABAC. flush_put_bits(pbc); memcpy(put_bits_ptr(pbc), pos, rest); - skip_put_bytes(pbc, rest); } else { // If not, we have to copy manually. - // rbsp_stop_one_bit forces us to special-case - // the last byte. - uint8_t temp; - int i; - for (; rest > 4; rest -= 4, pos += 4) + for (; rest >= 4; rest -= 4, pos += 4) put_bits32(pbc, AV_RB32(pos)); - for (; rest > 1; rest--, pos++) + for (; rest > 0; rest--, pos++) put_bits(pbc, 8, *pos); - rbsp_stop_one_bit: - temp = rest ? *pos : *pos & MAX_UINT_BITS(8 - data_bit_start % 8); + // Pad with zeroes + flush_put_bits(pbc); - av_assert0(temp); - i = ff_ctz(*pos); - temp = temp >> i; - i = rest ? (8 - i) : (8 - i - data_bit_start % 8); - put_bits(pbc, i, temp); - if (put_bits_count(pbc) % 8) - put_bits(pbc, 8 - put_bits_count(pbc) % 8, 0); + // Correct size if it is too big because of misalignment. + if (!unit->data[size - 1]) + unit->data_size = size - 1; } + unit->data_bit_padding = 0; + return 0; } @@ -1207,11 +1209,9 @@ static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx, return err; if (slice->data) { - err = cbs_h2645_write_slice_data(ctx, pbc, slice->data, - slice->data_size, - slice->data_bit_start); - if (err < 0) - return err; + return cbs_h2645_write_slice_data(ctx, unit, pbc, slice->data, + slice->data_size, + slice->data_bit_start); } else { // No slice data - that was just the header. // (Bitstream may be unaligned!) @@ -1341,11 +1341,9 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx, return err; if (slice->data) { - err = cbs_h2645_write_slice_data(ctx, pbc, slice->data, - slice->data_size, - slice->data_bit_start); - if (err < 0) - return err; + return cbs_h2645_write_slice_data(ctx, unit, pbc, slice->data, + slice->data_size, + slice->data_bit_start); } else { // No slice data - that was just the header. }