From a903c5cef2c54f10974943254357f641f09ea3ef Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 5 Aug 2026 23:25:30 -0500 Subject: [PATCH] Explicitly request limited range for renderers that require it --- app/streaming/video/ffmpeg-renderers/dxva2.cpp | 8 ++++++++ app/streaming/video/ffmpeg-renderers/dxva2.h | 1 + app/streaming/video/ffmpeg-renderers/mmal.cpp | 6 ++++++ app/streaming/video/ffmpeg-renderers/mmal.h | 1 + app/streaming/video/ffmpeg-renderers/vaapi.cpp | 6 ++++++ app/streaming/video/ffmpeg-renderers/vaapi.h | 1 + app/streaming/video/ffmpeg-renderers/vdpau.cpp | 6 ++++++ app/streaming/video/ffmpeg-renderers/vdpau.h | 1 + app/streaming/video/ffmpeg-renderers/vt_avsamplelayer.mm | 5 +++++ 9 files changed, 35 insertions(+) diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.cpp b/app/streaming/video/ffmpeg-renderers/dxva2.cpp index 1eaf520c..e4386157 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.cpp +++ b/app/streaming/video/ffmpeg-renderers/dxva2.cpp @@ -784,6 +784,14 @@ int DXVA2Renderer::getDecoderColorspace() } } +int DXVA2Renderer::getDecoderColorRange() +{ + // StretchRect() assumes limited range on Intel and Qualcomm GPUs. + // VideoProcessBlt() should handle either fine, but let's not take + // chances on potentially broken DXVA2 GPU drivers for little gain. + return COLOR_RANGE_LIMITED; +} + int DXVA2Renderer::getDecoderCapabilities() { return CAPABILITY_REFERENCE_FRAME_INVALIDATION_HEVC | diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.h b/app/streaming/video/ffmpeg-renderers/dxva2.h index 23ef3d8f..14ffc0e0 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.h +++ b/app/streaming/video/ffmpeg-renderers/dxva2.h @@ -18,6 +18,7 @@ public: virtual void renderFrame(AVFrame* frame) override; virtual void notifyOverlayUpdated(Overlay::OverlayType type) override; virtual int getDecoderColorspace() override; + virtual int getDecoderColorRange() override; virtual int getDecoderCapabilities() override; private: diff --git a/app/streaming/video/ffmpeg-renderers/mmal.cpp b/app/streaming/video/ffmpeg-renderers/mmal.cpp index ea649661..bf8e2123 100644 --- a/app/streaming/video/ffmpeg-renderers/mmal.cpp +++ b/app/streaming/video/ffmpeg-renderers/mmal.cpp @@ -242,6 +242,12 @@ int MmalRenderer::getDecoderColorspace() return COLORSPACE_REC_709; } +int MmalRenderer::getDecoderColorRange() +{ + // MMAL_COLOR_SPACE_ITUR_BT709 assumes limited range content + return COLOR_RANGE_LIMITED; +} + void MmalRenderer::InputPortCallback(MMAL_PORT_T*, MMAL_BUFFER_HEADER_T* buffer) { mmal_buffer_header_release(buffer); diff --git a/app/streaming/video/ffmpeg-renderers/mmal.h b/app/streaming/video/ffmpeg-renderers/mmal.h index 4297a441..3eb2d566 100644 --- a/app/streaming/video/ffmpeg-renderers/mmal.h +++ b/app/streaming/video/ffmpeg-renderers/mmal.h @@ -18,6 +18,7 @@ public: virtual enum AVPixelFormat getPreferredPixelFormat(int videoFormat) override; virtual int getRendererAttributes() override; virtual int getDecoderColorspace() override; + virtual int getDecoderColorRange() override; private: static void InputPortCallback(MMAL_PORT_T* port, MMAL_BUFFER_HEADER_T* buffer); diff --git a/app/streaming/video/ffmpeg-renderers/vaapi.cpp b/app/streaming/video/ffmpeg-renderers/vaapi.cpp index aa2aa5b5..5531d6c4 100644 --- a/app/streaming/video/ffmpeg-renderers/vaapi.cpp +++ b/app/streaming/video/ffmpeg-renderers/vaapi.cpp @@ -648,6 +648,12 @@ int VAAPIRenderer::getDecoderColorspace() return COLORSPACE_REC_601; } +int VAAPIRenderer::getDecoderColorRange() +{ + // vaPutSurface() assumes limited range + return COLOR_RANGE_LIMITED; +} + int VAAPIRenderer::getDecoderCapabilities() { int caps = 0; diff --git a/app/streaming/video/ffmpeg-renderers/vaapi.h b/app/streaming/video/ffmpeg-renderers/vaapi.h index f391fdaf..61643083 100644 --- a/app/streaming/video/ffmpeg-renderers/vaapi.h +++ b/app/streaming/video/ffmpeg-renderers/vaapi.h @@ -64,6 +64,7 @@ public: virtual void renderFrame(AVFrame* frame) override; virtual bool isDirectRenderingSupported() override; virtual int getDecoderColorspace() override; + virtual int getDecoderColorRange() override; virtual int getDecoderCapabilities() override; virtual void notifyOverlayUpdated(Overlay::OverlayType) override; virtual bool notifyWindowChanged(PWINDOW_STATE_CHANGE_INFO) override; diff --git a/app/streaming/video/ffmpeg-renderers/vdpau.cpp b/app/streaming/video/ffmpeg-renderers/vdpau.cpp index dfb7e1ee..dc0522e8 100644 --- a/app/streaming/video/ffmpeg-renderers/vdpau.cpp +++ b/app/streaming/video/ffmpeg-renderers/vdpau.cpp @@ -470,6 +470,12 @@ int VDPAURenderer::getDecoderColorspace() return COLORSPACE_REC_601; } +int VDPAURenderer::getDecoderColorRange() +{ + // The default VdpVideoMixer CSC matrix assumes limited range + return COLOR_RANGE_LIMITED; +} + int VDPAURenderer::getDecoderCapabilities() { return CAPABILITY_REFERENCE_FRAME_INVALIDATION_HEVC | diff --git a/app/streaming/video/ffmpeg-renderers/vdpau.h b/app/streaming/video/ffmpeg-renderers/vdpau.h index 5b2a6aed..183b35ce 100644 --- a/app/streaming/video/ffmpeg-renderers/vdpau.h +++ b/app/streaming/video/ffmpeg-renderers/vdpau.h @@ -19,6 +19,7 @@ public: virtual void waitToRender() override; virtual void renderFrame(AVFrame* frame) override; virtual int getDecoderColorspace() override; + virtual int getDecoderColorRange() override; virtual int getDecoderCapabilities() override; private: diff --git a/app/streaming/video/ffmpeg-renderers/vt_avsamplelayer.mm b/app/streaming/video/ffmpeg-renderers/vt_avsamplelayer.mm index 17522a31..c7d03ed1 100644 --- a/app/streaming/video/ffmpeg-renderers/vt_avsamplelayer.mm +++ b/app/streaming/video/ffmpeg-renderers/vt_avsamplelayer.mm @@ -457,6 +457,11 @@ public: return COLORSPACE_REC_601; } + int getDecoderColorRange() override + { + return COLOR_RANGE_LIMITED; + } + int getDecoderCapabilities() override { return CAPABILITY_REFERENCE_FRAME_INVALIDATION_HEVC |