From patchwork Thu Mar 5 00:25:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 18031 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 DD23444AFCE for ; Thu, 5 Mar 2020 02:34:09 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B760668B1D0; Thu, 5 Mar 2020 02:34:09 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f68.google.com (mail-wr1-f68.google.com [209.85.221.68]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 755F36880FD for ; Thu, 5 Mar 2020 02:34:03 +0200 (EET) Received: by mail-wr1-f68.google.com with SMTP id n7so4854973wrt.11 for ; Wed, 04 Mar 2020 16:34:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=T3tctoHOju/XLxNIxES+rIzkByNqA46ZR0YDm4AyChg=; b=QpkfZm1hXbuKBXBwSwR5mLvI4u78Dhvl3wKXBzQQaf5qQPDJeEAdyNfOHiSrXKFllL yh2FuZeAqZnYErDpUWv0jisJjeX9GMsEFxajbL291X3RcMARrAxltqraxLckSEdm3cS4 8ThuLfw/wD8mwWDQlsbfRULLSahnP4Iz7Fzr5EouFHVmxTMJnATcU/N0eskYGBhHLohs QQAgszucx7BXdmUVBjDf+n1wA10Ca8aHtDukJUlkOnLBkq1Tub2kF0in6Ok17bMq2uoV YhN560xevgnxuWN9AIoUlrxJJdDWj4tOOVRmn4dRIxsLaGEUHPT2cAPRrShNmeW5Faxq bZww== 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:mime-version :content-transfer-encoding; bh=T3tctoHOju/XLxNIxES+rIzkByNqA46ZR0YDm4AyChg=; b=PUXVLEDpWPrYDcHbADWzTi4aa0j/h5FKudylA1YzInav7BvKRTbXag9ywBQGWTpgww 2vrqp4Qso//bBSZY5YRfbvY+c1j+z7Lk6mim5jH2Rrr53ROq8rHTl+zK0ymN/+nd5wUH BvpDGUlBfDvopp/p+cAP44/1ZM3gXweN0fy/JeI9GQOruwChlX3s5Jq5SZWvfdH6/AbL BRk6vi15j74AMKFpy0m14wRS5P8yiLtXCs/waLgOrQLbq1kKUlQ/NgMdsAOrO1XVGvA8 XlcVcS+zhFYA9jjRfv2+aS4kbOTxcz4422GYiefPQKTwuYnCKP8J468YGhWonCGTAG6/ WArw== X-Gm-Message-State: ANhLgQ0TqTnV52ARJfOtwPfPqpOIPJ0Hyrt7q0upXpydUui5v8J89MHy 5IDNO6hTzgfFa+ZU1Urhwl/cooaxZZk= X-Google-Smtp-Source: ADFU+vsaEDPf385LQNGrkW9CaODPNOmvIK4gI9Ar7h5s7DVcasEg0+XXVa6ly2RjctkiQjP3/1rQgA== X-Received: by 2002:a5d:4389:: with SMTP id i9mr5847650wrq.90.1583367935856; Wed, 04 Mar 2020 16:25:35 -0800 (PST) Received: from rywe.jkqxz.net (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id k65sm7106943wmf.1.2020.03.04.16.25.34 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Mar 2020 16:25:35 -0800 (PST) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Thu, 5 Mar 2020 00:25:25 +0000 Message-Id: <20200305002528.11418-1-sw@jkqxz.net> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/4] vaapi_encode: Move block size calculation after entrypoint selection 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" The block size can be dependent on the profile and entrypoint selected. It defaults to 16x16, with codecs able to override this choice with their own function. --- libavcodec/vaapi_encode.c | 14 ++++++++++++++ libavcodec/vaapi_encode.h | 6 ++++++ libavcodec/vaapi_encode_h265.c | 32 ++++++++++++++++++++++++++------ libavcodec/vaapi_encode_mjpeg.c | 16 +++++++++++++--- libavcodec/vaapi_encode_mpeg2.c | 3 --- libavcodec/vaapi_encode_vp8.c | 3 --- libavcodec/vaapi_encode_vp9.c | 14 ++++++++++---- 7 files changed, 69 insertions(+), 19 deletions(-) diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index 8ff720e395..93bbed4539 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -1840,6 +1840,8 @@ static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx) return 0; } + av_assert0(ctx->slice_block_height > 0 && ctx->slice_block_width > 0); + ctx->slice_block_rows = (avctx->height + ctx->slice_block_height - 1) / ctx->slice_block_height; ctx->slice_block_cols = (avctx->width + ctx->slice_block_width - 1) / @@ -2237,6 +2239,18 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) if (err < 0) goto fail; + if (ctx->codec->block_size) { + ctx->codec->block_size(avctx); + } else { + // Assume 16x16 blocks. + ctx->surface_width = FFALIGN(avctx->width, 16); + ctx->surface_height = FFALIGN(avctx->height, 16); + if (ctx->codec->flags & FLAG_SLICE_CONTROL) { + ctx->slice_block_width = 16; + ctx->slice_block_height = 16; + } + } + err = vaapi_encode_init_rate_control(avctx); if (err < 0) goto fail; diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index b9a3defd72..583be9c845 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -355,6 +355,12 @@ typedef struct VAAPIEncodeType { // factor depending on RC mode. int default_quality; + // Determine block sizes for surface alignment and slices. This may + // need to query the profile and entrypoint, which will be available + // when this function is called. If not set, assume that all blocks + // are 16x16 and that surfaces should be aligned to match this. + void (*block_size)(AVCodecContext *avctx); + // Perform any extra codec-specific configuration after the // codec context is initialised (set up the private data and // add any necessary global parameters). diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index 538862a9d5..9a78dfb4f7 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -55,6 +55,10 @@ typedef struct VAAPIEncodeH265Picture { typedef struct VAAPIEncodeH265Context { VAAPIEncodeContext common; + // Encoder features. + uint32_t ctu_size; + uint32_t min_cb_size; + // User options. int qp; int aud; @@ -1062,6 +1066,27 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, return 0; } +static av_cold void vaapi_encode_h265_block_size(AVCodecContext *avctx) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAAPIEncodeH265Context *priv = avctx->priv_data; + + if (!priv->ctu_size) { + priv->ctu_size = 32; + priv->min_cb_size = 16; + } + av_log(avctx, AV_LOG_VERBOSE, "Using CTU size %dx%d, " + "min CB size %dx%d.\n", priv->ctu_size, priv->ctu_size, + priv->min_cb_size, priv->min_cb_size); + + ctx->surface_width = FFALIGN(avctx->width, priv->min_cb_size); + ctx->surface_height = FFALIGN(avctx->height, priv->min_cb_size); + + ctx->slice_block_width = ctx->slice_block_height = priv->ctu_size; + + return; +} + static av_cold int vaapi_encode_h265_configure(AVCodecContext *avctx) { VAAPIEncodeContext *ctx = avctx->priv_data; @@ -1127,6 +1152,7 @@ static const VAAPIEncodeType vaapi_encode_type_h265 = { .default_quality = 25, + .block_size = &vaapi_encode_h265_block_size, .configure = &vaapi_encode_h265_configure, .picture_priv_data_size = sizeof(VAAPIEncodeH265Picture), @@ -1172,12 +1198,6 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx) VA_ENC_PACKED_HEADER_SLICE | // Slice headers. VA_ENC_PACKED_HEADER_MISC; // SEI - ctx->surface_width = FFALIGN(avctx->width, 16); - ctx->surface_height = FFALIGN(avctx->height, 16); - - // CTU size is currently hard-coded to 32. - ctx->slice_block_width = ctx->slice_block_height = 32; - if (priv->qp > 0) ctx->explicit_qp = priv->qp; diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c index bd029cc903..0d992d6f44 100644 --- a/libavcodec/vaapi_encode_mjpeg.c +++ b/libavcodec/vaapi_encode_mjpeg.c @@ -434,6 +434,18 @@ static int vaapi_encode_mjpeg_init_slice_params(AVCodecContext *avctx, return 0; } +static av_cold void vaapi_encode_mjpeg_block_size(AVCodecContext *avctx) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + const AVPixFmtDescriptor *desc; + + desc = av_pix_fmt_desc_get(ctx->input_frames->sw_format); + av_assert0(desc); + + ctx->surface_width = FFALIGN(avctx->width, 8 << desc->log2_chroma_w); + ctx->surface_height = FFALIGN(avctx->height, 8 << desc->log2_chroma_h); +} + static av_cold int vaapi_encode_mjpeg_configure(AVCodecContext *avctx) { VAAPIEncodeContext *ctx = avctx->priv_data; @@ -483,6 +495,7 @@ static const VAAPIEncodeType vaapi_encode_type_mjpeg = { .flags = FLAG_CONSTANT_QUALITY_ONLY | FLAG_INTRA_ONLY, + .block_size = &vaapi_encode_mjpeg_block_size, .configure = &vaapi_encode_mjpeg_configure, .default_quality = 80, @@ -509,9 +522,6 @@ static av_cold int vaapi_encode_mjpeg_init(AVCodecContext *avctx) ctx->desired_packed_headers = VA_ENC_PACKED_HEADER_RAW_DATA; - ctx->surface_width = FFALIGN(avctx->width, 8); - ctx->surface_height = FFALIGN(avctx->height, 8); - return ff_vaapi_encode_init(avctx); } diff --git a/libavcodec/vaapi_encode_mpeg2.c b/libavcodec/vaapi_encode_mpeg2.c index bac9ea1fa6..442321b55c 100644 --- a/libavcodec/vaapi_encode_mpeg2.c +++ b/libavcodec/vaapi_encode_mpeg2.c @@ -623,9 +623,6 @@ static av_cold int vaapi_encode_mpeg2_init(AVCodecContext *avctx) ctx->desired_packed_headers = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE; - ctx->surface_width = FFALIGN(avctx->width, 16); - ctx->surface_height = FFALIGN(avctx->height, 16); - return ff_vaapi_encode_init(avctx); } diff --git a/libavcodec/vaapi_encode_vp8.c b/libavcodec/vaapi_encode_vp8.c index 6e7bf9d106..93d8b57316 100644 --- a/libavcodec/vaapi_encode_vp8.c +++ b/libavcodec/vaapi_encode_vp8.c @@ -210,9 +210,6 @@ static av_cold int vaapi_encode_vp8_init(AVCodecContext *avctx) // adding them anyway. ctx->desired_packed_headers = 0; - ctx->surface_width = FFALIGN(avctx->width, 16); - ctx->surface_height = FFALIGN(avctx->height, 16); - return ff_vaapi_encode_init(avctx); } diff --git a/libavcodec/vaapi_encode_vp9.c b/libavcodec/vaapi_encode_vp9.c index d7f415d704..19093bfa71 100644 --- a/libavcodec/vaapi_encode_vp9.c +++ b/libavcodec/vaapi_encode_vp9.c @@ -176,6 +176,15 @@ static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx, return 0; } +static av_cold void vaapi_encode_vp9_block_size(AVCodecContext *avctx) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + + // Surfaces must be aligned to 64x64 superblock boundaries. + ctx->surface_width = FFALIGN(avctx->width, 64); + ctx->surface_height = FFALIGN(avctx->height, 64); +} + static av_cold int vaapi_encode_vp9_configure(AVCodecContext *avctx) { VAAPIEncodeContext *ctx = avctx->priv_data; @@ -223,6 +232,7 @@ static const VAAPIEncodeType vaapi_encode_type_vp9 = { .picture_priv_data_size = sizeof(VAAPIEncodeVP9Picture), + .block_size = &vaapi_encode_vp9_block_size, .configure = &vaapi_encode_vp9_configure, .sequence_params_size = sizeof(VAEncSequenceParameterBufferVP9), @@ -243,10 +253,6 @@ static av_cold int vaapi_encode_vp9_init(AVCodecContext *avctx) // can write its own headers and there is no metadata to include. ctx->desired_packed_headers = 0; - // Surfaces must be aligned to superblock boundaries. - ctx->surface_width = FFALIGN(avctx->width, 64); - ctx->surface_height = FFALIGN(avctx->height, 64); - return ff_vaapi_encode_init(avctx); }