From patchwork Mon Mar 4 21:06:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 12191 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 2AC234485FE for ; Mon, 4 Mar 2019 23:08:29 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 051F3689A81; Mon, 4 Mar 2019 23:08:29 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qt1-f194.google.com (mail-qt1-f194.google.com [209.85.160.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B782568090B for ; Mon, 4 Mar 2019 23:08:20 +0200 (EET) Received: by mail-qt1-f194.google.com with SMTP id y4so6712750qtc.10 for ; Mon, 04 Mar 2019 13:08:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=T/0Sz93jxh0Fgq7XiPzCOweb20CkyL9BxAEroEq//YU=; b=HPWekC30pbq9r22ZrBhJK2SahFCYtsv+GIEKgaMyKtB30DGVmf7kCeJUB94AyCurGn rw+cv7E5Jr5F4DHbw72O4plyS35OBbxUb4Pa6L+1SfI/Z8A+Fl4YM0EUU9DsFk7EnT9u nNOrNUOI47HbQ1Lel3fG6hqWVGlVwa1I2H6VKSlkGdmutaO1APH3EYsCHiFFtlTKZ/JQ IlSds74d6mjHZoMVrqsyCNU1/+SXXUaVnGTNWmic6kNms+jV6wJ2SxQt/HtJuhInA0RT dt+8p9tiEBDWQ76jOnyPhXtKmI8mAQtbi3pBPN4I+VpcFiTPLWS0E9NhH5HibapRbGB8 VYFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=T/0Sz93jxh0Fgq7XiPzCOweb20CkyL9BxAEroEq//YU=; b=YmHIFrBavyAxpzhLhO2RgoEd9FhbZJBk3SIAYchA1HaIjgaPzqsQ7Hc7elg+SIHNeT /tl84YDCqcfniEp4dotTeCYNIsVz/qJVJt2iYsEJc28RmLSbwMtktvO1W+JaSh5d+mBC Yg/Gqrv18s6S3LEsiURxAiI5Zu7cwG5AUHT6iEp4C7f5mrSjL8bT0tv6Nyf7RM35brRD pyBf/3H+PDuBMYxsPXqQOp2QHDh3kmGH1TJ7WEN9R7b1jX8F/5iML8XHJgodWMSXBsGx nuHYIgAyIBbbRY53UkK3S0i6C+t5yAVve7dZPsoVGe2TN/CFvmDgJBSYe1OzSVgUZcfM xQuw== X-Gm-Message-State: APjAAAWG7PaVwWgUXjthvd2v1UrKH9HGnoA4Bu+cVgK1e6KEKJFd7yFy lnUecD8virRaDN/gR0XkBdToP/RtDnA= X-Google-Smtp-Source: APXvYqwE3M/B9Ik3YOxWuhTq+JXt8QdIz69CAaH4idmkNnGVaYg2Z7SGP748nZPIlKKlNNE6ml1sRQ== X-Received: by 2002:a0c:963d:: with SMTP id 58mr15912668qvx.25.1551733699209; Mon, 04 Mar 2019 13:08:19 -0800 (PST) Received: from localhost.localdomain ([181.23.86.217]) by smtp.gmail.com with ESMTPSA id g53sm4642810qte.21.2019.03.04.13.08.18 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 04 Mar 2019 13:08:18 -0800 (PST) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Mon, 4 Mar 2019 18:06:56 -0300 Message-Id: <20190304210656.2412-2-jamrial@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190304210656.2412-1-jamrial@gmail.com> References: <20190304210656.2412-1-jamrial@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/2] avcodec/libdav1d: use a custom picture allocator 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Replaces the libdav1d internal allocator. It uses an AVBufferPool to reduce the amount of allocated buffers. About 5% speed up when decoding 720p or higher streams. Signed-off-by: James Almer --- get_buffer2() can't be used for this decoder, as there's no guarantee the buffers it returns will respect the constrains specified by libdav1d. libavcodec/libdav1d.c | 72 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 7 deletions(-) diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c index 459bbae687..855c27db7f 100644 --- a/libavcodec/libdav1d.c +++ b/libavcodec/libdav1d.c @@ -22,6 +22,7 @@ #include #include "libavutil/avassert.h" +#include "libavutil/imgutils.h" #include "libavutil/opt.h" #include "avcodec.h" @@ -31,12 +32,21 @@ typedef struct Libdav1dContext { AVClass *class; Dav1dContext *c; + AVBufferPool *pool; + int pool_size; Dav1dData data; int tile_threads; int apply_grain; } Libdav1dContext; +static const enum AVPixelFormat pix_fmt[][3] = { + [DAV1D_PIXEL_LAYOUT_I400] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12 }, + [DAV1D_PIXEL_LAYOUT_I420] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV420P12 }, + [DAV1D_PIXEL_LAYOUT_I422] = { AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV422P12 }, + [DAV1D_PIXEL_LAYOUT_I444] = { AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV444P12 }, +}; + static void libdav1d_log_callback(void *opaque, const char *fmt, va_list vl) { AVCodecContext *c = opaque; @@ -44,6 +54,57 @@ static void libdav1d_log_callback(void *opaque, const char *fmt, va_list vl) av_vlog(c, AV_LOG_ERROR, fmt, vl); } +static int libdav1d_picture_allocator(Dav1dPicture *p, void *cookie) { + Libdav1dContext *dav1d = cookie; + enum AVPixelFormat format = pix_fmt[p->p.layout][p->seq_hdr->hbd]; + int ret, linesize[4], h = FFALIGN(p->p.h, 128); + uint8_t *aligned_ptr, *data[4]; + AVBufferRef *buf; + + ret = av_image_fill_arrays(data, linesize, NULL, format, FFALIGN(p->p.w, 128), + h, DAV1D_PICTURE_ALIGNMENT); + if (ret < 0) + return ret; + + if (ret != dav1d->pool_size) { + av_buffer_pool_uninit(&dav1d->pool); + // Use twice the amount of required padding bytes for aligned_ptr below. + dav1d->pool = av_buffer_pool_init(ret + DAV1D_PICTURE_ALIGNMENT * 2, NULL); + if (!dav1d->pool) + return -ENOMEM; + dav1d->pool_size = ret; + } + buf = av_buffer_pool_get(dav1d->pool); + if (!buf) + return -ENOMEM; + + // libdav1d requires DAV1D_PICTURE_ALIGNMENT aligned buffers, which av_malloc() + // doesn't guarantee for example when AVX is disabled at configure time. + // Use the extra DAV1D_PICTURE_ALIGNMENT padding bytes in the buffer to align it + // if required. + aligned_ptr = (uint8_t *)FFALIGN((uintptr_t)buf->data, DAV1D_PICTURE_ALIGNMENT); + ret = av_image_fill_pointers(data, format, h, aligned_ptr, linesize); + if (ret < 0) { + av_buffer_unref(&buf); + return ret; + } + + p->data[0] = data[0]; + p->data[1] = data[1]; + p->data[2] = data[2]; + p->stride[0] = linesize[0]; + p->stride[1] = linesize[1]; + p->allocator_data = buf; + + return 0; +} + +static void libdav1d_picture_release(Dav1dPicture *p, void *cookie) { + AVBufferRef *buf = p->allocator_data; + + av_buffer_unref(&buf); +} + static av_cold int libdav1d_init(AVCodecContext *c) { Libdav1dContext *dav1d = c->priv_data; @@ -55,6 +116,9 @@ static av_cold int libdav1d_init(AVCodecContext *c) dav1d_default_settings(&s); s.logger.cookie = c; s.logger.callback = libdav1d_log_callback; + s.allocator.cookie = dav1d; + s.allocator.alloc_picture_callback = libdav1d_picture_allocator; + s.allocator.release_picture_callback = libdav1d_picture_release; s.n_tile_threads = dav1d->tile_threads; s.apply_grain = dav1d->apply_grain; s.n_frame_threads = FFMIN(c->thread_count ? c->thread_count : av_cpu_count(), DAV1D_MAX_FRAME_THREADS); @@ -87,13 +151,6 @@ static void libdav1d_frame_free(void *opaque, uint8_t *data) { av_free(p); } -static const enum AVPixelFormat pix_fmt[][3] = { - [DAV1D_PIXEL_LAYOUT_I400] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12 }, - [DAV1D_PIXEL_LAYOUT_I420] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV420P12 }, - [DAV1D_PIXEL_LAYOUT_I422] = { AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV422P12 }, - [DAV1D_PIXEL_LAYOUT_I444] = { AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV444P12 }, -}; - static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame) { Libdav1dContext *dav1d = c->priv_data; @@ -222,6 +279,7 @@ static av_cold int libdav1d_close(AVCodecContext *c) { Libdav1dContext *dav1d = c->priv_data; + av_buffer_pool_uninit(&dav1d->pool); dav1d_data_unref(&dav1d->data); dav1d_close(&dav1d->c);