mirror of
https://github.com/obsproject/obs-studio
synced 2025-04-29 18:17:19 +08:00
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
This commit is contained in:
parent
d31271834f
commit
4efc6bf0d8
@ -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": [
|
||||
|
@ -0,0 +1,115 @@
|
||||
From bcfbf2bac8f9eeeedc407b40596f5c7aaa0d5b47 Mon Sep 17 00:00:00 2001
|
||||
From: David Rosca <nowrep@gmail.com>
|
||||
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 <timo@rothenpieler.org>
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,32 @@
|
||||
From d0facac679faf45d3356dff2e2cb382580d7a521 Mon Sep 17 00:00:00 2001
|
||||
From: David Rosca <nowrep@gmail.com>
|
||||
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 <timo@rothenpieler.org>
|
||||
---
|
||||
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…
x
Reference in New Issue
Block a user