From 7cf8b46c7952da70bb82af89ef8a2c1408d5b087 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 6 Aug 2026 00:29:53 -0500 Subject: [PATCH] Pass the correct renderer to EGLImageFactory We should be using the EGL renderer's colorspace and color range rather than the backend renderer's for fallbacks. The former is what actually gets passed to the host PC during stream init. --- app/streaming/video/ffmpeg-renderers/drm.cpp | 8 +++----- app/streaming/video/ffmpeg-renderers/drm.h | 2 +- .../video/ffmpeg-renderers/eglimagefactory.cpp | 17 ++++++++++++++--- .../video/ffmpeg-renderers/eglimagefactory.h | 4 ++-- app/streaming/video/ffmpeg-renderers/eglvid.cpp | 2 +- app/streaming/video/ffmpeg-renderers/renderer.h | 3 ++- app/streaming/video/ffmpeg-renderers/vaapi.cpp | 8 ++++---- app/streaming/video/ffmpeg-renderers/vaapi.h | 2 +- 8 files changed, 28 insertions(+), 18 deletions(-) diff --git a/app/streaming/video/ffmpeg-renderers/drm.cpp b/app/streaming/video/ffmpeg-renderers/drm.cpp index 788fb30a..50d7a395 100644 --- a/app/streaming/video/ffmpeg-renderers/drm.cpp +++ b/app/streaming/video/ffmpeg-renderers/drm.cpp @@ -163,9 +163,6 @@ DrmRenderer::DrmRenderer(AVHWDeviceType hwDeviceType, IFFmpegRenderer *backendRe m_OutputRect{}, m_SwFrameMapper(this), m_CurrentSwFrameIdx(0) -#ifdef HAVE_EGL - , m_EglImageFactory(this) -#endif { SDL_zero(m_SwFrame); } @@ -2100,9 +2097,10 @@ AVPixelFormat DrmRenderer::getEGLImagePixelFormat() { return AV_PIX_FMT_DRM_PRIME; } -bool DrmRenderer::initializeEGL(EGLDisplay display, +bool DrmRenderer::initializeEGL(IFFmpegRenderer* eglRenderer, + EGLDisplay display, const EGLExtensions &ext) { - return m_EglImageFactory.initializeEGL(display, ext); + return m_EglImageFactory.initializeEGL(eglRenderer, display, ext); } ssize_t DrmRenderer::exportEGLImages(AVFrame *frame, EGLDisplay dpy, diff --git a/app/streaming/video/ffmpeg-renderers/drm.h b/app/streaming/video/ffmpeg-renderers/drm.h index 0c82ccdc..3060bef1 100644 --- a/app/streaming/video/ffmpeg-renderers/drm.h +++ b/app/streaming/video/ffmpeg-renderers/drm.h @@ -776,7 +776,7 @@ public: #ifdef HAVE_EGL virtual bool canExportEGL() override; virtual AVPixelFormat getEGLImagePixelFormat() override; - virtual bool initializeEGL(EGLDisplay dpy, const EGLExtensions &ext) override; + virtual bool initializeEGL(IFFmpegRenderer* eglRenderer, EGLDisplay dpy, const EGLExtensions &ext) override; virtual ssize_t exportEGLImages(AVFrame *frame, EGLDisplay dpy, EGLImage images[EGL_MAX_PLANES]) override; #endif diff --git a/app/streaming/video/ffmpeg-renderers/eglimagefactory.cpp b/app/streaming/video/ffmpeg-renderers/eglimagefactory.cpp index b0dd1413..2faf4b0a 100644 --- a/app/streaming/video/ffmpeg-renderers/eglimagefactory.cpp +++ b/app/streaming/video/ffmpeg-renderers/eglimagefactory.cpp @@ -24,8 +24,8 @@ #define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8') #endif -EglImageFactory::EglImageFactory(IFFmpegRenderer* renderer) : - m_Renderer(renderer), +EglImageFactory::EglImageFactory() : + m_Renderer(nullptr), m_EGLExtDmaBuf(false), m_eglCreateImage(nullptr), m_eglDestroyImage(nullptr), @@ -36,9 +36,16 @@ EglImageFactory::EglImageFactory(IFFmpegRenderer* renderer) : { } -bool EglImageFactory::initializeEGL(EGLDisplay, +bool EglImageFactory::initializeEGL(IFFmpegRenderer* eglRenderer, + EGLDisplay, const EGLExtensions &ext) { + // The EGL renderer is guaranteed to be alive for any calls to this factory, + // since it's the one that calls exportEGLImages() on the backend renderer. + SDL_assert(eglRenderer->getRendererType() == IFFmpegRenderer::RendererType::EGL); + SDL_assert(!m_Renderer); + m_Renderer = eglRenderer; + if (!ext.isSupported("EGL_EXT_image_dma_buf_import")) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "DRM-EGL: DMABUF unsupported"); @@ -75,6 +82,8 @@ void EglImageFactory::resetCache() ssize_t EglImageFactory::exportDRMImages(AVFrame* frame, EGLDisplay dpy, EGLImage images[EGL_MAX_PLANES]) { + SDL_assert(m_Renderer); + SDL_assert(frame->format == AV_PIX_FMT_DRM_PRIME); AVDRMFrameDescriptor* drmFrame = (AVDRMFrameDescriptor*)frame->data[0]; @@ -264,6 +273,8 @@ ssize_t EglImageFactory::exportDRMImages(AVFrame* frame, EGLDisplay dpy, EGLImag ssize_t EglImageFactory::exportVAImages(AVFrame *frame, uint32_t exportFlags, EGLDisplay dpy, EGLImage images[EGL_MAX_PLANES]) { + SDL_assert(m_Renderer); + SDL_assert(frame->format == AV_PIX_FMT_VAAPI); auto hwFrameCtx = (AVHWFramesContext*)frame->hw_frames_ctx->data; AVVAAPIDeviceContext* vaDeviceContext = (AVVAAPIDeviceContext*)hwFrameCtx->device_ctx->hwctx; diff --git a/app/streaming/video/ffmpeg-renderers/eglimagefactory.h b/app/streaming/video/ffmpeg-renderers/eglimagefactory.h index 7828c2bd..6a5c0474 100644 --- a/app/streaming/video/ffmpeg-renderers/eglimagefactory.h +++ b/app/streaming/video/ffmpeg-renderers/eglimagefactory.h @@ -41,8 +41,8 @@ class EglImageFactory }; public: - EglImageFactory(IFFmpegRenderer* renderer); - bool initializeEGL(EGLDisplay, const EGLExtensions &ext); + EglImageFactory(); + bool initializeEGL(IFFmpegRenderer* eglRenderer, EGLDisplay, const EGLExtensions &ext); void resetCache(); #ifdef HAVE_DRM diff --git a/app/streaming/video/ffmpeg-renderers/eglvid.cpp b/app/streaming/video/ffmpeg-renderers/eglvid.cpp index d137dbf8..e5090b6e 100644 --- a/app/streaming/video/ffmpeg-renderers/eglvid.cpp +++ b/app/streaming/video/ffmpeg-renderers/eglvid.cpp @@ -523,7 +523,7 @@ bool EGLRenderer::initialize(PDECODER_PARAMETERS params) return false; } - if (!m_Backend->initializeEGL(m_EGLDisplay, eglExtensions)) + if (!m_Backend->initializeEGL(this, m_EGLDisplay, eglExtensions)) return false; if (!(m_glEGLImageTargetTexture2DOES = (typeof(m_glEGLImageTargetTexture2DOES))eglGetProcAddress("glEGLImageTargetTexture2DOES"))) { diff --git a/app/streaming/video/ffmpeg-renderers/renderer.h b/app/streaming/video/ffmpeg-renderers/renderer.h index 96aba8e5..ba125842 100644 --- a/app/streaming/video/ffmpeg-renderers/renderer.h +++ b/app/streaming/video/ffmpeg-renderers/renderer.h @@ -508,7 +508,8 @@ public: return AV_PIX_FMT_NONE; } - virtual bool initializeEGL(EGLDisplay, + virtual bool initializeEGL(IFFmpegRenderer*, + EGLDisplay, const EGLExtensions &) { return false; } diff --git a/app/streaming/video/ffmpeg-renderers/vaapi.cpp b/app/streaming/video/ffmpeg-renderers/vaapi.cpp index 5531d6c4..6142e79e 100644 --- a/app/streaming/video/ffmpeg-renderers/vaapi.cpp +++ b/app/streaming/video/ffmpeg-renderers/vaapi.cpp @@ -26,8 +26,7 @@ VAAPIRenderer::VAAPIRenderer(int decoderSelectionPass) m_RequiresExplicitPixelFormat(false), m_OverlayMutex(nullptr) #ifdef HAVE_EGL - , m_EglExportType(EglExportType::Unknown), - m_EglImageFactory(this) + , m_EglExportType(EglExportType::Unknown) #endif { #ifdef HAVE_LIBVA_X11 @@ -1082,11 +1081,12 @@ AVPixelFormat VAAPIRenderer::getEGLImagePixelFormat() { } bool -VAAPIRenderer::initializeEGL(EGLDisplay dpy, +VAAPIRenderer::initializeEGL(IFFmpegRenderer* eglRenderer, + EGLDisplay dpy, const EGLExtensions &ext) { VADRMPRIMESurfaceDescriptor descriptor; - if (!m_EglImageFactory.initializeEGL(dpy, ext)) { + if (!m_EglImageFactory.initializeEGL(eglRenderer, dpy, ext)) { return false; } diff --git a/app/streaming/video/ffmpeg-renderers/vaapi.h b/app/streaming/video/ffmpeg-renderers/vaapi.h index 61643083..95c1c9b0 100644 --- a/app/streaming/video/ffmpeg-renderers/vaapi.h +++ b/app/streaming/video/ffmpeg-renderers/vaapi.h @@ -72,7 +72,7 @@ public: #ifdef HAVE_EGL virtual bool canExportEGL() override; virtual AVPixelFormat getEGLImagePixelFormat() override; - virtual bool initializeEGL(EGLDisplay dpy, const EGLExtensions &ext) override; + virtual bool initializeEGL(IFFmpegRenderer* eglRenderer, EGLDisplay dpy, const EGLExtensions &ext) override; virtual ssize_t exportEGLImages(AVFrame *frame, EGLDisplay dpy, EGLImage images[EGL_MAX_PLANES]) override; #endif