diff options
23 files changed, 102 insertions, 7 deletions
diff --git a/system/settings/settings.xml b/system/settings/settings.xml index 9e09dc3578..ef5abcde4e 100755 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -2998,7 +2998,12 @@ <control type="toggle" /> </setting> <setting id="videoscreen.guipeakluminance" type="integer" label="36097" help="36547"> - <requirement>HAS_DX</requirement> + <requirement> + <or> + <condition>HAS_DX</condition> + <condition>HAS_MEDIACODEC</condition> + </or> + </requirement> <dependencies> <dependency type="visible" on="property" name="ishdrdisplay"/> <dependency type="enable"> diff --git a/system/shaders/GLES/2.0/gles_shader_default.frag b/system/shaders/GLES/2.0/gles_shader_default.frag index f213360454..5f0bcd28c4 100644 --- a/system/shaders/GLES/2.0/gles_shader_default.frag +++ b/system/shaders/GLES/2.0/gles_shader_default.frag @@ -22,6 +22,7 @@ precision mediump float; uniform lowp vec4 m_unicol; +uniform float m_sdrPeak; void main () { @@ -34,5 +35,9 @@ void main () rgb.rgb += 16.0 / 255.0; #endif +#if defined(KODI_TRANSFER_PQ) + rgb.rgb *= m_sdrPeak; +#endif + gl_FragColor = rgb; } diff --git a/system/shaders/GLES/2.0/gles_shader_fonts.frag b/system/shaders/GLES/2.0/gles_shader_fonts.frag index 075d26f67a..a26d28b593 100644 --- a/system/shaders/GLES/2.0/gles_shader_fonts.frag +++ b/system/shaders/GLES/2.0/gles_shader_fonts.frag @@ -24,6 +24,7 @@ precision mediump float; uniform sampler2D m_samp0; varying vec4 m_cord0; varying lowp vec4 m_colour; +uniform float m_sdrPeak; void main () { @@ -37,5 +38,9 @@ void main () rgb.rgb += 16.0 / 255.0; #endif +#if defined(KODI_TRANSFER_PQ) + rgb.rgb *= m_sdrPeak; +#endif + gl_FragColor = rgb; } diff --git a/system/shaders/GLES/2.0/gles_shader_multi.frag b/system/shaders/GLES/2.0/gles_shader_multi.frag index 9f288982ec..f4c608d150 100644 --- a/system/shaders/GLES/2.0/gles_shader_multi.frag +++ b/system/shaders/GLES/2.0/gles_shader_multi.frag @@ -25,6 +25,7 @@ uniform sampler2D m_samp0; uniform sampler2D m_samp1; varying vec4 m_cord0; varying vec4 m_cord1; +uniform float m_sdrPeak; void main () { @@ -37,5 +38,9 @@ void main () rgb.rgb += 16.0 / 255.0; #endif +#if defined(KODI_TRANSFER_PQ) + rgb.rgb *= m_sdrPeak; +#endif + gl_FragColor = rgb; } diff --git a/system/shaders/GLES/2.0/gles_shader_multi_blendcolor.frag b/system/shaders/GLES/2.0/gles_shader_multi_blendcolor.frag index 35153da34c..98e5f7e7df 100644 --- a/system/shaders/GLES/2.0/gles_shader_multi_blendcolor.frag +++ b/system/shaders/GLES/2.0/gles_shader_multi_blendcolor.frag @@ -26,6 +26,7 @@ uniform sampler2D m_samp1; varying vec4 m_cord0; varying vec4 m_cord1; uniform lowp vec4 m_unicol; +uniform float m_sdrPeak; void main () { @@ -38,5 +39,9 @@ void main () rgb.rgb += 16.0 / 255.0; #endif +#if defined(KODI_TRANSFER_PQ) + rgb.rgb *= m_sdrPeak; +#endif + gl_FragColor = rgb; } diff --git a/system/shaders/GLES/2.0/gles_shader_texture.frag b/system/shaders/GLES/2.0/gles_shader_texture.frag index a2ac2de79b..ef1609c7f1 100644 --- a/system/shaders/GLES/2.0/gles_shader_texture.frag +++ b/system/shaders/GLES/2.0/gles_shader_texture.frag @@ -24,6 +24,7 @@ precision mediump float; uniform sampler2D m_samp0; uniform lowp vec4 m_unicol; varying vec4 m_cord0; +uniform float m_sdrPeak; void main () { @@ -36,5 +37,9 @@ void main () rgb.rgb += 16.0 / 255.0; #endif +#if defined(KODI_TRANSFER_PQ) + rgb.rgb *= m_sdrPeak; +#endif + gl_FragColor = rgb; } diff --git a/system/shaders/GLES/2.0/gles_shader_texture_noalpha.frag b/system/shaders/GLES/2.0/gles_shader_texture_noalpha.frag index 9f478ed3da..7db591c84e 100644 --- a/system/shaders/GLES/2.0/gles_shader_texture_noalpha.frag +++ b/system/shaders/GLES/2.0/gles_shader_texture_noalpha.frag @@ -11,6 +11,7 @@ precision mediump float; uniform sampler2D m_samp0; varying vec4 m_cord0; +uniform float m_sdrPeak; void main () { @@ -21,5 +22,9 @@ void main () rgb += 16.0 / 255.0; #endif +#if defined(KODI_TRANSFER_PQ) + rgb.rgb *= m_sdrPeak; +#endif + gl_FragColor = vec4(rgb, 1.0); } diff --git a/system/shaders/GLES/2.0/gles_shader_texture_noblend.frag b/system/shaders/GLES/2.0/gles_shader_texture_noblend.frag index 8cc66c94c9..44d797b539 100644 --- a/system/shaders/GLES/2.0/gles_shader_texture_noblend.frag +++ b/system/shaders/GLES/2.0/gles_shader_texture_noblend.frag @@ -23,6 +23,7 @@ precision mediump float; uniform sampler2D m_samp0; varying vec4 m_cord0; +uniform float m_sdrPeak; void main () { @@ -35,5 +36,9 @@ void main () rgb.rgb += 16.0 / 255.0; #endif +#if defined(KODI_TRANSFER_PQ) + rgb.rgb *= m_sdrPeak; +#endif + gl_FragColor = rgb; } diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.cpp index 0d986e9154..495d6a25f5 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.cpp @@ -51,6 +51,8 @@ void VideoPicture::Reset() qscale_type = 0; pict_type = 0; + hdrType = StreamHdrType::HDR_TYPE_NONE; + hasDisplayMetadata = false; hasLightMetadata = false; diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h index 3c55a7b06c..ca83b1a04f 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h @@ -64,6 +64,8 @@ public: int qscale_type; int pict_type; + StreamHdrType hdrType; + bool hasDisplayMetadata = false; AVMasteringDisplayMetadata displayMetadata; bool hasLightMetadata = false; diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp index 0bc6305eaf..6a542a558b 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.cpp @@ -1802,6 +1802,11 @@ void CDVDVideoCodecAndroidMediaCodec::ConfigureOutputFormat(CJNIMediaFormat& med m_videobuffer.iDisplayHeight = ((int)lrint(m_videobuffer.iWidth / m_hints.aspect)) & ~3; } } + + m_videobuffer.hdrType = m_hints.hdrType; + m_videobuffer.color_space = m_hints.colorSpace; + m_videobuffer.color_primaries = m_hints.colorPrimaries; + m_videobuffer.color_transfer = m_hints.colorTransferCharacteristic; } void CDVDVideoCodecAndroidMediaCodec::CallbackInitSurfaceTexture(void *userdata) diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp index d974171346..d66378fa07 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp @@ -1063,6 +1063,8 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(VideoPicture* pVideoPicture) pVideoPicture->qstride = 0; pVideoPicture->qscale_type = 0; + pVideoPicture->hdrType = m_hints.hdrType; + AVFrameSideData* sd; // https://github.com/FFmpeg/FFmpeg/blob/991d417692/doc/APIchanges#L18-L20 diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererMediaCodecSurface.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererMediaCodecSurface.cpp index 7e6e4e1a70..b65a669774 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererMediaCodecSurface.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererMediaCodecSurface.cpp @@ -63,6 +63,18 @@ bool CRendererMediaCodecSurface::Configure(const VideoPicture &picture, float fp CalculateFrameAspectRatio(picture.iDisplayWidth, picture.iDisplayHeight); SetViewMode(m_videoSettings.m_ViewMode); + // Configure GUI/OSD for HDR PQ when display is in HDR PQ mode + if (picture.color_transfer == AVCOL_TRC_SMPTE2084) + { + if (CServiceBroker::GetWinSystem()->IsHDRDisplay()) + CServiceBroker::GetWinSystem()->GetGfxContext().SetTransferPQ(true); + } + else if (picture.hdrType == StreamHdrType::HDR_TYPE_DOLBYVISION) + { + if (CServiceBroker::GetWinSystem()->GetDisplayHDRCapabilities().SupportsDolbyVision()) + CServiceBroker::GetWinSystem()->GetGfxContext().SetTransferPQ(true); + } + return true; } @@ -130,6 +142,8 @@ void CRendererMediaCodecSurface::Reset() for (int i = 0 ; i < 4 ; ++i) ReleaseVideoBuffer(i, false); m_lastIndex = -1; + + CServiceBroker::GetWinSystem()->GetGfxContext().SetTransferPQ(false); } void CRendererMediaCodecSurface::RenderUpdate(int index, int index2, bool clear, unsigned int flags, unsigned int alpha) diff --git a/xbmc/rendering/RenderSystem.h b/xbmc/rendering/RenderSystem.h index 0c3d6e099f..334b74b4f8 100644 --- a/xbmc/rendering/RenderSystem.h +++ b/xbmc/rendering/RenderSystem.h @@ -91,6 +91,7 @@ protected: RENDER_STEREO_VIEW m_stereoView = RENDER_STEREO_VIEW_OFF; RENDER_STEREO_MODE m_stereoMode = RENDER_STEREO_MODE_OFF; bool m_limitedColorRange = false; + bool m_transferPQ{false}; std::unique_ptr<CGUIImage> m_splashImage; std::unique_ptr<CGUITextLayout> m_splashMessageLayout; diff --git a/xbmc/rendering/gles/GLESShader.cpp b/xbmc/rendering/gles/GLESShader.cpp index 3964f4ba47..961c3f7961 100644 --- a/xbmc/rendering/gles/GLESShader.cpp +++ b/xbmc/rendering/gles/GLESShader.cpp @@ -48,6 +48,7 @@ void CGLESShader::OnCompiledAndLinked() m_hStep = glGetUniformLocation(ProgramHandle(), "m_step"); m_hContrast = glGetUniformLocation(ProgramHandle(), "m_contrast"); m_hBrightness = glGetUniformLocation(ProgramHandle(), "m_brightness"); + m_sdrPeak = glGetUniformLocation(ProgramHandle(), "m_sdrPeak"); // Variables passed directly to the Vertex shader m_hProj = glGetUniformLocation(ProgramHandle(), "m_proj"); @@ -167,6 +168,9 @@ bool CGLESShader::OnEnabled() glUniform1f(m_hBrightness, 0.0f); glUniform1f(m_hContrast, 1.0f); + const float sdrPeak = CServiceBroker::GetWinSystem()->GetGuiSdrPeakLuminance(); + glUniform1f(m_sdrPeak, sdrPeak); + return true; } diff --git a/xbmc/rendering/gles/GLESShader.h b/xbmc/rendering/gles/GLESShader.h index 8ce31e5570..1f59895740 100644 --- a/xbmc/rendering/gles/GLESShader.h +++ b/xbmc/rendering/gles/GLESShader.h @@ -62,4 +62,6 @@ protected: GLfloat m_clipXOffset; GLfloat m_clipYFactor; GLfloat m_clipYOffset; + + GLfloat m_sdrPeak; }; diff --git a/xbmc/rendering/gles/RenderSystemGLES.cpp b/xbmc/rendering/gles/RenderSystemGLES.cpp index d8557ff8a0..f25f783960 100644 --- a/xbmc/rendering/gles/RenderSystemGLES.cpp +++ b/xbmc/rendering/gles/RenderSystemGLES.cpp @@ -163,16 +163,19 @@ bool CRenderSystemGLES::BeginRender() if (!m_bRenderCreated) return false; - bool useLimited = CServiceBroker::GetWinSystem()->UseLimitedColor(); + const bool useLimited = CServiceBroker::GetWinSystem()->UseLimitedColor(); + const bool usePQ = CServiceBroker::GetWinSystem()->GetGfxContext().IsTransferPQ(); - if (m_limitedColorRange != useLimited) + if (m_limitedColorRange != useLimited || m_transferPQ != usePQ) { ReleaseShaders(); + + m_limitedColorRange = useLimited; + m_transferPQ = usePQ; + InitialiseShaders(); } - m_limitedColorRange = useLimited; - return true; } @@ -389,6 +392,11 @@ void CRenderSystemGLES::InitialiseShaders() defines += "#define KODI_LIMITED_RANGE 1\n"; } + if (m_transferPQ) + { + defines += "#define KODI_TRANSFER_PQ 1\n"; + } + m_pShader[ShaderMethodGLES::SM_DEFAULT] = std::make_unique<CGLESShader>("gles_shader.vert", "gles_shader_default.frag", defines); if (!m_pShader[ShaderMethodGLES::SM_DEFAULT]->CompileAndLink()) diff --git a/xbmc/windowing/GraphicContext.h b/xbmc/windowing/GraphicContext.h index 9cd4f32718..0c5201f1e7 100644 --- a/xbmc/windowing/GraphicContext.h +++ b/xbmc/windowing/GraphicContext.h @@ -179,6 +179,9 @@ public: const std::string& GetMediaDir() const; void SetMediaDir(const std::string& strMediaDir); + void SetTransferPQ(bool PQ) { m_isTransferPQ = PQ; } + bool IsTransferPQ() const { return m_isTransferPQ; } + protected: void UpdateCameraPosition(const CPoint &camera, const float &factor); @@ -229,4 +232,6 @@ protected: RENDER_STEREO_VIEW m_stereoView = RENDER_STEREO_VIEW_OFF; RENDER_STEREO_MODE m_stereoMode = RENDER_STEREO_MODE_OFF; RENDER_STEREO_MODE m_nextStereoMode = RENDER_STEREO_MODE_OFF; + + bool m_isTransferPQ{false}; }; diff --git a/xbmc/windowing/WinSystem.h b/xbmc/windowing/WinSystem.h index 4b6cf0d177..88218db9e0 100644 --- a/xbmc/windowing/WinSystem.h +++ b/xbmc/windowing/WinSystem.h @@ -217,6 +217,7 @@ public: virtual HDR_STATUS GetOSHDRStatus() { return HDR_STATUS::HDR_UNSUPPORTED; } virtual CHDRCapabilities GetDisplayHDRCapabilities() const { return {}; } static const char* SETTING_WINSYSTEM_IS_HDR_DISPLAY; + virtual float GetGuiSdrPeakLuminance() const { return .0f; } virtual bool HasSystemSdrPeakLuminance() { return false; } /*! diff --git a/xbmc/windowing/android/WinSystemAndroid.cpp b/xbmc/windowing/android/WinSystemAndroid.cpp index c5e895b2e6..f5b92b136b 100644 --- a/xbmc/windowing/android/WinSystemAndroid.cpp +++ b/xbmc/windowing/android/WinSystemAndroid.cpp @@ -320,3 +320,11 @@ CHDRCapabilities CWinSystemAndroid::GetDisplayHDRCapabilities() const { return CAndroidUtils::GetDisplayHDRCapabilities(); } + +float CWinSystemAndroid::GetGuiSdrPeakLuminance() const +{ + const auto settings = CServiceBroker::GetSettingsComponent()->GetSettings(); + const int guiSdrPeak = settings->GetInt(CSettings::SETTING_VIDEOSCREEN_GUISDRPEAKLUMINANCE); + + return ((0.7f * guiSdrPeak + 30.0f) / 100.0f); +} diff --git a/xbmc/windowing/android/WinSystemAndroid.h b/xbmc/windowing/android/WinSystemAndroid.h index 0ed6e9b4f0..e4d9b9b064 100644 --- a/xbmc/windowing/android/WinSystemAndroid.h +++ b/xbmc/windowing/android/WinSystemAndroid.h @@ -59,6 +59,7 @@ public: bool IsHDRDisplay() override; CHDRCapabilities GetDisplayHDRCapabilities() const override; + float GetGuiSdrPeakLuminance() const override; protected: std::unique_ptr<KODI::WINDOWING::IOSScreenSaver> GetOSScreenSaverImpl() override; diff --git a/xbmc/windowing/win10/WinSystemWin10.h b/xbmc/windowing/win10/WinSystemWin10.h index 78ac8c4f4f..c53fd01872 100644 --- a/xbmc/windowing/win10/WinSystemWin10.h +++ b/xbmc/windowing/win10/WinSystemWin10.h @@ -82,6 +82,7 @@ public: bool Show(bool raise = true) override; std::string GetClipboardText() override; bool UseLimitedColor() override; + float GetGuiSdrPeakLuminance() const override; bool HasSystemSdrPeakLuminance() override; // videosync @@ -98,7 +99,6 @@ public: virtual bool DPIChanged(WORD dpi, RECT windowRect) const; bool IsMinimized() const { return m_bMinimized; } void SetMinimized(bool minimized) { m_bMinimized = minimized; } - float GetGuiSdrPeakLuminance() const; void CacheSystemSdrPeakLuminance(); bool CanDoWindowed() override; diff --git a/xbmc/windowing/windows/WinSystemWin32.h b/xbmc/windowing/windows/WinSystemWin32.h index 31dc54c3a1..dabc28cb56 100644 --- a/xbmc/windowing/windows/WinSystemWin32.h +++ b/xbmc/windowing/windows/WinSystemWin32.h @@ -96,6 +96,7 @@ public: bool Show(bool raise = true) override; std::string GetClipboardText() override; bool UseLimitedColor() override; + float GetGuiSdrPeakLuminance() const override; bool HasSystemSdrPeakLuminance() override; // videosync @@ -114,7 +115,6 @@ public: virtual bool DPIChanged(WORD dpi, RECT windowRect) const; bool IsMinimized() const { return m_bMinimized; } void SetMinimized(bool minimized); - float GetGuiSdrPeakLuminance() const; void CacheSystemSdrPeakLuminance(); void SetSizeMoveMode(bool mode) { m_bSizeMoveEnabled = mode; } |