From patchwork Tue Nov 19 16:12:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 16339 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 4DA48443FDB for ; Tue, 19 Nov 2019 18:25:00 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 38DFD68A454; Tue, 19 Nov 2019 18:25:00 +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 818CC689AB4 for ; Tue, 19 Nov 2019 18:24:54 +0200 (EET) Received: by mail-wr1-f67.google.com with SMTP id b18so23150997wrj.8 for ; Tue, 19 Nov 2019 08:24:54 -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=7Sih5ZQRv71oFqr7aDsJU1jQbsuNde41CsKpvbuEDFg=; b=iuUx/1iQcUm1GIORgt3eSyzfD+16EplOufTWb+Gpo/IsUGOY4tDsCe1bRjc3h1bSfX 9vnxkiHxquNMOe24t0m3YkaSCxzC+WMADGngPIiavjKNx6Fvd3045/VUunl6ZuiaDBSR 73Feir6rjg/2IxQlItxZogl4CIZOexkfL5pfRhps3glESthRXjSW1XEVohMpZyS6Pa8i V/KbsxAfBlmHHsnbw94qIi4sPLcEDrGBKoH5DALF8C/TytzEPMezOvaqmGCbTYnljqw7 8BbOkM4pZuTuKXJXQWmFWIVToQGh0gtuJhJRs9MtG7WXzWzMR3E2CWxkTdHvH23c/Scs x3HA== 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=7Sih5ZQRv71oFqr7aDsJU1jQbsuNde41CsKpvbuEDFg=; b=oi4ZHNyAYOwPTDSOFGXCNAx0pLP+CKTvroMc+Thk7tHt6NZjBZMfkXHEoahvwFQQGA NmLbzvXu5HrO2NUtshVGtujWgvX+K3dRQE6ibToapB47ws4nfd1hitFjb5ZdLgcT/i9y IwBzXAyTBOJ+BOOM4R5MvvWDuOxhD5geivPoJXZZFt9XP2AnvUaNzMRe3Il8jxUwx+Fd F+hOkEnU30G1iuGFuiUK48UAhmp/4m5tWlBFbr211uhpmGt68KVpjgHZvjVaXb9LcJtL TJwTg1ZRuZbBTnPUFjSCW/ekQeaKSHQ26I33UHoEPLkM1QfsKyjjBfjX1TTyTE6iG1Sk nH1g== X-Gm-Message-State: APjAAAXjGAlCv++vslFX2vqmoSIdaCesotn5Ow3ImnU6dbxyxFqFXIXy MiY2G19moJaKuCKQkg9mNFf5cXuU X-Google-Smtp-Source: APXvYqwvKo+Pt+5m+KTumCbWqhA0otNP6GT+hkygLK7YiJL7GPrwE0xtbVe9uT4h4p8rHNLAh+9Jbg== X-Received: by 2002:a5d:670a:: with SMTP id o10mr29459530wru.312.1574180285449; Tue, 19 Nov 2019 08:18:05 -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.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Nov 2019 08:18:04 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Tue, 19 Nov 2019 17:12:29 +0100 Message-Id: <20191119161234.3766-2-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 2/6] avcodec/cbs: Move allocation of unit data into write_unit 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" when writing a unit from content. Writing a unit (i.e. assembling it from its decomposed form) currently always uses an intermediate buffer; only after the unit has been completely assembled in this buffer (so that, in particular, the needed size is known), is the final buffer allocated and the data copied. This works well for most types of units except one: The slice/frame units that usually make up the bulk of the whole data. Only their headers are reassembled from content. Their actual data are mostly just copied into the write buffer. Given that the size of the actual data is known, one has a very good estimate on the needed size after having assembled the slice/frame header only. If one allocated the necessary buffer now and directly copied the frame header and frame data into it, one can avoid copying the data into the temporary buffer. This commit lays the groundwork for doing so by moving the data buffer's allocation into the (codec-dependent) write_unit function. It does not avoid copying yet. Signed-off-by: Andreas Rheinhardt --- libavcodec/cbs.c | 38 ++++++++++++++++++++++---------------- libavcodec/cbs_av1.c | 2 +- libavcodec/cbs_h2645.c | 4 ++-- libavcodec/cbs_internal.h | 12 +++++++++++- libavcodec/cbs_jpeg.c | 10 ++++++++-- libavcodec/cbs_mpeg2.c | 10 ++++++++-- libavcodec/cbs_vp9.c | 2 +- 7 files changed, 53 insertions(+), 25 deletions(-) diff --git a/libavcodec/cbs.c b/libavcodec/cbs.c index 0badb192d9..aa2e4904d0 100644 --- a/libavcodec/cbs.c +++ b/libavcodec/cbs.c @@ -283,6 +283,28 @@ int ff_cbs_read(CodedBitstreamContext *ctx, return cbs_read_fragment_content(ctx, frag); } +int ff_cbs_default_write_unit_data(CodedBitstreamContext *ctx, + CodedBitstreamUnit *unit, + PutBitContext *pbc) +{ + int err; + + if (put_bits_count(pbc) % 8) + unit->data_bit_padding = 8 - put_bits_count(pbc) % 8; + else + unit->data_bit_padding = 0; + + flush_put_bits(pbc); + + err = ff_cbs_alloc_unit_data(ctx, unit, put_bits_count(pbc) / 8); + if (err < 0) + return err; + + memcpy(unit->data, pbc->buf, unit->data_size); + + return 0; +} + static int cbs_write_unit_data(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit) { @@ -318,22 +340,6 @@ static int cbs_write_unit_data(CodedBitstreamContext *ctx, return ret; } - // Overflow but we didn't notice. - av_assert0(put_bits_count(&pbc) <= 8 * ctx->write_buffer_size); - - if (put_bits_count(&pbc) % 8) - unit->data_bit_padding = 8 - put_bits_count(&pbc) % 8; - else - unit->data_bit_padding = 0; - - flush_put_bits(&pbc); - - ret = ff_cbs_alloc_unit_data(ctx, unit, put_bits_count(&pbc) / 8); - if (ret < 0) - return ret; - - memcpy(unit->data, ctx->write_buffer, unit->data_size); - return 0; } diff --git a/libavcodec/cbs_av1.c b/libavcodec/cbs_av1.c index bbe4461130..7ff5539fb8 100644 --- a/libavcodec/cbs_av1.c +++ b/libavcodec/cbs_av1.c @@ -1217,7 +1217,7 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx, // OBU data must be byte-aligned. av_assert0(put_bits_count(pbc) % 8 == 0); - return 0; + return ff_cbs_default_write_unit_data(ctx, unit, pbc); } static int cbs_av1_assemble_fragment(CodedBitstreamContext *ctx, diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index 88fa0029cd..d3d5342bad 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -1265,7 +1265,7 @@ static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx, return AVERROR_PATCHWELCOME; } - return 0; + return ff_cbs_default_write_unit_data(ctx, unit, pbc); } static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx, @@ -1377,7 +1377,7 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx, return AVERROR_PATCHWELCOME; } - return 0; + return ff_cbs_default_write_unit_data(ctx, unit, pbc); } static int cbs_h2645_assemble_fragment(CodedBitstreamContext *ctx, diff --git a/libavcodec/cbs_internal.h b/libavcodec/cbs_internal.h index 4c5a535ca6..96c2a1ac80 100644 --- a/libavcodec/cbs_internal.h +++ b/libavcodec/cbs_internal.h @@ -44,7 +44,9 @@ typedef struct CodedBitstreamType { int (*read_unit)(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit); - // Write the data bitstream from unit->content into pbc. + // Write the data bitstream from unit->content. This includes + // allocating the buffer as well as setting all of unit's data-fields. + // The supplied PutBitContext may be used as temporary buffer. // Return value AVERROR(ENOSPC) indicates that pbc was too small. int (*write_unit)(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, @@ -60,6 +62,14 @@ typedef struct CodedBitstreamType { } CodedBitstreamType; +// Helper function to convert pbc's content into a unit's data. +// Allocates and copies data and sets all of unit's data-fields. + +int ff_cbs_default_write_unit_data(CodedBitstreamContext *ctx, + CodedBitstreamUnit *unit, + PutBitContext *pbc); + + // Helper functions for trace output. void ff_cbs_trace_header(CodedBitstreamContext *ctx, diff --git a/libavcodec/cbs_jpeg.c b/libavcodec/cbs_jpeg.c index 64fe70beab..da22bdf720 100644 --- a/libavcodec/cbs_jpeg.c +++ b/libavcodec/cbs_jpeg.c @@ -384,10 +384,16 @@ static int cbs_jpeg_write_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, PutBitContext *pbc) { + int err; + if (unit->type == JPEG_MARKER_SOS) - return cbs_jpeg_write_scan (ctx, unit, pbc); + err = cbs_jpeg_write_scan (ctx, unit, pbc); else - return cbs_jpeg_write_segment(ctx, unit, pbc); + err = cbs_jpeg_write_segment(ctx, unit, pbc); + if (err < 0) + return err; + + return ff_cbs_default_write_unit_data(ctx, unit, pbc); } static int cbs_jpeg_assemble_fragment(CodedBitstreamContext *ctx, diff --git a/libavcodec/cbs_mpeg2.c b/libavcodec/cbs_mpeg2.c index 13d871cc89..ba5e2417c2 100644 --- a/libavcodec/cbs_mpeg2.c +++ b/libavcodec/cbs_mpeg2.c @@ -374,10 +374,16 @@ static int cbs_mpeg2_write_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, PutBitContext *pbc) { + int err; + if (MPEG2_START_IS_SLICE(unit->type)) - return cbs_mpeg2_write_slice (ctx, unit, pbc); + err = cbs_mpeg2_write_slice (ctx, unit, pbc); else - return cbs_mpeg2_write_header(ctx, unit, pbc); + err = cbs_mpeg2_write_header(ctx, unit, pbc); + if (err < 0) + return err; + + return ff_cbs_default_write_unit_data(ctx, unit, pbc); } static int cbs_mpeg2_assemble_fragment(CodedBitstreamContext *ctx, diff --git a/libavcodec/cbs_vp9.c b/libavcodec/cbs_vp9.c index 42e4dcf5ac..a74c4f4cec 100644 --- a/libavcodec/cbs_vp9.c +++ b/libavcodec/cbs_vp9.c @@ -544,7 +544,7 @@ static int cbs_vp9_write_unit(CodedBitstreamContext *ctx, skip_put_bytes(pbc, frame->data_size); } - return 0; + return ff_cbs_default_write_unit_data(ctx, unit, pbc); } static int cbs_vp9_assemble_fragment(CodedBitstreamContext *ctx,