From patchwork Sun Nov 17 07:34:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 16301 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 83F834499FD for ; Sun, 17 Nov 2019 09:35:31 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7281268A61E; Sun, 17 Nov 2019 09:35:31 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f66.google.com (mail-wm1-f66.google.com [209.85.128.66]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id F3EEE68A485 for ; Sun, 17 Nov 2019 09:35:23 +0200 (EET) Received: by mail-wm1-f66.google.com with SMTP id b17so15282742wmj.2 for ; Sat, 16 Nov 2019 23:35:23 -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=a6hEudPQxUF+SjoLp38KnTq6kEom/gLpSVIc1JR6mzw=; b=a4q7Hr90QhB0SzHHRdEZnWyXZ7nClNdsYjq1lgbuZ22rzpSKNviZRRkXQ+wiTV2zV5 vAB4+HpW3iMa9foWzkYhrh3bbvUMVsSyP7Rny3A2/lFu3N6yMwuBoMDqS5kjklWfFruQ 5kfPXlokyoAT42BQ/W2nW1dj9AqyPGUQSfQ+VxcMMR7OmaQZ0QVCwuapinNs18w+I7KP t830fsIFvPb93ShioEYtaYJDT6EnsNKmvNdg3bkJhX4jl6V17rsdu5fBCgat/h4MGhUE JZbO96idMqZwIqNz9l3YXKTFxVYf71rDV1ABodtQNq3Ksie8YiK+6HBZAJCwaYIsOWPd bPbg== 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=a6hEudPQxUF+SjoLp38KnTq6kEom/gLpSVIc1JR6mzw=; b=OssyNRxzdHXmzsN4Eav725FUFCser7XSwpTvh1JQr9cXSlG7PCOA4yO9JYToRRFA+M WYVfN3Z8je0rz6DGihnaj5n7Q1rQGfx4MlGZJa2ZeldcA7jebUJup+UH+kHbMozP3w/U UXOSbOr1HC0utNtSchCrRr20is0o3evvIg9vZzUBmDQj0XvlF0DVfPWdgLqTMeNmPZ2d bpmOmF0ID3SxgDd4tixx/royE4PnIzqNuCI4RbRcc8VBwJ3nPmTQL5SErChsK3BJAVrk nKN1hiZ7dq3+esuCyW9X8mGbNDRMRkA7w4Q0KIE4SFVcFnx/4GF4wHoDW9kfbYFnD9/H 4YNA== X-Gm-Message-State: APjAAAXhcfDwd+1ocvrQvThRORp+6aiAx7t0zMJIqTWnKZ+tmv8UoJer sjwhT3BKHZWcI1MovvUtwKCVAcD5uqs= X-Google-Smtp-Source: APXvYqwlQKsJyH4iM5ac6k8xG5fWexxt1nvGkzdKixP2MeGFKoWm+xUvEqpIGU8XaPf7l7iAungWrA== X-Received: by 2002:a1c:560b:: with SMTP id k11mr25443068wmb.153.1573976123026; Sat, 16 Nov 2019 23:35:23 -0800 (PST) Received: from sblaptop.fritz.box (ipbcc08e23.dynamic.kabel-deutschland.de. [188.192.142.35]) by smtp.gmail.com with ESMTPSA id q15sm16713082wmq.0.2019.11.16.23.35.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 16 Nov 2019 23:35:21 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Sun, 17 Nov 2019 08:34:38 +0100 Message-Id: <20191117073440.22718-5-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191117073440.22718-1-andreas.rheinhardt@gmail.com> References: <20191117073440.22718-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 | 65 ++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index 88fa0029cd..c946ca5893 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); - if (!rest) - goto rbsp_stop_one_bit; + // 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; - // 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. + // 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. if (data_bit_start % 8) put_bits(pbc, 8 - data_bit_start % 8, *pos++ & MAX_UINT_BITS(8 - data_bit_start % 8)); @@ -1122,33 +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); + 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; } - return 0; + unit->data_bit_padding = 0; + + return 1; } static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx, @@ -1207,11 +1208,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 +1340,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. }