diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.cpp index 91c4630af77e6..684655f480520 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.cpp @@ -369,6 +369,9 @@ DXGI_COLOR_SPACE_TYPE CProcessorHD::GetDXGIColorSpace(CRenderBuffer* view, bool // DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_TOPLEFT_P2020 return DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020; + if (view->color_transfer == AVCOL_TRC_ARIB_STD_B67) // HLG + return DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_TOPLEFT_P2020; + if (view->full_range) return DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020; @@ -505,18 +508,26 @@ bool CProcessorHD::Render(CRect src, CRect dst, ID3D11Resource* target, CRenderB if (SUCCEEDED(m_pVideoContext.As(&videoCtx1))) { const DXGI_COLOR_SPACE_TYPE source_color = GetDXGIColorSpace(views[2], m_bSupportHDR10); - DXGI_COLOR_SPACE_TYPE target_color; + DXGI_COLOR_SPACE_TYPE target_color = DX::Windowing()->UseLimitedColor() + ? DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709 + : DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; - if (DX::DeviceResources::Get()->Is10BitSwapchain() && CRendererBase::IsStreamHDR10(views[2])) - { - target_color = DX::Windowing()->UseLimitedColor() - ? DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020 - : DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020; - } - else + if (DX::DeviceResources::Get()->Is10BitSwapchain()) { - target_color = DX::Windowing()->UseLimitedColor() ? DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709 - : DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; + if ((views[2]->color_transfer == AVCOL_TRC_SMPTE2084 || + views[2]->color_transfer == AVCOL_TRC_ARIB_STD_B67) && + views[2]->primaries == AVCOL_PRI_BT2020) + { + target_color = DX::Windowing()->UseLimitedColor() + ? DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020 + : DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020; + } + else if (views[2]->primaries == AVCOL_PRI_BT2020) + { + target_color = DX::Windowing()->UseLimitedColor() + ? DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020 + : DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020; + } } videoCtx1->VideoProcessorSetStreamColorSpace1(m_pVideoProcessor.Get(), DEFAULT_STREAM_INDEX, @@ -525,26 +536,23 @@ bool CProcessorHD::Render(CRect src, CRect dst, ID3D11Resource* target, CRenderB // makes target available for processing in shaders videoCtx1->VideoProcessorSetOutputShaderUsage(m_pVideoProcessor.Get(), 1); - if (m_bSupportHDR10 && (target_color == DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020 || - target_color == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020)) + if (m_bSupportHDR10 && views[2]->color_transfer == AVCOL_TRC_SMPTE2084 && + views[2]->primaries == AVCOL_PRI_BT2020) { - if (CRendererBase::IsStreamHDR10(views[2])) + ComPtr videoCtx2; + if (SUCCEEDED(m_pVideoContext.As(&videoCtx2))) { - ComPtr videoCtx2; - if (SUCCEEDED(m_pVideoContext.As(&videoCtx2))) - { - // Passes stream SEI HDR metadata to VideoProcessor (refresh changes during playback) - DXGI_HDR_METADATA_HDR10 hdr10Stream = CRendererBase::GetDXGIHDR10MetaData(views[2]); - videoCtx2->VideoProcessorSetStreamHDRMetaData( - m_pVideoProcessor.Get(), DEFAULT_STREAM_INDEX, DXGI_HDR_METADATA_TYPE_HDR10, - sizeof(hdr10Stream), &hdr10Stream); - - // Passes Display HDR parameters (EDID) to VideoProcessor - DXGI_HDR_METADATA_HDR10 hdr10Display = DX::DeviceResources::Get()->GetHdr10Display(); - videoCtx2->VideoProcessorSetOutputHDRMetaData(m_pVideoProcessor.Get(), - DXGI_HDR_METADATA_TYPE_HDR10, - sizeof(hdr10Display), &hdr10Display); - } + // Passes stream SEI HDR metadata to VideoProcessor (refresh changes during playback) + DXGI_HDR_METADATA_HDR10 hdr10Stream = CRendererBase::GetDXGIHDR10MetaData(views[2]); + videoCtx2->VideoProcessorSetStreamHDRMetaData(m_pVideoProcessor.Get(), DEFAULT_STREAM_INDEX, + DXGI_HDR_METADATA_TYPE_HDR10, + sizeof(hdr10Stream), &hdr10Stream); + + // Passes Display HDR parameters (EDID) to VideoProcessor + DXGI_HDR_METADATA_HDR10 hdr10Display = DX::DeviceResources::Get()->GetHdr10Display(); + videoCtx2->VideoProcessorSetOutputHDRMetaData(m_pVideoProcessor.Get(), + DXGI_HDR_METADATA_TYPE_HDR10, + sizeof(hdr10Display), &hdr10Display); } } } diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp index 58020087b872a..4cc0db52976d2 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.cpp @@ -134,7 +134,8 @@ CRendererBase::~CRendererBase() { if (DX::DeviceResources::Get()->IsDisplayHDREnabled()) { - DX::DeviceResources::Get()->ClearHdrMetaData(); + CLog::LogF(LOGDEBUG, "Restoring SDR rendering"); + DX::DeviceResources::Get()->SetColorSpace1(DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709); } } Flush(false); @@ -171,6 +172,8 @@ bool CRendererBase::Configure(const VideoPicture& picture, float fps, unsigned o m_lastHdr10 = {}; m_isHdrEnabled = false; + m_isHlgEnabled = false; + m_isRec2020Enabled = false; m_iCntMetaData = 0; return true; @@ -208,7 +211,7 @@ void CRendererBase::Render(CD3DTexture& target, const CRect& sourceRect, const C if (DX::DeviceResources::Get()->Is10BitSwapchain()) { - if (IsStreamHDR10(buf)) + if (buf->color_transfer == AVCOL_TRC_SMPTE2084 && buf->primaries == AVCOL_PRI_BT2020) // HDR10 { DXGI_HDR_METADATA_HDR10 hdr10 = GetDXGIHDR10MetaData(buf); if (m_isHdrEnabled) @@ -217,7 +220,7 @@ void CRendererBase::Render(CD3DTexture& target, const CRect& sourceRect, const C if (0 != std::memcmp(&hdr10, &m_lastHdr10, sizeof(hdr10))) { // Sets HDR10 metadata only - DX::DeviceResources::Get()->SetHdrMetaData(hdr10, false); + DX::DeviceResources::Get()->SetHdrMetaData(hdr10); m_lastHdr10 = hdr10; } } @@ -226,13 +229,38 @@ void CRendererBase::Render(CD3DTexture& target, const CRect& sourceRect, const C // Sets HDR10 metadata and enables HDR10 color space (switch to HDR rendering) if (DX::DeviceResources::Get()->IsDisplayHDREnabled()) { - DX::DeviceResources::Get()->SetHdrMetaData(hdr10, true); + DX::DeviceResources::Get()->SetHdrMetaData(hdr10); + CLog::LogF(LOGNOTICE, "Switching to HDR rendering"); + DX::DeviceResources::Get()->SetColorSpace1(DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020); m_isHdrEnabled = true; m_lastHdr10 = hdr10; } } m_iCntMetaData = 0; } + else if (buf->color_transfer == AVCOL_TRC_ARIB_STD_B67 && buf->primaries == AVCOL_PRI_BT2020) // HLG + { + if (!m_isHlgEnabled) + { + if (DX::DeviceResources::Get()->IsDisplayHDREnabled()) + { + // Switch to HLG rendering (internally converts HLG to HDR10) + CLog::LogF(LOGNOTICE, "Switching to HLG rendering"); + DX::DeviceResources::Get()->SetColorSpace1(DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020); + m_isHlgEnabled = true; + } + } + } + else if (buf->primaries == AVCOL_PRI_BT2020) + { + if (m_isRec2020Enabled == false) + { + // Switch to Rec.2020 rendering + CLog::LogF(LOGNOTICE, "Switching to Rec.2020 rendering"); + DX::DeviceResources::Get()->SetColorSpace1(DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020); + m_isRec2020Enabled = true; + } + } else { if (m_isHdrEnabled) @@ -241,11 +269,20 @@ void CRendererBase::Render(CD3DTexture& target, const CRect& sourceRect, const C if (m_iCntMetaData > 60) { // If more than 60 frames are received without HDR10 metadata switch to SDR rendering - DX::DeviceResources::Get()->ClearHdrMetaData(); + CLog::LogF(LOGNOTICE, "Switching to SDR rendering"); + DX::DeviceResources::Get()->SetColorSpace1(DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709); m_isHdrEnabled = false; m_iCntMetaData = 0; } } + if (m_isHlgEnabled || m_isRec2020Enabled) + { + // Switch to SDR rendering + CLog::LogF(LOGNOTICE, "Switching to SDR rendering"); + DX::DeviceResources::Get()->SetColorSpace1(DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709); + m_isHlgEnabled = false; + m_isRec2020Enabled = false; + } } } @@ -537,13 +574,3 @@ DXGI_HDR_METADATA_HDR10 CRendererBase::GetDXGIHDR10MetaData(CRenderBuffer* rb) } return hdr10; } - -bool CRendererBase::IsStreamHDR10(CRenderBuffer* rb) -{ - if ((rb->displayMetadata.has_luminance || rb->hasLightMetadata || - rb->color_transfer == AVCOL_TRC_SMPTE2084) && - rb->primaries == AVCOL_PRI_BT2020) - return true; - - return false; -} diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h index d669bad7d84dd..a67485236a6fd 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h +++ b/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererBase.h @@ -122,7 +122,6 @@ class CRendererBase static DXGI_FORMAT GetDXGIFormat(CVideoBuffer* videoBuffer); static AVPixelFormat GetAVFormat(DXGI_FORMAT dxgi_format); static DXGI_HDR_METADATA_HDR10 GetDXGIHDR10MetaData(CRenderBuffer* rb); - static bool IsStreamHDR10(CRenderBuffer* rb); protected: explicit CRendererBase(CVideoSettings& videoSettings); @@ -173,4 +172,6 @@ class CRendererBase DXGI_HDR_METADATA_HDR10 m_lastHdr10 = {}; int m_iCntMetaData = 0; bool m_isHdrEnabled = false; + bool m_isHlgEnabled = false; + bool m_isRec2020Enabled = false; }; diff --git a/xbmc/rendering/dx/DeviceResources.cpp b/xbmc/rendering/dx/DeviceResources.cpp index 9c606acf5a47d..3b3333895b2e5 100644 --- a/xbmc/rendering/dx/DeviceResources.cpp +++ b/xbmc/rendering/dx/DeviceResources.cpp @@ -1198,10 +1198,13 @@ bool DX::DeviceResources::IsDisplayHDREnabled() return hdrEnabled; } -void DX::DeviceResources::SetHdrMetaData(DXGI_HDR_METADATA_HDR10& hdr10, bool setColorSpace) const +void DX::DeviceResources::SetHdrMetaData(DXGI_HDR_METADATA_HDR10& hdr10) const { ComPtr swapChain4; + if (m_swapChain == nullptr) + return; + if (SUCCEEDED(m_swapChain.As(&swapChain4))) { if (SUCCEEDED(swapChain4->SetHDRMetaData(DXGI_HDR_METADATA_TYPE_HDR10, sizeof(hdr10), &hdr10))) @@ -1231,37 +1234,41 @@ void DX::DeviceResources::SetHdrMetaData(DXGI_HDR_METADATA_HDR10& hdr10, bool se { CLog::LogF(LOGERROR, "DXGI SetHDRMetaData failed"); } - - if (setColorSpace) - { - const DXGI_COLOR_SPACE_TYPE cs = DX::Windowing()->UseLimitedColor() - ? DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020 - : DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020; - - if (SUCCEEDED(swapChain4->SetColorSpace1(cs))) - { - CLog::LogF(LOGDEBUG, "DXGI SetColorSpace1 success"); - } - else - { - CLog::LogF(LOGERROR, "DXGI SetColorSpace1 failed"); - } - } } } -void DX::DeviceResources::ClearHdrMetaData() const +void DX::DeviceResources::SetColorSpace1(const DXGI_COLOR_SPACE_TYPE colorSpace) const { ComPtr swapChain3; - CLog::LogF(LOGDEBUG, "Restoring SDR rendering"); + if (m_swapChain == nullptr) + return; if (SUCCEEDED(m_swapChain.As(&swapChain3))) { - const DXGI_COLOR_SPACE_TYPE cs = DX::Windowing()->UseLimitedColor() - ? DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709 - : DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; - - swapChain3->SetColorSpace1(cs); + DXGI_COLOR_SPACE_TYPE cs = colorSpace; + if (DX::Windowing()->UseLimitedColor()) + { + switch (cs) + { + case DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709: + cs = DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709; + break; + case DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020: + cs = DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020; + break; + case DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020: + cs = DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020; + break; + } + } + if (SUCCEEDED(swapChain3->SetColorSpace1(cs))) + { + CLog::LogF(LOGDEBUG, "DXGI SetColorSpace1 success"); + } + else + { + CLog::LogF(LOGERROR, "DXGI SetColorSpace1 failed"); + } } } diff --git a/xbmc/rendering/dx/DeviceResources.h b/xbmc/rendering/dx/DeviceResources.h index 39491d20823bd..702136ced9803 100644 --- a/xbmc/rendering/dx/DeviceResources.h +++ b/xbmc/rendering/dx/DeviceResources.h @@ -11,7 +11,7 @@ #include #include #include -#if !defined(TARGET_WINDOWS_STORE) +#if defined(TARGET_WINDOWS_DESKTOP) #include #endif #include @@ -80,8 +80,8 @@ namespace DX bool SetFullScreen(bool fullscreen, RESOLUTION_INFO& res); bool IsDisplayHDREnabled(); - void SetHdrMetaData(DXGI_HDR_METADATA_HDR10& hdr10, bool setColorSpace) const; - void ClearHdrMetaData() const; + void SetHdrMetaData(DXGI_HDR_METADATA_HDR10& hdr10) const; + void SetColorSpace1(const DXGI_COLOR_SPACE_TYPE colorSpace) const; bool Is10BitSwapchain() const { return m_Is10bSwapchain; } DXGI_HDR_METADATA_HDR10 GetHdr10Display() const { return m_displayHDR10; }