From patchwork Thu Jan 23 16:08:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 17495 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 3F89744BAAD for ; Thu, 23 Jan 2020 18:08:59 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2310268B49E; Thu, 23 Jan 2020 18:08:59 +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 F1F2968AFD0 for ; Thu, 23 Jan 2020 18:08:50 +0200 (EET) Received: by mail-wr1-f67.google.com with SMTP id z3so3722222wru.3 for ; Thu, 23 Jan 2020 08:08:50 -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=NNOMAO2j92evoDimxXraroux7FNEw8Ryp4mz+eHXCLE=; b=RIur4a08ZctaJK6YbzQF+SzVkULKm0rJ1Yf9gtHN59jeTAl7S881SEw8RPXvCzNlxV 1Mk1411Cmi9syvWO4dPjtYd8VkkBGC69c8sVOle+3dgx5STHKKh80Yx627poEM+t6p9Z HwIrkkC+lyk6Tay9QjJgRJGHwiEKq7urAX99UV2KX3qMKCpBhcUQ/pUfBrEnKnivRATf DPnQHCV7eIvz3z5vUk0zoxBkVsbWlKAdHLX/Jrs7Bbz03JqizcQIy1LDJjzQ3VJRNVcv 4QSAnN/TVRa9tOP+P9HzLiPHD41f/7tTv6cDP21us6FgCb1/Fo7YLRrZkzRmLsMgcETc gnKg== 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=NNOMAO2j92evoDimxXraroux7FNEw8Ryp4mz+eHXCLE=; b=LNDw/oySNNmB65OvNfPhFDJq02NPp4ABVxo7voVvED59cxmh4CIMH/vTND2tr25igb KBcs3Hr+82Kbf0zsEFWM9qpIjCeMIdc5/5kW9MIgvarCJvnEtR/yMi0AsHsWe7M6p2uR s4BljUa02cwTPOEY1qM5hQyc4t1dbDGZ/O3y7AkBpenKolDkBF3cB36frRBwHEBouWbu P6FeAChX7YGmBmQ83L0/0lDDJb6IVIOczYqlMxalta8xvmzXmN9ATfskdHBsNsHdtisY Q9DyVayqgyBjZHcrPMJmEdQVeOSV5cVa9tIf1pauDtTmIJIP592KGElnTUuhLLYIkMZc D8dg== X-Gm-Message-State: APjAAAVHIFkbo59RHT3hFeRU7VFd2kUTSvNmNHxv4MWkNSdAonxZMkfA ciYYXRBVU6AWBN8ODHTeqySPjn7Z X-Google-Smtp-Source: APXvYqzQ7tLyWeg4jr+q1YLbQ+poTHdRLHztyoiS2+u0QCOn71KoAD4nkZKk9UqwQtpUIkqH8LvWUA== X-Received: by 2002:a5d:50cf:: with SMTP id f15mr17437452wrt.381.1579795730225; Thu, 23 Jan 2020 08:08:50 -0800 (PST) Received: from sblaptop.fritz.box (ipbcc08bbf.dynamic.kabel-deutschland.de. [188.192.139.191]) by smtp.gmail.com with ESMTPSA id o187sm3678419wme.36.2020.01.23.08.08.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Jan 2020 08:08:49 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Thu, 23 Jan 2020 17:08:32 +0100 Message-Id: <20200123160832.2020-6-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200123160832.2020-1-andreas.rheinhardt@gmail.com> References: <20200123160832.2020-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 6/6] avformat/av1: Improve filtering AV1 OBUs 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" Both ISOBMFF as well as Matroska require certain OBUs to be stripped before muxing them. There are two functions for this purpose; one writes directly into an AVIOContext, the other returns a freshly allocated buffer with the undesired units stripped away. The latter one actually relies on the former by means of a dynamic buffer. This has several drawbacks: The underlying buffer might have to be reallocated multiple times; the buffer will eventually be overallocated; the data will not be directly copied into the final buffer, but rather first in the write buffer (in chunks of 1024 byte) and then written in these chunks. Moreover, the API for dynamic buffers is defective wrt error checking and as a consequence, the earlier code would indicate a length of -AV_INPUT_BUFFER_PADDING_SIZE on allocation failure, but it would not return an error; there would also be no error in case the arbitrary limit of INT_MAX/2 that is currently imposed on dynamic buffers is hit. This commit changes this: The buffer is now parsed twice, once to get the precise length which will then be allocated; and once to actually write the data. For a 22.7mb/s file with average framesize 113 kB this improved the time for the calls to ff_av1_filter_obus_buf() when writing Matroska from 753662 decicycles to 313319 decicycles (based upon 50 runs a 2048 frames each); for another 1.5mb/s file (with average framesize of 7.3 kB) it improved from 79270 decicycles to 34539 decicycles (based upon 50 runs a 4096 frames). Signed-off-by: Andreas Rheinhardt --- libavformat/av1.c | 32 +++++++++++++++++++++----------- libavformat/av1.h | 4 ++-- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/libavformat/av1.c b/libavformat/av1.c index 4ff4bffddf..80c049f62f 100644 --- a/libavformat/av1.c +++ b/libavformat/av1.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/avassert.h" #include "libavutil/mem.h" #include "libavcodec/av1.h" #include "libavcodec/av1_parse.h" @@ -48,7 +49,8 @@ int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size) case AV1_OBU_PADDING: break; default: - avio_write(pb, buf, len); + if (pb) + avio_write(pb, buf, len); size += len; break; } @@ -58,23 +60,31 @@ int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size) return size; } -int ff_av1_filter_obus_buf(const uint8_t *buf, uint8_t **out, int *size) +int ff_av1_filter_obus_buf(const uint8_t *in, uint8_t **out, int *size) { - AVIOContext *pb; - int ret; + AVIOContext pb; + uint8_t *buf; + int len, ret; - ret = avio_open_dyn_buf(&pb); - if (ret < 0) - return ret; - - ret = ff_av1_filter_obus(pb, buf, *size); + len = ret = ff_av1_filter_obus(NULL, in, *size); if (ret < 0) { - ffio_free_dyn_buf(&pb); return ret; } + buf = av_malloc((size_t)len + AV_INPUT_BUFFER_PADDING_SIZE); + if (!buf) + return AVERROR(ENOMEM); + + ffio_init_context(&pb, buf, len, 1, NULL, NULL, NULL, NULL); + + ret = ff_av1_filter_obus(&pb, in, *size); + av_assert1(ret == len); + + memset(buf + len, 0, AV_INPUT_BUFFER_PADDING_SIZE); + av_freep(out); - *size = avio_close_dyn_buf(pb, out); + *out = buf; + *size = len; return 0; } diff --git a/libavformat/av1.h b/libavformat/av1.h index 0578435376..acba12612c 100644 --- a/libavformat/av1.h +++ b/libavformat/av1.h @@ -61,7 +61,7 @@ int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size); * * @param pb pointer to the AVIOContext where the filtered bitstream shall be * written - * @param buf input data buffer + * @param in input data buffer * @param out pointer to pointer that will hold the allocated data buffer * @param size size of the input data buffer. The size of the resulting output data buffer will be written here @@ -69,7 +69,7 @@ int ff_av1_filter_obus(AVIOContext *pb, const uint8_t *buf, int size); * @return 0 in case of success, a negative AVERROR code in case of failure. * On failure, out and size are unchanged */ -int ff_av1_filter_obus_buf(const uint8_t *buf, uint8_t **out, int *size); +int ff_av1_filter_obus_buf(const uint8_t *in, uint8_t **out, int *size); /** * Parses a Sequence Header from the the provided buffer.