Skip to content

build-aux: Fix incorrect HEVC vertical resolution on AMD VCN #11998

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions build-aux/modules/30-ffmpeg.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@
"tag": "2024-09-05",
"commit": "45b7d2cfac0e2ac256d458c7466a925b0a94de35"
},
{
"type": "patch",
"paths": [
"patches/ffmpeg/0001-lavc-vaapi_encode-Query-surface-alignment.patch",
"patches/ffmpeg/0002-lavc-vaapi_encode_h265-Use-surface-alignment.patch"
]
},
{
"type": "shell",
"commands": [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
From bcfbf2bac8f9eeeedc407b40596f5c7aaa0d5b47 Mon Sep 17 00:00:00 2001
From: David Rosca <[email protected]>
Date: Tue, 22 Oct 2024 17:26:58 +0200
Subject: [PATCH 1/2] lavc/vaapi_encode: Query surface alignment

It needs to create temporary config to query surface attribute.

Signed-off-by: Timo Rothenpieler <[email protected]>
---
libavcodec/vaapi_encode.c | 66 +++++++++++++++++++++++++++++++++++++++
libavcodec/vaapi_encode.h | 4 +++
2 files changed, 70 insertions(+)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index b593d976ef..8960e6b20a 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -1133,6 +1133,68 @@ fail:
return err;
}

+static av_cold int vaapi_encode_surface_alignment(av_unused AVCodecContext *avctx)
+{
+#if VA_CHECK_VERSION(1, 21, 0)
+ VAAPIEncodeContext *ctx = avctx->priv_data;
+ VASurfaceAttrib *attr_list = NULL;
+ unsigned int attr_count = 0;
+ VAConfigID va_config;
+ VAStatus vas;
+ int err = 0;
+
+ vas = vaCreateConfig(ctx->hwctx->display,
+ ctx->va_profile, ctx->va_entrypoint,
+ NULL, 0, &va_config);
+ if (vas != VA_STATUS_SUCCESS) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to create temp encode pipeline "
+ "configuration: %d (%s).\n", vas, vaErrorStr(vas));
+ return AVERROR(EIO);
+ }
+
+ vas = vaQuerySurfaceAttributes(ctx->hwctx->display, va_config,
+ 0, &attr_count);
+ if (vas != VA_STATUS_SUCCESS) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
+ "%d (%s).\n", vas, vaErrorStr(vas));
+ err = AVERROR_EXTERNAL;
+ goto fail;
+ }
+
+ attr_list = av_malloc(attr_count * sizeof(*attr_list));
+ if (!attr_list) {
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ vas = vaQuerySurfaceAttributes(ctx->hwctx->display, va_config,
+ attr_list, &attr_count);
+ if (vas != VA_STATUS_SUCCESS) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
+ "%d (%s).\n", vas, vaErrorStr(vas));
+ err = AVERROR_EXTERNAL;
+ goto fail;
+ }
+
+ for (unsigned int i = 0; i < attr_count; i++) {
+ if (attr_list[i].type == VASurfaceAttribAlignmentSize) {
+ ctx->surface_alignment_width =
+ 1 << (attr_list[i].value.value.i & 0xf);
+ ctx->surface_alignment_height =
+ 1 << ((attr_list[i].value.value.i & 0xf0) >> 4);
+ break;
+ }
+ }
+
+fail:
+ av_freep(&attr_list);
+ vaDestroyConfig(ctx->hwctx->display, va_config);
+ return err;
+#else
+ return 0;
+#endif
+}
+
static const VAAPIEncodeRCMode vaapi_encode_rc_modes[] = {
// Bitrate Quality
// | Maxrate | HRD/VBV
@@ -2111,6 +2173,10 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
if (err < 0)
goto fail;

+ err = vaapi_encode_surface_alignment(avctx);
+ if (err < 0)
+ goto fail;
+
if (ctx->codec->get_encoder_caps) {
err = ctx->codec->get_encoder_caps(avctx);
if (err < 0)
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index 40a3f4e064..8e3eab9f27 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -260,6 +260,10 @@ typedef struct VAAPIEncodeContext {
* This is a RefStruct reference.
*/
VABufferID *coded_buffer_ref;
+
+ // Surface alignment required by driver.
+ int surface_alignment_width;
+ int surface_alignment_height;
} VAAPIEncodeContext;

typedef struct VAAPIEncodeType {
--
2.43.0

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
From d0facac679faf45d3356dff2e2cb382580d7a521 Mon Sep 17 00:00:00 2001
From: David Rosca <[email protected]>
Date: Tue, 22 Oct 2024 17:26:59 +0200
Subject: [PATCH 2/2] lavc/vaapi_encode_h265: Use surface alignment

This is needed to correctly set conformance window crop with Mesa AMD.

Signed-off-by: Timo Rothenpieler <[email protected]>
---
libavcodec/vaapi_encode_h265.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
index 2283bcc0b4..44d9fdbbd5 100644
--- a/libavcodec/vaapi_encode_h265.c
+++ b/libavcodec/vaapi_encode_h265.c
@@ -951,8 +951,10 @@ static av_cold int vaapi_encode_h265_get_encoder_caps(AVCodecContext *avctx)
"min CB size %dx%d.\n", priv->ctu_size, priv->ctu_size,
priv->min_cb_size, priv->min_cb_size);

- base_ctx->surface_width = FFALIGN(avctx->width, priv->min_cb_size);
- base_ctx->surface_height = FFALIGN(avctx->height, priv->min_cb_size);
+ base_ctx->surface_width = FFALIGN(avctx->width,
+ FFMAX(priv->min_cb_size, priv->common.surface_alignment_width));
+ base_ctx->surface_height = FFALIGN(avctx->height,
+ FFMAX(priv->min_cb_size, priv->common.surface_alignment_height));

base_ctx->slice_block_width = base_ctx->slice_block_height = priv->ctu_size;

--
2.43.0

Loading