aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCrystalP <crystalp@kodi.tv>2023-10-17 13:05:12 -0400
committerGitHub <noreply@github.com>2023-10-17 13:05:12 -0400
commit90b8fcf797e578f1d0cbbbfd7898e7ba1839c16b (patch)
treea1e827fbf08342760257890a65433b53cece1091
parent259a6ee947b862a6f167881fb6595b0cc199d0cb (diff)
parentc28972ed9114c60cc33df399d71fc33132e1d97a (diff)
downloadxbmc-90b8fcf797e578f1d0cbbbfd7898e7ba1839c16b.tar.xz
Merge pull request #23078 from CrystalP/fix-tonemapping
[rendering] use default luminance for tone mapping of streams with bad metadata, share with all platforms
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt8
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/ToneMappers.cpp54
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/ToneMappers.h23
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp42
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h1
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.cpp42
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.h1
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.cpp42
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h1
9 files changed, 104 insertions, 110 deletions
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt
index 76f18f0f20..5bb02199e7 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/CMakeLists.txt
@@ -6,15 +6,19 @@ set(HEADERS ConvolutionKernels.h
if(CORE_SYSTEM_NAME STREQUAL windows OR CORE_SYSTEM_NAME STREQUAL windowsstore)
list(APPEND SOURCES ConversionMatrix.cpp
+ ToneMappers.cpp
WinVideoFilter.cpp)
list(APPEND HEADERS ConversionMatrix.h
+ ToneMappers.h
WinVideoFilter.h)
endif()
if(TARGET OpenGL::GL OR TARGET OpenGL::GLES)
- list(APPEND SOURCES ConversionMatrix.cpp)
- list(APPEND HEADERS ConversionMatrix.h)
+ list(APPEND SOURCES ConversionMatrix.cpp
+ ToneMappers.cpp)
+ list(APPEND HEADERS ConversionMatrix.h
+ ToneMappers.h)
endif()
if(TARGET OpenGL::GL)
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/ToneMappers.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/ToneMappers.cpp
new file mode 100644
index 0000000000..f98cd71c01
--- /dev/null
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/ToneMappers.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "ToneMappers.h"
+
+float CToneMappers::GetLuminanceValue(bool hasDisplayMetadata,
+ const AVMasteringDisplayMetadata& displayMetadata,
+ bool hasLightMetadata,
+ const AVContentLightMetadata& lightMetadata)
+{
+ // default for bad quality HDR-PQ sources (missing or invalid metadata)
+ const float defaultLuminance = 400.0f;
+ float lum1 = defaultLuminance;
+
+ unsigned int maxLuminance = static_cast<unsigned int>(defaultLuminance);
+
+ if (hasDisplayMetadata && displayMetadata.has_luminance && displayMetadata.max_luminance.den)
+ {
+ const uint16_t lum = displayMetadata.max_luminance.num / displayMetadata.max_luminance.den;
+
+ if (lum > 0)
+ maxLuminance = lum;
+ }
+
+ if (hasLightMetadata)
+ {
+ float lum2;
+
+ if (lightMetadata.MaxCLL >= maxLuminance)
+ {
+ lum1 = static_cast<float>(maxLuminance);
+ lum2 = static_cast<float>(lightMetadata.MaxCLL);
+ }
+ else
+ {
+ lum1 = static_cast<float>(lightMetadata.MaxCLL);
+ lum2 = static_cast<float>(maxLuminance);
+ }
+ const float lum3 = static_cast<float>(lightMetadata.MaxFALL);
+
+ lum1 = (lum1 * 0.5f) + (lum2 * 0.2f) + (lum3 * 0.3f);
+ }
+ else if (hasDisplayMetadata && displayMetadata.has_luminance)
+ {
+ lum1 = static_cast<float>(maxLuminance);
+ }
+
+ return lum1;
+}
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/ToneMappers.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/ToneMappers.h
new file mode 100644
index 0000000000..0d668838cb
--- /dev/null
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/ToneMappers.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+extern "C"
+{
+#include <libavutil/mastering_display_metadata.h>
+}
+
+class CToneMappers
+{
+public:
+ static float GetLuminanceValue(bool hasDisplayMetadata,
+ const AVMasteringDisplayMetadata& displayMetadata,
+ bool hasLightMetadata,
+ const AVContentLightMetadata& lightMetadata);
+};
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp
index 83f146b248..e68976ca9c 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp
@@ -9,6 +9,7 @@
#include "WinVideoFilter.h"
#include "ConvolutionKernels.h"
+#include "ToneMappers.h"
#include "Util.h"
#include "VideoRenderers/windows/RendererBase.h"
#include "cores/VideoPlayer/VideoRenderers/VideoShaders/dither.h"
@@ -206,53 +207,24 @@ void COutputShader::ApplyEffectParameters(CD3DEffect &effect, unsigned sourceWid
}
else if (m_toneMapping && m_toneMappingMethod == VS_TONEMAPMETHOD_ACES)
{
- float lumin = GetLuminanceValue();
+ const float lumin = CToneMappers::GetLuminanceValue(m_hasDisplayMetadata, m_displayMetadata,
+ m_hasLightMetadata, m_lightMetadata);
effect.SetScalar("g_luminance", lumin);
effect.SetScalar("g_toneP1", m_toneMappingParam);
m_toneMappingDebug = lumin;
}
else if (m_toneMapping && m_toneMappingMethod == VS_TONEMAPMETHOD_HABLE)
{
- float lumin = GetLuminanceValue();
- float lumin_factor = (10000.0f / lumin) * (2.0f / m_toneMappingParam);
- float lumin_div100 = lumin / (100.0f * m_toneMappingParam);
+ const float lumin = CToneMappers::GetLuminanceValue(m_hasDisplayMetadata, m_displayMetadata,
+ m_hasLightMetadata, m_lightMetadata);
+ const float lumin_factor = (10000.0f / lumin) * (2.0f / m_toneMappingParam);
+ const float lumin_div100 = lumin / (100.0f * m_toneMappingParam);
effect.SetScalar("g_toneP1", lumin_factor);
effect.SetScalar("g_toneP2", lumin_div100);
m_toneMappingDebug = lumin;
}
}
-float COutputShader::GetLuminanceValue() const
-{
- float lum1 = 400.0f; // default for bad quality HDR-PQ sources (with no metadata)
- float lum2 = lum1;
- float lum3 = lum1;
-
- if (m_hasLightMetadata)
- {
- uint16_t lum = m_displayMetadata.max_luminance.num / m_displayMetadata.max_luminance.den;
- if (m_lightMetadata.MaxCLL >= lum)
- {
- lum1 = static_cast<float>(lum);
- lum2 = static_cast<float>(m_lightMetadata.MaxCLL);
- }
- else
- {
- lum1 = static_cast<float>(m_lightMetadata.MaxCLL);
- lum2 = static_cast<float>(lum);
- }
- lum3 = static_cast<float>(m_lightMetadata.MaxFALL);
- lum1 = (lum1 * 0.5f) + (lum2 * 0.2f) + (lum3 * 0.3f);
- }
- else if (m_hasDisplayMetadata && m_displayMetadata.has_luminance)
- {
- uint16_t lum = m_displayMetadata.max_luminance.num / m_displayMetadata.max_luminance.den;
- lum1 = static_cast<float>(lum);
- }
-
- return lum1;
-}
-
void COutputShader::GetDefines(DefinesMap& map) const
{
if (m_useLut)
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h
index de901afcc1..d559dda519 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h
@@ -91,7 +91,6 @@ private:
void PrepareParameters(unsigned sourceWidth, unsigned sourceHeight, CRect sourceRect, const CPoint points[4]);
void SetShaderParameters(CD3DTexture &sourceTexture, unsigned range, float contrast, float brightness);
void CreateDitherView();
- float GetLuminanceValue() const;
bool m_useLut = false;
bool m_useDithering = false;
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.cpp
index 4491ad2464..e9ff471f3d 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.cpp
@@ -12,6 +12,7 @@
#include "../RenderFlags.h"
#include "ConvolutionKernels.h"
#include "ServiceBroker.h"
+#include "ToneMappers.h"
#include "settings/AdvancedSettings.h"
#include "settings/SettingsComponent.h"
#include "utils/GLUtils.h"
@@ -192,13 +193,16 @@ bool BaseYUV2RGBGLSLShader::OnEnabled()
}
else if (m_toneMappingMethod == VS_TONEMAPMETHOD_ACES)
{
- glUniform1f(m_hLuminance, GetLuminanceValue());
+ const float lumin = CToneMappers::GetLuminanceValue(m_hasDisplayMetadata, m_displayMetadata,
+ m_hasLightMetadata, m_lightMetadata);
+ glUniform1f(m_hLuminance, lumin);
glUniform1f(m_hToneP1, m_toneMappingParam);
}
else if (m_toneMappingMethod == VS_TONEMAPMETHOD_HABLE)
{
- float lumin = GetLuminanceValue();
- float param = (10000.0f / lumin) * (2.0f / m_toneMappingParam);
+ const float lumin = CToneMappers::GetLuminanceValue(m_hasDisplayMetadata, m_displayMetadata,
+ m_hasLightMetadata, m_lightMetadata);
+ const float param = (10000.0f / lumin) * (2.0f / m_toneMappingParam);
glUniform1f(m_hLuminance, lumin);
glUniform1f(m_hToneP1, param);
}
@@ -256,38 +260,6 @@ void BaseYUV2RGBGLSLShader::SetToneMapParam(ETONEMAPMETHOD method, float param)
m_toneMappingParam = param;
}
-float BaseYUV2RGBGLSLShader::GetLuminanceValue() const //Maybe move this to linuxrenderer?! same as in baserenderer
-{
- float lum1 = 400.0f; // default for bad quality HDR-PQ sources (with no metadata)
- float lum2 = lum1;
- float lum3 = lum1;
-
- if (m_hasLightMetadata)
- {
- uint16_t lum = m_displayMetadata.max_luminance.num / m_displayMetadata.max_luminance.den;
- if (m_lightMetadata.MaxCLL >= lum)
- {
- lum1 = static_cast<float>(lum);
- lum2 = static_cast<float>(m_lightMetadata.MaxCLL);
- }
- else
- {
- lum1 = static_cast<float>(m_lightMetadata.MaxCLL);
- lum2 = static_cast<float>(lum);
- }
- lum3 = static_cast<float>(m_lightMetadata.MaxFALL);
- lum1 = (lum1 * 0.5f) + (lum2 * 0.2f) + (lum3 * 0.3f);
- }
- else if (m_hasDisplayMetadata && m_displayMetadata.has_luminance &&
- m_displayMetadata.max_luminance.num)
- {
- uint16_t lum = m_displayMetadata.max_luminance.num / m_displayMetadata.max_luminance.den;
- lum1 = static_cast<float>(lum);
- }
-
- return lum1;
-}
-
//////////////////////////////////////////////////////////////////////
// YUV2RGBProgressiveShader - YUV2RGB with no deinterlacing
// Use for weave deinterlacing / progressive
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.h
index 18e10faf91..6604291049 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGL.h
@@ -54,7 +54,6 @@ public:
bool hasLightMetadata,
AVContentLightMetadata lightMetadata);
void SetToneMapParam(ETONEMAPMETHOD method, float param);
- float GetLuminanceValue() const;
void SetConvertFullColorRange(bool convertFullRange) { m_convertFullRange = convertFullRange; }
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.cpp
index 4682a3db1a..63e4d304a4 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.cpp
@@ -10,6 +10,7 @@
#include "YUV2RGBShaderGLES.h"
#include "../RenderFlags.h"
+#include "ToneMappers.h"
#include "settings/AdvancedSettings.h"
#include "utils/GLUtils.h"
#include "utils/log.h"
@@ -158,13 +159,16 @@ bool BaseYUV2RGBGLSLShader::OnEnabled()
}
else if (m_toneMappingMethod == VS_TONEMAPMETHOD_ACES)
{
- glUniform1f(m_hLuminance, GetLuminanceValue());
+ const float lumin = CToneMappers::GetLuminanceValue(m_hasDisplayMetadata, m_displayMetadata,
+ m_hasLightMetadata, m_lightMetadata);
+ glUniform1f(m_hLuminance, lumin);
glUniform1f(m_hToneP1, m_toneMappingParam);
}
else if (m_toneMappingMethod == VS_TONEMAPMETHOD_HABLE)
{
- float lumin = GetLuminanceValue();
- float param = (10000.0f / lumin) * (2.0f / m_toneMappingParam);
+ const float lumin = CToneMappers::GetLuminanceValue(m_hasDisplayMetadata, m_displayMetadata,
+ m_hasLightMetadata, m_lightMetadata);
+ const float param = (10000.0f / lumin) * (2.0f / m_toneMappingParam);
glUniform1f(m_hLuminance, lumin);
glUniform1f(m_hToneP1, param);
}
@@ -211,38 +215,6 @@ void BaseYUV2RGBGLSLShader::SetDisplayMetadata(bool hasDisplayMetadata,
m_lightMetadata = lightMetadata;
}
-float BaseYUV2RGBGLSLShader::GetLuminanceValue() const
-{
- float lum1 = 400.0f; // default for bad quality HDR-PQ sources (with no metadata)
- float lum2 = lum1;
- float lum3 = lum1;
-
- if (m_hasLightMetadata)
- {
- uint16_t lum = m_displayMetadata.max_luminance.num / m_displayMetadata.max_luminance.den;
- if (m_lightMetadata.MaxCLL >= lum)
- {
- lum1 = static_cast<float>(lum);
- lum2 = static_cast<float>(m_lightMetadata.MaxCLL);
- }
- else
- {
- lum1 = static_cast<float>(m_lightMetadata.MaxCLL);
- lum2 = static_cast<float>(lum);
- }
- lum3 = static_cast<float>(m_lightMetadata.MaxFALL);
- lum1 = (lum1 * 0.5f) + (lum2 * 0.2f) + (lum3 * 0.3f);
- }
- else if (m_hasDisplayMetadata && m_displayMetadata.has_luminance &&
- m_displayMetadata.max_luminance.num > 0)
- {
- uint16_t lum = m_displayMetadata.max_luminance.num / m_displayMetadata.max_luminance.den;
- lum1 = static_cast<float>(lum);
- }
-
- return lum1;
-}
-
//////////////////////////////////////////////////////////////////////
// YUV2RGBProgressiveShader - YUV2RGB with no deinterlacing
// Use for weave deinterlacing / progressive
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h
index df369f518f..44b1a8221a 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/YUV2RGBShaderGLES.h
@@ -45,7 +45,6 @@ class BaseYUV2RGBGLSLShader : public CGLSLShaderProgram
bool hasLightMetadata,
AVContentLightMetadata lightMetadata);
void SetToneMapParam(float param) { m_toneMappingParam = param; }
- float GetLuminanceValue() const;
GLint GetVertexLoc() { return m_hVertex; }
GLint GetYcoordLoc() { return m_hYcoord; }