diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/addons/skin.estuary/xml/MyPVRTimers.xml kodi-21.0+git20230429.0301-54e9471bc6/addons/skin.estuary/xml/MyPVRTimers.xml
--- kodi-21.0+git20230427.0301-9164f7ee91/addons/skin.estuary/xml/MyPVRTimers.xml 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/addons/skin.estuary/xml/MyPVRTimers.xml 2013-05-12 08:41:54.000000000 +0000
@@ -57,29 +57,29 @@
-
-
-
-
-
-
-
-
- 20
- OpenClose_Right
- 10
- 850
- 60
-
- black
- right
- center
- true
- font27
-
-
- MediaMenuCommon
- PVRSideBar
+
+
+
+
+
+
+
+ 20
+ OpenClose_Right
+ 10
+ 850
+ 60
+
+ black
+ right
+ center
+ true
+ font27
+
+
+ MediaMenuCommon
+ PVRSideBar
+
diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/BUILDDATE kodi-21.0+git20230429.0301-54e9471bc6/BUILDDATE
--- kodi-21.0+git20230427.0301-9164f7ee91/BUILDDATE 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/BUILDDATE 2013-05-12 08:41:54.000000000 +0000
@@ -1 +1 @@
-20230427
+20230429
diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/debian/changelog kodi-21.0+git20230429.0301-54e9471bc6/debian/changelog
--- kodi-21.0+git20230427.0301-9164f7ee91/debian/changelog 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/debian/changelog 2013-05-12 08:41:54.000000000 +0000
@@ -1,4 +1,4 @@
-kodi (6:21.0+git20230427.0301-9164f7ee91-0~kinetic) kinetic; urgency=medium
+kodi (6:21.0+git20230429.0301-54e9471bc6-0~kinetic) kinetic; urgency=medium
[ kodi ]
* autogenerated dummy changelog
diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/VERSION kodi-21.0+git20230429.0301-54e9471bc6/VERSION
--- kodi-21.0+git20230427.0301-9164f7ee91/VERSION 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/VERSION 2013-05-12 08:41:54.000000000 +0000
@@ -1 +1 @@
-9164f7ee91
+54e9471bc6
diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.cpp kodi-21.0+git20230429.0301-54e9471bc6/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.cpp
--- kodi-21.0+git20230427.0301-9164f7ee91/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.cpp 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.cpp 2013-05-12 08:41:54.000000000 +0000
@@ -20,6 +20,19 @@
namespace DRMPRIME
{
+KODI::UTILS::Colorimetry GetColorimetry(const VideoPicture& picture)
+{
+ switch (picture.color_space)
+ {
+ case AVCOL_SPC_BT2020_CL:
+ return KODI::UTILS::Colorimetry::BT2020_CYCC;
+ case AVCOL_SPC_BT2020_NCL:
+ return KODI::UTILS::Colorimetry::BT2020_YCC;
+ default:
+ return KODI::UTILS::Colorimetry::DEFAULT;
+ }
+}
+
std::string GetColorEncoding(const VideoPicture& picture)
{
switch (picture.color_space)
diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.h kodi-21.0+git20230429.0301-54e9471bc6/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.h
--- kodi-21.0+git20230427.0301-9164f7ee91/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.h 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.h 2013-05-12 08:41:54.000000000 +0000
@@ -35,6 +35,7 @@
HDMI_EOTF_BT_2100_HLG,
};
+KODI::UTILS::Colorimetry GetColorimetry(const VideoPicture& picture);
std::string GetColorEncoding(const VideoPicture& picture);
std::string GetColorRange(const VideoPicture& picture);
KODI::UTILS::Eotf GetEOTF(const VideoPicture& picture);
diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.cpp kodi-21.0+git20230429.0301-54e9471bc6/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.cpp
--- kodi-21.0+git20230427.0301-9164f7ee91/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.cpp 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.cpp 2013-05-12 08:41:54.000000000 +0000
@@ -17,6 +17,7 @@
#include "VideoRenderers/RenderManager.h"
#include "VideoRenderers/windows/RendererBase.h"
#include "rendering/dx/RenderContext.h"
+#include "utils/StringUtils.h"
#include "utils/log.h"
#include
@@ -64,6 +65,7 @@
void CProcessorHD::Close()
{
std::unique_lock lock(m_section);
+ m_pEnumerator1 = nullptr;
m_pEnumerator = nullptr;
m_pVideoProcessor = nullptr;
m_pVideoContext = nullptr;
@@ -105,6 +107,7 @@
m_pVideoDevice = nullptr;
m_pVideoContext = nullptr;
m_pEnumerator = nullptr;
+ m_pEnumerator1 = nullptr;
ComPtr pD3DDeviceContext = DX::DeviceResources::Get()->GetImmediateContext();
ComPtr pD3DDevice = DX::DeviceResources::Get()->GetD3DDevice();
@@ -140,6 +143,12 @@
return false;
}
+ if (FAILED(hr = m_pEnumerator.As(&m_pEnumerator1)))
+ {
+ CLog::LogF(LOGDEBUG, "ID3D11VideoProcessorEnumerator1 not available on this system. Message {}",
+ DX::GetErrorDescription(hr));
+ }
+
if (CServiceBroker::GetLogging().IsLogLevelLogged(LOGDEBUG))
{
std::string inputFormats{};
@@ -259,33 +268,31 @@
}
}
- ComPtr pEnumerator1;
-
- if (SUCCEEDED(m_pEnumerator.As(&pEnumerator1)))
+ if (m_pEnumerator1)
{
DXGI_FORMAT format = DX::Windowing()->GetBackBuffer().GetFormat();
BOOL supported = 0;
HRESULT hr;
// Check if HLG color space conversion is supported by driver
- hr = pEnumerator1->CheckVideoProcessorFormatConversion(
+ hr = m_pEnumerator1->CheckVideoProcessorFormatConversion(
DXGI_FORMAT_P010, DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_TOPLEFT_P2020, format,
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709, &supported);
m_bSupportHLG = SUCCEEDED(hr) && !!supported;
// Check if HDR10 RGB limited range output is supported by driver
- hr = pEnumerator1->CheckVideoProcessorFormatConversion(
+ hr = m_pEnumerator1->CheckVideoProcessorFormatConversion(
DXGI_FORMAT_P010, DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020, format,
DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020, &supported);
m_bSupportHDR10Limited = SUCCEEDED(hr) && !!supported;
// Check if driver prefers YCbCr TOP LEFT for 10 bit BT.2020
- hr = pEnumerator1->CheckVideoProcessorFormatConversion(
+ hr = m_pEnumerator1->CheckVideoProcessorFormatConversion(
DXGI_FORMAT_P010, DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020, format,
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709, &supported);
const bool left = SUCCEEDED(hr) && static_cast(supported);
- hr = pEnumerator1->CheckVideoProcessorFormatConversion(
+ hr = m_pEnumerator1->CheckVideoProcessorFormatConversion(
DXGI_FORMAT_P010, DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_TOPLEFT_P2020, format,
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709, &supported);
const bool topLeft = SUCCEEDED(hr) && static_cast(supported);
@@ -326,40 +333,35 @@
bool CProcessorHD::IsFormatConversionSupported(DXGI_FORMAT inputFormat,
DXGI_FORMAT outputFormat,
- const VideoPicture& picture) const
+ const VideoPicture& picture)
{
+ std::unique_lock lock(m_section);
+
// accept the conversion unless the API can be called successfully and disallows it
BOOL supported{TRUE};
- ComPtr enumerator1;
- if (SUCCEEDED(m_pEnumerator.As(&enumerator1)))
- {
- ProcColorSpaces spaces = CalculateDXGIColorSpaces(DXGIColorSpaceArgs(picture));
+ if (!m_pEnumerator1)
+ return true;
- HRESULT hr;
- if (SUCCEEDED(hr = enumerator1->CheckVideoProcessorFormatConversion(
- inputFormat, spaces.inputColorSpace, outputFormat, spaces.outputColorSpace,
- &supported)))
- {
- CLog::LogF(LOGDEBUG, "conversion from {} / {} to {} / {} is {}supported.",
- DX::DXGIFormatToString(inputFormat),
- DX::DXGIColorSpaceTypeToString(spaces.inputColorSpace),
- DX::DXGIFormatToString(outputFormat),
- DX::DXGIColorSpaceTypeToString(spaces.outputColorSpace), supported ? "" : "not ");
- }
- else
- {
- CLog::LogF(LOGERROR, "unable to validate the format conversion, error {}",
- DX::GetErrorDescription(hr));
- }
+ ProcColorSpaces spaces = CalculateDXGIColorSpaces(DXGIColorSpaceArgs(picture));
+
+ HRESULT hr;
+ if (SUCCEEDED(hr = m_pEnumerator1->CheckVideoProcessorFormatConversion(
+ inputFormat, spaces.inputColorSpace, outputFormat, spaces.outputColorSpace,
+ &supported)))
+ {
+ CLog::LogF(
+ LOGDEBUG, "conversion from {} / {} to {} / {} is {}supported.",
+ DX::DXGIFormatToString(inputFormat), DX::DXGIColorSpaceTypeToString(spaces.inputColorSpace),
+ DX::DXGIFormatToString(outputFormat),
+ DX::DXGIColorSpaceTypeToString(spaces.outputColorSpace), supported == TRUE ? "" : "NOT ");
}
else
{
- CLog::LogF(
- LOGDEBUG,
- "ID3D11VideoProcessorEnumerator1 not available on this system, accepting the conversion.");
+ CLog::LogF(LOGERROR, "unable to validate the format conversion, error {}",
+ DX::GetErrorDescription(hr));
}
- return supported;
+ return supported == TRUE;
}
bool CProcessorHD::Open(UINT width, UINT height)
@@ -814,3 +816,216 @@
"Input color space BT.2020 is not supported by video processor. DXVA will not be used.");
return false;
}
+
+void CProcessorHD::ListSupportedConversions(const DXGI_FORMAT& inputFormat,
+ const DXGI_FORMAT& heuristicsOutputFormat,
+ const VideoPicture& picture)
+{
+ std::unique_lock lock(m_section);
+
+ // Windows 8 and above compatible code
+ if (!m_pEnumerator)
+ return;
+
+ HRESULT hr;
+ UINT uiFlags;
+
+ if (FAILED(hr = m_pEnumerator->CheckVideoProcessorFormat(inputFormat, &uiFlags)))
+ {
+ CLog::LogF(LOGDEBUG, "unable to retrieve processor support of input format {}. Error {}",
+ DX::DXGIFormatToString(inputFormat), DX::GetErrorDescription(hr));
+ return;
+ }
+ else if (!(uiFlags & D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT))
+ {
+ CLog::LogF(LOGERROR, "input format {} not supported by the processor. No conversion possible.",
+ DX::DXGIFormatToString(inputFormat));
+ return;
+ }
+
+ // Windows 10 and above from this point on
+ if (!m_pEnumerator1)
+ return;
+
+ const DXGIColorSpaceArgs csArgs = DXGIColorSpaceArgs(picture);
+
+ // Defaults used by Kodi
+ const ProcColorSpaces heuristicsCS = CalculateDXGIColorSpaces(csArgs);
+ BOOL supported{FALSE};
+
+ const DXGI_COLOR_SPACE_TYPE inputNativeCS = AvToDxgiColorSpace(csArgs);
+ CLog::LogF(LOGDEBUG, "The source is {} / {}", DX::DXGIFormatToString(inputFormat),
+ DX::DXGIColorSpaceTypeToString(inputNativeCS));
+
+ if (SUCCEEDED(hr = m_pEnumerator1->CheckVideoProcessorFormatConversion(
+ inputFormat, inputNativeCS, heuristicsOutputFormat,
+ heuristicsCS.outputColorSpace, &supported)))
+ {
+ CLog::LogF(LOGDEBUG, "conversion from {} / {} to {} / {} is {}supported.",
+ DX::DXGIFormatToString(inputFormat), DX::DXGIColorSpaceTypeToString(inputNativeCS),
+ DX::DXGIFormatToString(heuristicsOutputFormat),
+ DX::DXGIColorSpaceTypeToString(heuristicsCS.outputColorSpace),
+ supported == TRUE ? "" : "NOT ");
+ }
+ else
+ {
+ CLog::LogF(LOGERROR, "unable to validate the default format conversion, error {}",
+ DX::GetErrorDescription(hr));
+ }
+
+ // Possible input color spaces: YCbCr only
+ std::vector ycbcrColorSpaces;
+ // Possible output color spaces: RGB only
+ std::vector rgbColorSpaces;
+
+ for (UINT colorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
+ colorSpace < DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_TOPLEFT_P2020; ++colorSpace)
+ {
+ DXGI_COLOR_SPACE_TYPE cs = static_cast(colorSpace);
+
+ constexpr std::string_view rgb("RGB_");
+ if (DX::DXGIColorSpaceTypeToString(cs).compare(0, rgb.size(), rgb) == 0)
+ rgbColorSpaces.push_back(cs);
+
+ constexpr std::string_view ycbcr("YCBCR_");
+ if (DX::DXGIColorSpaceTypeToString(cs).compare(0, ycbcr.size(), ycbcr) == 0)
+ ycbcrColorSpaces.push_back(cs);
+ }
+
+ // Only probe the output formats of RGB/BGR type supported by the processor.
+ std::vector outputFormats;
+ for (const auto& format : GetProcessorOutputFormats())
+ {
+ std::string name = DX::DXGIFormatToString(format);
+ if (name.find('R') != std::string::npos && name.find('G') != std::string::npos &&
+ name.find('B') != std::string::npos)
+ outputFormats.push_back(format);
+ }
+
+ // Color spaces supported directly by the swap chain - as a set for easy lookup
+ std::vector bbcs = DX::DeviceResources::Get()->GetSwapChainColorSpaces();
+ std::set backbufferColorSpaces(bbcs.begin(), bbcs.end());
+
+ std::string conversions;
+
+ // The input format cannot be worked around and is fixed.
+ // Loop over the lists of:
+ // - input color spaces
+ // - output formats
+ // - output color spaces
+ for (const DXGI_COLOR_SPACE_TYPE& inputCS : ycbcrColorSpaces)
+ {
+ for (const DXGI_FORMAT& outputFormat : outputFormats)
+ {
+ for (const DXGI_COLOR_SPACE_TYPE& outputCS : rgbColorSpaces)
+ {
+ if (SUCCEEDED(m_pEnumerator1->CheckVideoProcessorFormatConversion(
+ inputFormat, inputCS, outputFormat, outputCS, &supported)) &&
+ supported == TRUE)
+ {
+ conversions.append("\n");
+ conversions.append(StringUtils::Format(
+ "{} {} / {}{} {:<{}} to {} {:<{}} / {}{} {:<{}}", "*",
+ DX::DXGIFormatToString(inputFormat),
+ (inputCS == heuristicsCS.inputColorSpace) ? "*" : " ",
+ (inputCS == inputNativeCS) ? "N" : " ", DX::DXGIColorSpaceTypeToString(inputCS), 32,
+ (outputFormat == heuristicsOutputFormat) ? "*" : " ",
+ DX::DXGIFormatToString(outputFormat), 26,
+ (outputCS == heuristicsCS.outputColorSpace) ? "*" : " ",
+ (backbufferColorSpaces.find(outputCS) != backbufferColorSpaces.end()) ? "bb" : " ",
+ DX::DXGIColorSpaceTypeToString(outputCS), 32));
+ }
+ }
+ }
+ }
+
+ CLog::LogF(LOGDEBUG,
+ "supported conversions from format {}\n(*: values picked by "
+ "heuristics, N native input color space, bb supported as swap chain backbuffer){}",
+ DX::DXGIFormatToString(inputFormat), conversions);
+}
+
+std::vector CProcessorHD::GetProcessorOutputFormats() const
+{
+ std::vector result;
+
+ UINT uiFlags;
+ for (int fmt = DXGI_FORMAT_UNKNOWN; fmt <= DXGI_FORMAT_V408; fmt++)
+ {
+ DXGI_FORMAT dxgiFormat = static_cast(fmt);
+ if (S_OK == m_pEnumerator->CheckVideoProcessorFormat(dxgiFormat, &uiFlags) &&
+ uiFlags & D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_OUTPUT)
+ result.push_back(dxgiFormat);
+ }
+ return result;
+}
+
+DXGI_COLOR_SPACE_TYPE CProcessorHD::AvToDxgiColorSpace(const DXGIColorSpaceArgs& csArgs)
+{
+ // RGB
+ if (csArgs.color_space == AVCOL_SPC_RGB)
+ {
+ if (!csArgs.full_range)
+ {
+ if (csArgs.primaries == AVCOL_PRI_BT2020)
+ {
+ if (csArgs.color_transfer == AVCOL_TRC_SMPTEST2084)
+ return DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020;
+
+ return DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020;
+ }
+ return DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709;
+ }
+
+ if (csArgs.primaries == AVCOL_PRI_BT2020)
+ {
+ if (csArgs.color_transfer == AVCOL_TRC_SMPTEST2084)
+ return DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020;
+
+ return DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020;
+ }
+ if (csArgs.color_transfer == AVCOL_TRC_LINEAR || csArgs.color_transfer == AVCOL_TRC_LOG)
+ return DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709;
+
+ return DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
+ }
+ // UHDTV
+ if (csArgs.primaries == AVCOL_PRI_BT2020)
+ {
+ if (csArgs.color_transfer == AVCOL_TRC_SMPTEST2084)
+ // Full range DXGI_COLOR_SPACE_YCBCR_FULL_G2084_LEFT_P2020 does not exist at this time
+ return DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020;
+
+ // HLG transfer can be used for HLG source in SDR display if is supported
+ if (csArgs.color_transfer == AVCOL_TRC_ARIB_STD_B67)
+ {
+ if (csArgs.full_range)
+ return DXGI_COLOR_SPACE_YCBCR_FULL_GHLG_TOPLEFT_P2020;
+ else
+ return DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_TOPLEFT_P2020;
+ }
+
+ if (csArgs.full_range)
+ return DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020;
+ else
+ return DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020;
+ }
+ // SDTV
+ if (csArgs.primaries == AVCOL_PRI_BT470BG || csArgs.primaries == AVCOL_PRI_SMPTE170M)
+ {
+ if (csArgs.full_range)
+ return DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601;
+
+ return DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601;
+ }
+ // HDTV
+ if (csArgs.full_range)
+ {
+ if (csArgs.color_transfer == AVCOL_TRC_SMPTE170M)
+ return DXGI_COLOR_SPACE_YCBCR_FULL_G22_NONE_P709_X601;
+
+ return DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709;
+ }
+
+ return DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709;
+}
diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.h kodi-21.0+git20230429.0301-54e9471bc6/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.h
--- kodi-21.0+git20230427.0301-9164f7ee91/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.h 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.h 2013-05-12 08:41:54.000000000 +0000
@@ -95,12 +95,21 @@
* Always returns true when the Windows 10+ API is not available or cannot be called successfully.
* \param inputFormat The source format
* \param outputFormat The destination format
- * \param picture Picutre information used to derive the color spaces
+ * \param picture Picture information used to derive the color spaces
* \return true if the conversion is supported, false otherwise
*/
bool IsFormatConversionSupported(DXGI_FORMAT inputFormat,
DXGI_FORMAT outputFormat,
- const VideoPicture& picture) const;
+ const VideoPicture& picture);
+ /*!
+ * \brief Outputs in the log a list of conversions supported by the DXVA processor.
+ * \param inputFormat The source format
+ * \param outputFormat The destination format
+ * \param picture Picture information used to derive the color spaces
+ */
+ void ListSupportedConversions(const DXGI_FORMAT& inputFormat,
+ const DXGI_FORMAT& outputFormat,
+ const VideoPicture& picture);
// ID3DResource overrides
void OnCreateDevice() override {}
@@ -132,6 +141,17 @@
DXGI_COLOR_SPACE_TYPE GetDXGIColorSpaceTarget(const DXGIColorSpaceArgs& csArgs,
bool supportHDR,
bool limitedRange) const;
+ /*!
+ * \brief Converts ffmpeg AV parameters to a DXGI color space
+ * \param csArgs ffmpeg AV picture parameters
+ * \return DXGI color space
+ */
+ static DXGI_COLOR_SPACE_TYPE AvToDxgiColorSpace(const DXGIColorSpaceArgs& csArgs);
+ /*!
+ * \brief Retrieve the list of DXGI_FORMAT supported as output by the DXVA processor
+ * \return Vector of formats
+ */
+ std::vector GetProcessorOutputFormats() const;
CCriticalSection m_section;
@@ -155,6 +175,7 @@
Microsoft::WRL::ComPtr m_pVideoDevice;
Microsoft::WRL::ComPtr m_pVideoContext;
Microsoft::WRL::ComPtr m_pEnumerator;
+ Microsoft::WRL::ComPtr m_pEnumerator1;
Microsoft::WRL::ComPtr m_pVideoProcessor;
};
diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererDXVA.cpp kodi-21.0+git20230429.0301-54e9471bc6/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererDXVA.cpp
--- kodi-21.0+git20230427.0301-9164f7ee91/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererDXVA.cpp 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererDXVA.cpp 2013-05-12 08:41:54.000000000 +0000
@@ -111,10 +111,13 @@
// create processor
m_processor = std::make_unique();
if (m_processor->PreInit() && m_processor->Open(m_sourceWidth, m_sourceHeight) &&
- m_processor->IsFormatSupported(dxgi_format, support_type) &&
- m_processor->IsFormatConversionSupported(dxgi_format, dest_format, picture))
+ m_processor->IsFormatSupported(dxgi_format, support_type))
{
- return true;
+ if (CServiceBroker::GetLogging().IsLogLevelLogged(LOGDEBUG))
+ m_processor->ListSupportedConversions(dxgi_format, dest_format, picture);
+
+ if (m_processor->IsFormatConversionSupported(dxgi_format, dest_format, picture))
+ return true;
}
CLog::LogF(LOGERROR, "unable to create DXVA processor");
diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/xbmc/rendering/dx/DeviceResources.cpp kodi-21.0+git20230429.0301-54e9471bc6/xbmc/rendering/dx/DeviceResources.cpp
--- kodi-21.0+git20230427.0301-9164f7ee91/xbmc/rendering/dx/DeviceResources.cpp 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/xbmc/rendering/dx/DeviceResources.cpp 2013-05-12 08:41:54.000000000 +0000
@@ -716,26 +716,13 @@
if (CServiceBroker::GetLogging().IsLogLevelLogged(LOGDEBUG))
{
- ComPtr swapChain4;
- if (SUCCEEDED(m_swapChain.As(&swapChain4)))
+ std::string colorSpaces;
+ for (const DXGI_COLOR_SPACE_TYPE& colorSpace : GetSwapChainColorSpaces())
{
- UINT colorSpaceSupport = 0;
- std::string colorSpaces{};
- for (UINT colorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
- colorSpace < DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_TOPLEFT_P2020; colorSpace++)
- {
- if (SUCCEEDED(swapChain4->CheckColorSpaceSupport(
- static_cast(colorSpace), &colorSpaceSupport)) &&
- (colorSpaceSupport & DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT) ==
- DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT)
- {
- colorSpaces.append("\n");
- colorSpaces.append(
- DX::DXGIColorSpaceTypeToString(static_cast(colorSpace)));
- }
- }
- CLog::LogF(LOGDEBUG, "Color spaces supported by the swap chain:{}", colorSpaces);
+ colorSpaces.append("\n");
+ colorSpaces.append(DX::DXGIColorSpaceTypeToString(colorSpace));
}
+ CLog::LogF(LOGDEBUG, "Color spaces supported by the swap chain:{}", colorSpaces);
}
// Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
@@ -1384,8 +1371,8 @@
"Swapchain: {} buffers, flip {}, {}, EOTF: {} (Windows HDR {})", desc.BufferCount,
(desc.SwapEffect == DXGI_SWAP_EFFECT_FLIP_DISCARD) ? "discard" : "sequential",
Windowing()->IsFullScreen()
- ? ((desc.Flags == DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH) ? "fullscreen exclusive"
- : "fullscreen windowed")
+ ? ((desc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH) ? "fullscreen exclusive"
+ : "fullscreen windowed")
: "windowed screen",
m_IsTransferPQ ? "PQ" : "SDR", m_IsHDROutput ? "on" : "off");
@@ -1399,3 +1386,31 @@
return info;
}
+
+std::vector DX::DeviceResources::GetSwapChainColorSpaces() const
+{
+ if (!m_swapChain)
+ return {};
+
+ std::vector result;
+ HRESULT hr;
+
+ ComPtr swapChain3;
+ if (SUCCEEDED(hr = m_swapChain.As(&swapChain3)))
+ {
+ UINT colorSpaceSupport = 0;
+ for (UINT colorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
+ colorSpace < DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_TOPLEFT_P2020; colorSpace++)
+ {
+ DXGI_COLOR_SPACE_TYPE cs = static_cast(colorSpace);
+ if (SUCCEEDED(swapChain3->CheckColorSpaceSupport(cs, &colorSpaceSupport)) &&
+ (colorSpaceSupport & DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT))
+ result.push_back(cs);
+ }
+ }
+ else
+ {
+ CLog::LogF(LOGDEBUG, "IDXGISwapChain3 is not available. Error {}", DX::GetErrorDescription(hr));
+ }
+ return result;
+}
diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/xbmc/rendering/dx/DeviceResources.h kodi-21.0+git20230429.0301-54e9471bc6/xbmc/rendering/dx/DeviceResources.h
--- kodi-21.0+git20230427.0301-9164f7ee91/xbmc/rendering/dx/DeviceResources.h 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/xbmc/rendering/dx/DeviceResources.h 2013-05-12 08:41:54.000000000 +0000
@@ -117,6 +117,7 @@
// Gets debug info from swapchain
DEBUG_INFO_RENDER GetDebugInfo() const;
+ std::vector GetSwapChainColorSpaces() const;
private:
class CBackBuffer : public CD3DTexture
diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/xbmc/utils/DisplayInfo.cpp kodi-21.0+git20230429.0301-54e9471bc6/xbmc/utils/DisplayInfo.cpp
--- kodi-21.0+git20230427.0301-9164f7ee91/xbmc/utils/DisplayInfo.cpp 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/xbmc/utils/DisplayInfo.cpp 2013-05-12 08:41:54.000000000 +0000
@@ -103,6 +103,12 @@
switch (cta_tag)
{
+ case DI_CTA_DATA_BLOCK_COLORIMETRY:
+ {
+ m_colorimetry = di_cta_data_block_get_colorimetry(block);
+
+ break;
+ }
case DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA:
{
m_hdr_static_metadata = di_cta_data_block_get_hdr_static_metadata(block);
@@ -144,6 +150,21 @@
m_hdr_static_metadata->desired_content_max_frame_avg_luminance,
m_hdr_static_metadata->desired_content_max_luminance);
}
+
+ if (m_colorimetry)
+ {
+ CLog::Log(LOGINFO, "[display-info] supported colorimetry:");
+ CLog::Log(LOGINFO, "[display-info] xvycc_601: {}", m_colorimetry->xvycc_601);
+ CLog::Log(LOGINFO, "[display-info] xvycc_709: {}", m_colorimetry->xvycc_709);
+ CLog::Log(LOGINFO, "[display-info] sycc_601: {}", m_colorimetry->sycc_601);
+ CLog::Log(LOGINFO, "[display-info] opycc_601: {}", m_colorimetry->opycc_601);
+ CLog::Log(LOGINFO, "[display-info] oprgb: {}", m_colorimetry->oprgb);
+ CLog::Log(LOGINFO, "[display-info] bt2020_cycc: {}", m_colorimetry->bt2020_cycc);
+ CLog::Log(LOGINFO, "[display-info] bt2020_ycc: {}", m_colorimetry->bt2020_ycc);
+ CLog::Log(LOGINFO, "[display-info] bt2020_rgb: {}", m_colorimetry->bt2020_rgb);
+ CLog::Log(LOGINFO, "[display-info] st2113_rgb: {}", m_colorimetry->st2113_rgb);
+ CLog::Log(LOGINFO, "[display-info] ictcp: {}", m_colorimetry->ictcp);
+ }
}
bool CDisplayInfo::SupportsHDRStaticMetadataType1() const
@@ -172,4 +193,36 @@
default:
return false;
}
+}
+
+bool CDisplayInfo::SupportsColorimetry(Colorimetry colorimetry) const
+{
+ if (!m_colorimetry)
+ return false;
+
+ switch (colorimetry)
+ {
+ case Colorimetry::XVYCC_601:
+ return m_colorimetry->xvycc_601;
+ case Colorimetry::XVYCC_709:
+ return m_colorimetry->xvycc_709;
+ case Colorimetry::SYCC_601:
+ return m_colorimetry->sycc_601;
+ case Colorimetry::OPYCC_601:
+ return m_colorimetry->opycc_601;
+ case Colorimetry::OPRGB:
+ return m_colorimetry->oprgb;
+ case Colorimetry::BT2020_CYCC:
+ return m_colorimetry->bt2020_cycc;
+ case Colorimetry::BT2020_YCC:
+ return m_colorimetry->bt2020_ycc;
+ case Colorimetry::BT2020_RGB:
+ return m_colorimetry->bt2020_rgb;
+ case Colorimetry::ST2113_RGB:
+ return m_colorimetry->st2113_rgb;
+ case Colorimetry::ICTCP:
+ return m_colorimetry->ictcp;
+ default:
+ return false;
+ }
}
diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/xbmc/utils/DisplayInfo.h kodi-21.0+git20230429.0301-54e9471bc6/xbmc/utils/DisplayInfo.h
--- kodi-21.0+git20230427.0301-9164f7ee91/xbmc/utils/DisplayInfo.h 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/xbmc/utils/DisplayInfo.h 2013-05-12 08:41:54.000000000 +0000
@@ -14,6 +14,7 @@
#include
struct di_info;
+struct di_cta_colorimetry_block;
struct di_cta_hdr_static_metadata_block;
namespace KODI
@@ -29,6 +30,21 @@
HLG,
};
+enum class Colorimetry
+{
+ DEFAULT,
+ XVYCC_601,
+ XVYCC_709,
+ SYCC_601,
+ OPYCC_601,
+ OPRGB,
+ BT2020_CYCC,
+ BT2020_YCC,
+ BT2020_RGB,
+ ST2113_RGB,
+ ICTCP,
+};
+
class CDisplayInfo
{
public:
@@ -40,6 +56,8 @@
bool SupportsEOTF(Eotf eotf) const;
+ bool SupportsColorimetry(Colorimetry colorimetry) const;
+
private:
explicit CDisplayInfo(const std::vector& edid);
@@ -57,6 +75,7 @@
std::string m_make;
std::string m_model;
+ const di_cta_colorimetry_block* m_colorimetry = nullptr;
const di_cta_hdr_static_metadata_block* m_hdr_static_metadata = nullptr;
};
diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/xbmc/windowing/gbm/drm/DRMObject.cpp kodi-21.0+git20230429.0301-54e9471bc6/xbmc/windowing/gbm/drm/DRMObject.cpp
--- kodi-21.0+git20230427.0301-9164f7ee91/xbmc/windowing/gbm/drm/DRMObject.cpp 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/xbmc/windowing/gbm/drm/DRMObject.cpp 2013-05-12 08:41:54.000000000 +0000
@@ -80,8 +80,8 @@
return true;
}
-std::optional CDRMObject::GetPropertyValue(const std::string& name,
- const std::string& valueName) const
+std::optional CDRMObject::GetPropertyValue(std::string_view name,
+ std::string_view valueName) const
{
auto property = std::find_if(m_propsInfo.begin(), m_propsInfo.end(),
[&name](const auto& prop) { return prop->name == name; });
diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/xbmc/windowing/gbm/drm/DRMObject.h kodi-21.0+git20230429.0301-54e9471bc6/xbmc/windowing/gbm/drm/DRMObject.h
--- kodi-21.0+git20230427.0301-9164f7ee91/xbmc/windowing/gbm/drm/DRMObject.h 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/xbmc/windowing/gbm/drm/DRMObject.h 2013-05-12 08:41:54.000000000 +0000
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include
#include
@@ -35,8 +36,7 @@
uint32_t GetId() const { return m_id; }
uint32_t GetPropertyId(const std::string& name) const;
- std::optional GetPropertyValue(const std::string& name,
- const std::string& valueName) const;
+ std::optional GetPropertyValue(std::string_view name, std::string_view valueName) const;
bool SetProperty(const std::string& name, uint64_t value);
bool SupportsProperty(const std::string& name);
diff -Nru kodi-21.0+git20230427.0301-9164f7ee91/xbmc/windowing/gbm/WinSystemGbm.cpp kodi-21.0+git20230429.0301-54e9471bc6/xbmc/windowing/gbm/WinSystemGbm.cpp
--- kodi-21.0+git20230427.0301-9164f7ee91/xbmc/windowing/gbm/WinSystemGbm.cpp 2013-05-12 08:41:54.000000000 +0000
+++ kodi-21.0+git20230429.0301-54e9471bc6/xbmc/windowing/gbm/WinSystemGbm.cpp 2013-05-12 08:41:54.000000000 +0000
@@ -22,6 +22,7 @@
#include "settings/SettingsComponent.h"
#include "settings/lib/Setting.h"
#include "utils/DisplayInfo.h"
+#include "utils/Map.h"
#include "utils/StringUtils.h"
#include "utils/log.h"
#include "windowing/GraphicContext.h"
@@ -62,6 +63,27 @@
using namespace std::chrono_literals;
+namespace
+{
+
+// These map to the definitions in the linux kernel
+// drivers/gpu/drm/drm_connector.c
+
+constexpr auto ColorimetryMap = make_map({
+ {KODI::UTILS::Colorimetry::DEFAULT, "Default"},
+ {KODI::UTILS::Colorimetry::XVYCC_601, "XVYCC_601"},
+ {KODI::UTILS::Colorimetry::XVYCC_709, "XVYCC_709"},
+ {KODI::UTILS::Colorimetry::SYCC_601, "SYCC_601"},
+ {KODI::UTILS::Colorimetry::OPYCC_601, "opYCC_601"},
+ {KODI::UTILS::Colorimetry::OPRGB, "opRGB"},
+ {KODI::UTILS::Colorimetry::BT2020_CYCC, "BT2020_CYCC"},
+ {KODI::UTILS::Colorimetry::BT2020_YCC, "BT2020_YCC"},
+ {KODI::UTILS::Colorimetry::BT2020_RGB, "BT2020_RGB"},
+ {KODI::UTILS::Colorimetry::ST2113_RGB, "Default"},
+ {KODI::UTILS::Colorimetry::ICTCP, "Default"},
+});
+} // namespace
+
CWinSystemGbm::CWinSystemGbm() :
m_DRM(nullptr),
m_GBM(new CGBMUtils),
@@ -343,9 +365,23 @@
if (!drm)
return false;
+ auto connector = drm->GetConnector();
+ if (!connector)
+ return false;
+
if (!videoPicture)
{
- auto connector = drm->GetConnector();
+ if (connector->SupportsProperty("Colorspace"))
+ {
+ std::optional colorspace = connector->GetPropertyValue("Colorspace", "Default");
+ if (colorspace)
+ {
+ CLog::LogF(LOGDEBUG, "setting connector colorspace to Default");
+ drm->AddProperty(connector, "Colorspace", colorspace.value());
+ drm->SetActive(true);
+ }
+ }
+
if (connector->SupportsProperty("HDR_OUTPUT_METADATA"))
{
drm->AddProperty(connector, "HDR_OUTPUT_METADATA", 0);
@@ -359,9 +395,23 @@
return true;
}
+ KODI::UTILS::Colorimetry colorimetry = DRMPRIME::GetColorimetry(*videoPicture);
+
+ if (connector->SupportsProperty("Colorspace") && m_info &&
+ m_info->SupportsColorimetry(colorimetry))
+ {
+ std::optional colorspace =
+ connector->GetPropertyValue("Colorspace", ColorimetryMap.at(colorimetry));
+ if (colorspace)
+ {
+ CLog::LogF(LOGDEBUG, "setting connector colorspace to {}", ColorimetryMap.at(colorimetry));
+ drm->AddProperty(connector, "Colorspace", colorspace.value());
+ drm->SetActive(true);
+ }
+ }
+
KODI::UTILS::Eotf eotf = DRMPRIME::GetEOTF(*videoPicture);
- auto connector = drm->GetConnector();
if (connector->SupportsProperty("HDR_OUTPUT_METADATA") && m_info &&
m_info->SupportsHDRStaticMetadataType1() && m_info->SupportsEOTF(eotf))
{