From: Fei Wang <fei.w.wang-at-intel.com@ffmpeg.org>
To: ffmpeg-devel@ffmpeg.org
Cc: Mark Thompson <sw@jkqxz.net>, Fei Wang <fei.w.wang@intel.com>
Subject: [FFmpeg-devel] [PATCH v1 2/4] vaapi_encode: Move block size calculation after entrypoint selection
Date: Fri, 18 Feb 2022 09:42:59 +0800
Message-ID: <20220218014301.1830754-2-fei.w.wang@intel.com> (raw)
In-Reply-To: <20220218014301.1830754-1-fei.w.wang@intel.com>
From: Mark Thompson <sw@jkqxz.net>
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.
Signed-off-by: Fei Wang <fei.w.wang@intel.com>
---
libavcodec/vaapi_encode.c | 14 ++++++++++++++
libavcodec/vaapi_encode.h | 7 +++++++
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, 70 insertions(+), 19 deletions(-)
diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 95eca7c288..763fe50009 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -2041,6 +2041,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) /
@@ -2430,6 +2432,18 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
if (err < 0)
goto fail;
+ if (ctx->codec->get_encoder_caps) {
+ ctx->codec->get_encoder_caps(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 61c5615eb8..2e5cfd7a72 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -376,6 +376,13 @@ typedef struct VAAPIEncodeType {
// factor depending on RC mode.
int default_quality;
+ // Determine encode parameters like 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 (*get_encoder_caps)(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 ea45893508..5b8dbe841d 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;
@@ -1091,6 +1095,27 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
return 0;
}
+static av_cold void vaapi_encode_h265_get_encoder_caps(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;
@@ -1160,6 +1185,7 @@ static const VAAPIEncodeType vaapi_encode_type_h265 = {
.default_quality = 25,
+ .get_encoder_caps = &vaapi_encode_h265_get_encoder_caps,
.configure = &vaapi_encode_h265_configure,
.picture_priv_data_size = sizeof(VAAPIEncodeH265Picture),
@@ -1205,12 +1231,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 6206b23e5f..c4fe879073 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_get_encoder_caps(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,
+ .get_encoder_caps = &vaapi_encode_mjpeg_get_encoder_caps,
.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 d084d8c4b9..f8809b08ab 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 7d4578f674..ab3c84a618 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 be706e3bd6..b7560c4b81 100644
--- a/libavcodec/vaapi_encode_vp9.c
+++ b/libavcodec/vaapi_encode_vp9.c
@@ -184,6 +184,15 @@ static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx,
return 0;
}
+static av_cold void vaapi_encode_vp9_get_encoder_caps(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;
@@ -231,6 +240,7 @@ static const VAAPIEncodeType vaapi_encode_type_vp9 = {
.picture_priv_data_size = sizeof(VAAPIEncodeVP9Picture),
+ .get_encoder_caps = &vaapi_encode_vp9_get_encoder_caps,
.configure = &vaapi_encode_vp9_configure,
.sequence_params_size = sizeof(VAEncSequenceParameterBufferVP9),
@@ -251,10 +261,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);
}
--
2.25.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2022-02-18 1:48 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-18 1:42 [FFmpeg-devel] [PATCH v1 1/4] lavc/vaapi_encode_h265: Add P frame to GPB frame support for hevc_vaapi Fei Wang
2022-02-18 1:42 ` Fei Wang [this message]
2022-02-18 1:43 ` [FFmpeg-devel] [PATCH v1 3/4] vaapi_encode_h265: Explicitly set and correct some flags Fei Wang
2022-02-18 1:43 ` [FFmpeg-devel] [PATCH v1 4/4] vaapi_encode_h265: Query encoding block sizes and features Fei Wang
2022-02-18 4:38 ` Xiang, Haihao
2022-02-21 2:21 ` Wang, Fei W
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220218014301.1830754-2-fei.w.wang@intel.com \
--to=fei.w.wang-at-intel.com@ffmpeg.org \
--cc=fei.w.wang@intel.com \
--cc=ffmpeg-devel@ffmpeg.org \
--cc=sw@jkqxz.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git