Skip to content

Commit 2a936e0

Browse files
committed
build-aux: Fix incorrect HEVC vertical resolution on AMD VCN
AMD VCN uses a different surface alignment compared to other GPUs for encoding, which required an upstream fix in Mesa, libva, FFmpeg, and the VCN firmware. This commit adds the FFmpeg patches to the flatpak build of OBS which is currently using FFmpeg version n7.1, however the patches were applied upstream after that release. libva API version 1.21 or higher is also required, which is satisfied by using KDE runtime 6.8. The incorrect 1920x1088 HEVC output resolution (instead of 1920x1080) resulted in streaming disconnects for Twitch Enhanced Broadcsating Linux users. Local file recording when using AMD VAAPI HEVC also outputs 1088 instead of 1080. This commit fixes both cases. Please refer to [1], [2], and [3] for context. The patches are taken from [2]. Note that the fix is applicable to flatpak builds only. Standalone and Debian package builds depend on the host library versions and will still have the problem until a version of FFmpeg with the fix is used. [1]: https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=11222 [2]: https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=13168 [3]: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10985
1 parent b966073 commit 2a936e0

File tree

3 files changed

+154
-0
lines changed

3 files changed

+154
-0
lines changed

build-aux/modules/30-ffmpeg.json

+7
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@
3636
"tag": "2024-09-05",
3737
"commit": "45b7d2cfac0e2ac256d458c7466a925b0a94de35"
3838
},
39+
{
40+
"type": "patch",
41+
"paths": [
42+
"../modules/patches/ffmpeg/0001-lavc-vaapi_encode-Query-surface-alignment.patch",
43+
"../modules/patches/ffmpeg/0002-lavc-vaapi_encode_h265-Use-surface-alignment.patch"
44+
]
45+
},
3946
{
4047
"type": "shell",
4148
"commands": [
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
From bcfbf2bac8f9eeeedc407b40596f5c7aaa0d5b47 Mon Sep 17 00:00:00 2001
2+
From: David Rosca <[email protected]>
3+
Date: Tue, 22 Oct 2024 17:26:58 +0200
4+
Subject: [PATCH 1/2] lavc/vaapi_encode: Query surface alignment
5+
6+
It needs to create temporary config to query surface attribute.
7+
8+
Signed-off-by: Timo Rothenpieler <[email protected]>
9+
---
10+
libavcodec/vaapi_encode.c | 66 +++++++++++++++++++++++++++++++++++++++
11+
libavcodec/vaapi_encode.h | 4 +++
12+
2 files changed, 70 insertions(+)
13+
14+
diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
15+
index b593d976ef..8960e6b20a 100644
16+
--- a/libavcodec/vaapi_encode.c
17+
+++ b/libavcodec/vaapi_encode.c
18+
@@ -1133,6 +1133,68 @@ fail:
19+
return err;
20+
}
21+
22+
+static av_cold int vaapi_encode_surface_alignment(av_unused AVCodecContext *avctx)
23+
+{
24+
+#if VA_CHECK_VERSION(1, 21, 0)
25+
+ VAAPIEncodeContext *ctx = avctx->priv_data;
26+
+ VASurfaceAttrib *attr_list = NULL;
27+
+ unsigned int attr_count = 0;
28+
+ VAConfigID va_config;
29+
+ VAStatus vas;
30+
+ int err = 0;
31+
+
32+
+ vas = vaCreateConfig(ctx->hwctx->display,
33+
+ ctx->va_profile, ctx->va_entrypoint,
34+
+ NULL, 0, &va_config);
35+
+ if (vas != VA_STATUS_SUCCESS) {
36+
+ av_log(avctx, AV_LOG_ERROR, "Failed to create temp encode pipeline "
37+
+ "configuration: %d (%s).\n", vas, vaErrorStr(vas));
38+
+ return AVERROR(EIO);
39+
+ }
40+
+
41+
+ vas = vaQuerySurfaceAttributes(ctx->hwctx->display, va_config,
42+
+ 0, &attr_count);
43+
+ if (vas != VA_STATUS_SUCCESS) {
44+
+ av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
45+
+ "%d (%s).\n", vas, vaErrorStr(vas));
46+
+ err = AVERROR_EXTERNAL;
47+
+ goto fail;
48+
+ }
49+
+
50+
+ attr_list = av_malloc(attr_count * sizeof(*attr_list));
51+
+ if (!attr_list) {
52+
+ err = AVERROR(ENOMEM);
53+
+ goto fail;
54+
+ }
55+
+
56+
+ vas = vaQuerySurfaceAttributes(ctx->hwctx->display, va_config,
57+
+ attr_list, &attr_count);
58+
+ if (vas != VA_STATUS_SUCCESS) {
59+
+ av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
60+
+ "%d (%s).\n", vas, vaErrorStr(vas));
61+
+ err = AVERROR_EXTERNAL;
62+
+ goto fail;
63+
+ }
64+
+
65+
+ for (unsigned int i = 0; i < attr_count; i++) {
66+
+ if (attr_list[i].type == VASurfaceAttribAlignmentSize) {
67+
+ ctx->surface_alignment_width =
68+
+ 1 << (attr_list[i].value.value.i & 0xf);
69+
+ ctx->surface_alignment_height =
70+
+ 1 << ((attr_list[i].value.value.i & 0xf0) >> 4);
71+
+ break;
72+
+ }
73+
+ }
74+
+
75+
+fail:
76+
+ av_freep(&attr_list);
77+
+ vaDestroyConfig(ctx->hwctx->display, va_config);
78+
+ return err;
79+
+#else
80+
+ return 0;
81+
+#endif
82+
+}
83+
+
84+
static const VAAPIEncodeRCMode vaapi_encode_rc_modes[] = {
85+
// Bitrate Quality
86+
// | Maxrate | HRD/VBV
87+
@@ -2111,6 +2173,10 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
88+
if (err < 0)
89+
goto fail;
90+
91+
+ err = vaapi_encode_surface_alignment(avctx);
92+
+ if (err < 0)
93+
+ goto fail;
94+
+
95+
if (ctx->codec->get_encoder_caps) {
96+
err = ctx->codec->get_encoder_caps(avctx);
97+
if (err < 0)
98+
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
99+
index 40a3f4e064..8e3eab9f27 100644
100+
--- a/libavcodec/vaapi_encode.h
101+
+++ b/libavcodec/vaapi_encode.h
102+
@@ -260,6 +260,10 @@ typedef struct VAAPIEncodeContext {
103+
* This is a RefStruct reference.
104+
*/
105+
VABufferID *coded_buffer_ref;
106+
+
107+
+ // Surface alignment required by driver.
108+
+ int surface_alignment_width;
109+
+ int surface_alignment_height;
110+
} VAAPIEncodeContext;
111+
112+
typedef struct VAAPIEncodeType {
113+
--
114+
2.43.0
115+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
From d0facac679faf45d3356dff2e2cb382580d7a521 Mon Sep 17 00:00:00 2001
2+
From: David Rosca <[email protected]>
3+
Date: Tue, 22 Oct 2024 17:26:59 +0200
4+
Subject: [PATCH 2/2] lavc/vaapi_encode_h265: Use surface alignment
5+
6+
This is needed to correctly set conformance window crop with Mesa AMD.
7+
8+
Signed-off-by: Timo Rothenpieler <[email protected]>
9+
---
10+
libavcodec/vaapi_encode_h265.c | 6 ++++--
11+
1 file changed, 4 insertions(+), 2 deletions(-)
12+
13+
diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
14+
index 2283bcc0b4..44d9fdbbd5 100644
15+
--- a/libavcodec/vaapi_encode_h265.c
16+
+++ b/libavcodec/vaapi_encode_h265.c
17+
@@ -951,8 +951,10 @@ static av_cold int vaapi_encode_h265_get_encoder_caps(AVCodecContext *avctx)
18+
"min CB size %dx%d.\n", priv->ctu_size, priv->ctu_size,
19+
priv->min_cb_size, priv->min_cb_size);
20+
21+
- base_ctx->surface_width = FFALIGN(avctx->width, priv->min_cb_size);
22+
- base_ctx->surface_height = FFALIGN(avctx->height, priv->min_cb_size);
23+
+ base_ctx->surface_width = FFALIGN(avctx->width,
24+
+ FFMAX(priv->min_cb_size, priv->common.surface_alignment_width));
25+
+ base_ctx->surface_height = FFALIGN(avctx->height,
26+
+ FFMAX(priv->min_cb_size, priv->common.surface_alignment_height));
27+
28+
base_ctx->slice_block_width = base_ctx->slice_block_height = priv->ctu_size;
29+
30+
--
31+
2.43.0
32+

0 commit comments

Comments
 (0)