From f5ef2019053cbc80ec9aec1ffa99152424c9c890 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 23 Nov 2025 13:21:10 -0600 Subject: [PATCH] Create a separate X11 Display object for libva Sharing these directly is fraught with concurrency issues that require extreme care on both sides to avoid spurious X11 errors, hangs, and other nasty stuff. We can't necessarily depend on SDL, libva, or the underlying VA drivers to do the right thing here. Using a new Display (as FFmpeg does for VAAPI and VDPAU) avoids all these problems. --- .../video/ffmpeg-renderers/vaapi.cpp | 25 ++++++++++++++++++- app/streaming/video/ffmpeg-renderers/vaapi.h | 1 + 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/streaming/video/ffmpeg-renderers/vaapi.cpp b/app/streaming/video/ffmpeg-renderers/vaapi.cpp index f722dec9..03f5a66a 100644 --- a/app/streaming/video/ffmpeg-renderers/vaapi.cpp +++ b/app/streaming/video/ffmpeg-renderers/vaapi.cpp @@ -34,6 +34,11 @@ VAAPIRenderer::VAAPIRenderer(int decoderSelectionPass) SDL_zero(m_PrimeDescriptor); #endif +#ifdef HAVE_LIBVA_X11 + m_XDisplay = nullptr; + m_XWindow = None; +#endif + #ifdef HAVE_LIBVA_DRM m_DrmFd = -1; #endif @@ -74,6 +79,12 @@ VAAPIRenderer::~VAAPIRenderer() } #endif +#ifdef HAVE_LIBVA_X11 + if (m_XDisplay != nullptr) { + XCloseDisplay(m_XDisplay); + } +#endif + if (m_OverlayMutex != nullptr) { SDL_DestroyMutex(m_OverlayMutex); } @@ -98,7 +109,19 @@ VAAPIRenderer::openDisplay(SDL_Window* window) if (info.subsystem == SDL_SYSWM_X11) { #ifdef HAVE_LIBVA_X11 m_XWindow = info.info.x11.window; - display = vaGetDisplay(info.info.x11.display); + + // It's possible to enter this function several times as we're probing VA drivers. + // Only open the new Display object the first time through. + if (m_XDisplay == nullptr) { + m_XDisplay = XOpenDisplay(XDisplayString(info.info.x11.display)); + if (m_XDisplay == nullptr) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Unable to clone SDL X11 display for VAAPI"); + return nullptr; + } + } + + display = vaGetDisplay(m_XDisplay); if (display == nullptr) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to open X11 display for VAAPI"); diff --git a/app/streaming/video/ffmpeg-renderers/vaapi.h b/app/streaming/video/ffmpeg-renderers/vaapi.h index f45a18c4..9b6287ff 100644 --- a/app/streaming/video/ffmpeg-renderers/vaapi.h +++ b/app/streaming/video/ffmpeg-renderers/vaapi.h @@ -106,6 +106,7 @@ private: SDL_Rect m_OverlayRect[Overlay::OverlayMax]; #ifdef HAVE_LIBVA_X11 + Display* m_XDisplay; Window m_XWindow; #endif