aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/resource.language.en_gb/resources/strings.po183
-rw-r--r--addons/skin.estuary/1080i/VideoOSD.xml8
-rw-r--r--configure.ac30
-rw-r--r--system/settings/settings.xml143
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/CMakeLists.txt2
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.cpp550
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.h173
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/Makefile.in1
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/RenderFlags.h10
-rw-r--r--xbmc/guilib/GUIWindowManager.cpp3
-rw-r--r--xbmc/guilib/WindowIDs.h1
-rw-r--r--xbmc/input/ButtonTranslator.cpp1
-rw-r--r--xbmc/settings/DisplaySettings.cpp87
-rw-r--r--xbmc/settings/DisplaySettings.h6
-rw-r--r--xbmc/settings/SettingConditions.cpp3
-rw-r--r--xbmc/settings/Settings.cpp12
-rw-r--r--xbmc/settings/Settings.h2
-rw-r--r--xbmc/video/dialogs/CMakeLists.txt2
-rw-r--r--xbmc/video/dialogs/GUIDialogCMSSettings.cpp243
-rw-r--r--xbmc/video/dialogs/GUIDialogCMSSettings.h52
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoOSD.cpp1
-rw-r--r--xbmc/video/dialogs/Makefile1
22 files changed, 1507 insertions, 7 deletions
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
index 3cb54266c4..e668d89285 100644
--- a/addons/resource.language.en_gb/resources/strings.po
+++ b/addons/resource.language.en_gb/resources/strings.po
@@ -18502,7 +18502,188 @@ msgctxt "#36552"
msgid "Defines the number of presentation buffers used by the graphics driver. Select 2 if the driver uses double buffering or 3 for triple buffering."
msgstr ""
-#empty strings from id 36553 to 36597
+#: system/settings/settings.xml
+msgctxt "#36560"
+msgid "Color management"
+msgstr ""
+
+#. Description of setting "System -> Video output -> Color management" with label #36560
+#: system/settings/settings.xml
+msgctxt "#36561"
+msgid "Reproduce video colors accurately using a display profile or a 3D lookup table."
+msgstr ""
+
+#: system/settings/settings.xml
+msgctxt "#36562"
+msgid "Color management mode"
+msgstr ""
+
+#. Description of setting "System -> Video output -> Color management mode" with label #36562
+#: system/settings/settings.xml
+msgctxt "#36563"
+msgid "Use a precalculated 3D lookup table for video color correction, or calculate the transformation for each video from a profile of your display. A precalculated 3D lookup table is preferred as it allows you to take advantage of the advanced features and high precision in ArgyllCMS. Display profile based correction is useful for testing different parameters, or emulating display settings that you don't have a 3D LUT prepared for."
+msgstr ""
+
+#: system/settings/settings.xml
+msgctxt "#36564"
+msgid "3D LUT"
+msgstr ""
+
+#. Description of setting "System -> Video output -> 3D LUT" with label #36564
+#: system/settings/settings.xml
+msgctxt "#36565"
+msgid "TODO: 3D LUT filename description"
+msgstr ""
+
+#: system/settings/settings.xml
+msgctxt "#36566"
+msgid "ICC display profile"
+msgstr ""
+
+#. Description of setting "System -> Video output -> ICC display profile" with label #36566
+#: system/settings/settings.xml
+msgctxt "#36567"
+msgid "TODO: ICC display profile filename description"
+msgstr ""
+
+#: system/settings/settings.xml
+msgctxt "#36568"
+msgid "Whitepoint"
+msgstr ""
+
+#. Description of setting "System -> Video output -> Whitepoint" with label #36568
+#: system/settings/settings.xml
+msgctxt "#36569"
+msgid "TODO: Whitepoint selection description"
+msgstr ""
+
+#: system/settings/settings.xml
+msgctxt "#36570"
+msgid "Primaries"
+msgstr ""
+
+#. Description of setting "System -> Video output -> Primaries" with label #36570
+#: system/settings/settings.xml
+msgctxt "#36571"
+msgid "TODO: Primary coordinates description"
+msgstr ""
+
+#: system/settings/settings.xml
+msgctxt "#36572"
+msgid "Gamma mode"
+msgstr ""
+
+#. Description of setting "System -> Video output -> Gamma mode" with label #36572
+#: system/settings/settings.xml
+msgctxt "#36573"
+msgid "TODO: Gamma mode description"
+msgstr ""
+
+#: system/settings/settings.xml
+msgctxt "#36574"
+msgid "Gamma"
+msgstr ""
+
+#. Description of setting "System -> Video output -> Gamma" with label #36574
+#: system/settings/settings.xml
+msgctxt "#36575"
+msgid "TODO: Gamma description"
+msgstr ""
+
+#: system/settings/settings.xml
+msgctxt "#36576"
+msgid "Lookup table size"
+msgstr ""
+
+#. Description of setting "System -> Video output -> Lookup table size" with label #36576
+#: system/settings/settings.xml
+msgctxt "#36577"
+msgid "TODO: Lookup table size description"
+msgstr ""
+
+# Dialog title for 3D LUT file picker
+#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp
+msgctxt "#36580"
+msgid "3D LUT file"
+msgstr ""
+
+# Dialog title for ICC display profile file picker
+#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp
+msgctxt "#36581"
+msgid "ICC Profile"
+msgstr ""
+
+#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp
+#. gamma type labels
+msgctxt "#36582"
+msgid "BT.1886"
+msgstr ""
+
+msgctxt "#36583"
+msgid "Input offset"
+msgstr ""
+
+msgctxt "#36584"
+msgid "Output offset"
+msgstr ""
+
+msgctxt "#36585"
+msgid "Absolute"
+msgstr ""
+
+#: xbmc/video/dialogs/GUIDialogCMSSettings.cpp
+#. whitepoint labels
+msgctxt "#36586"
+msgid "D65 (standard)"
+msgstr ""
+
+msgctxt "#36587"
+msgid "D93 (Japanese NTSC)"
+msgstr ""
+
+#: xbmc/video/dialogs/GUIDialogCMSSettings.cpp
+#. primaries labels
+msgctxt "#36588"
+msgid "Automatic"
+msgstr ""
+
+msgctxt "#36589"
+msgid "HDTV (BT.709)"
+msgstr ""
+
+msgctxt "#36590"
+msgid "SDTV (SMPTE C)"
+msgstr ""
+
+msgctxt "#36591"
+msgid "NTSC 1953 (BT.470 M)"
+msgstr ""
+
+msgctxt "#36592"
+msgid "PAL/SECAM 1975 (BT.470 B/G)"
+msgstr ""
+
+msgctxt "#36593"
+msgid "HDTV 1988 (SMPTE 240M)"
+msgstr ""
+
+#: xbmc/video/dialogs/GUIDialogCMSSettings.cpp
+#. 3D LUT size labels
+msgctxt "#36594"
+msgid "16x16x16"
+msgstr ""
+
+msgctxt "#36595"
+msgid "64x64x64"
+msgstr ""
+
+msgctxt "#36596"
+msgid "256x256x256"
+msgstr ""
+
+msgctxt "#36597"
+msgid "%1.2f"
+msgstr ""
#. Description of setting with label #36099 "Dither"
#: system/settings/settings.xml
diff --git a/addons/skin.estuary/1080i/VideoOSD.xml b/addons/skin.estuary/1080i/VideoOSD.xml
index 4bb00929a1..4cef09dcc5 100644
--- a/addons/skin.estuary/1080i/VideoOSD.xml
+++ b/addons/skin.estuary/1080i/VideoOSD.xml
@@ -22,7 +22,7 @@
<animation effect="fade" start="100" end="0" time="200">WindowClose</animation>
<control type="group">
<top>900</top>
- <visible>!Window.IsVisible(fullscreeninfo) + !Window.IsActive(osdaudiosettings) + !Window.IsActive(osdvideosettings) + !Window.IsActive(PVROSDChannels) + !Window.IsActive(PVROSDGuide)</visible>
+ <visible>!Window.IsVisible(fullscreeninfo) + !Window.IsActive(osdaudiosettings) + !Window.IsActive(osdvideosettings) + !Window.IsActive(osdcmssettings) + !Window.IsActive(PVROSDChannels) + !Window.IsActive(PVROSDGuide)</visible>
<animation effect="fade" end="100" time="200">WindowOpen</animation>
<animation effect="fade" time="200">VisibleChange</animation>
<animation effect="fade" start="100" end="0" time="200">WindowClose</animation>
@@ -310,6 +310,12 @@
<label>$LOCALIZE[13395]</label>
<onclick>ActivateWindow(osdvideosettings)</onclick>
</control>
+ <control type="button" id="11105">
+ <width>470</width>
+ <include>DefaultSettingButton</include>
+ <label>$LOCALIZE[36560]</label>
+ <onclick>ActivateWindow(osdcmssettings)</onclick>
+ </control>
<control type="button" id="11103">
<width>470</width>
<include>DefaultSettingButton</include>
diff --git a/configure.ac b/configure.ac
index 8cc0ba8d8b..174c57c279 100644
--- a/configure.ac
+++ b/configure.ac
@@ -208,6 +208,9 @@ libusb_disabled="== libusb disabled. Plug and play USB device support will not b
libusb_disabled_udev_found="== libusb disabled. =="
libcec_enabled="== libcec enabled. =="
libcec_disabled="== libcec disabled. CEC adapter support will not be available. =="
+lcms2_enabled="== lcms2 enabled. =="
+lcms2_not_found="== Could not find lcms2. ICC profile support will not be available. =="
+lcms2_disabled="== lcms2 disabled. ICC profile support will not be available. =="
libbluetooth_not_found="== Could not find libbluetooth. Bluetooth support will not be available =="
libbluetooth_enabled="== libbluetooth enabled. =="
libbluetooth_disabled="== libbluetooth disabled. Bluetooth support will not be available. =="
@@ -442,6 +445,12 @@ AC_ARG_ENABLE([libcec],
[use_libcec=$enableval],
[use_libcec=auto])
+AC_ARG_ENABLE([lcms2],
+ [AS_HELP_STRING([--enable-lcms2],
+ [enable lcms2 support (default is auto)])],
+ [use_lcms2=$enableval],
+ [use_lcms2=auto])
+
AC_ARG_ENABLE([libbluetooth],
[AS_HELP_STRING([--enable-libbluetooth],
[enable libbluetooth support (default is auto)])],
@@ -1444,6 +1453,21 @@ else
AC_MSG_NOTICE($libcec_disabled)
fi
+# lcms2
+if test "$use_lcms2" = "auto"; then
+ PKG_CHECK_MODULES([LCMS2],[lcms2],,[use_lcms2="no";AC_MSG_RESULT($lcms2_not_found)])
+elif test "$use_lcms2" = "yes" ; then
+ PKG_CHECK_MODULES([LCMS2],[lcms2],,[use_lcms2="no";AC_MSG_ERROR($lcms2_not_found)])
+else
+ AC_MSG_NOTICE($lcms2_disabled)
+fi
+
+if test "x$use_lcms2" != "xno"; then
+ USE_LCMS2=1;INCLUDES="$INCLUDES $LCMS2_CFLAGS";LIBS="$LIBS $LCMS2_LIBS"
+ AC_DEFINE([HAVE_LCMS2],[1],["Define to 1 if lcms2 is installed"])
+ AC_MSG_NOTICE($lcms2_enabled)
+fi
+
# libbluetooth
USE_LIBBLUETOOTH=0
if test "$use_libbluetooth" = "auto"; then
@@ -2074,6 +2098,12 @@ else
final_message="$final_message\n libcec support:\tNo"
fi
+if test "x$use_lcms2" != "xno"; then
+ final_message="$final_message\n lcms2 support:\tYes"
+else
+ final_message="$final_message\n lcms2 support:\tNo"
+fi
+
if test "x$use_libbluetooth" != "xno"; then
final_message="$final_message\n libbluetooth support:\tYes"
else
diff --git a/system/settings/settings.xml b/system/settings/settings.xml
index 53a4fe31b5..42c24eba10 100644
--- a/system/settings/settings.xml
+++ b/system/settings/settings.xml
@@ -2546,6 +2546,149 @@
<hidevalue>true</hidevalue>
</control>
</setting>
+ <setting id="videoscreen.cmsenabled" type="boolean" label="36560" help="36561">
+ <requirement>HAS_GL</requirement>
+ <level>3</level>
+ <default>false</default>
+ <control type="toggle" />
+ </setting>
+ <setting id="videoscreen.cmsmode" type="integer" label="36562" help="36563">
+ <requirement>HAS_GL</requirement>
+ <level>3</level>
+ <default>0</default>
+ <constraints>
+ <options>cmsmodes</options>
+ </constraints>
+ <dependencies>
+ <dependency type="visible" setting="videoscreen.cmsenabled" operator="is">true</dependency>
+ </dependencies>
+ <control type="list" format="integer"/>
+ </setting>
+ <setting id="videoscreen.cms3dlut" type="string" label="36564" help="36565">
+ <requirement>
+ <and>
+ <condition>HAS_GL</condition>
+ </and>
+ </requirement>
+ <level>3</level>
+ <default></default>
+ <constraints>
+ <allowempty>true</allowempty>
+ </constraints>
+ <dependencies>
+ <dependency type="visible" setting="videoscreen.cmsenabled" operator="is">true</dependency>
+ <dependency type="visible" setting="videoscreen.cmsmode" operator="is">0</dependency>
+ </dependencies>
+ <control type="button" format="action" />
+ </setting>
+ <setting id="videoscreen.displayprofile" type="string" label="36566" help="36567">
+ <requirement>
+ <and>
+ <condition>HAS_GL</condition>
+ <condition>HAVE_LCMS2</condition>
+ </and>
+ </requirement>
+ <level>3</level>
+ <default></default>
+ <constraints>
+ <allowempty>true</allowempty>
+ </constraints>
+ <dependencies>
+ <dependency type="visible" setting="videoscreen.cmsenabled" operator="is">true</dependency>
+ <dependency type="visible" setting="videoscreen.cmsmode" operator="is">1</dependency>
+ </dependencies>
+ <control type="button" format="action" />
+ </setting>
+ <setting id="videoscreen.cmswhitepoint" type="integer" label="36568" help="36569">
+ <requirement>
+ <and>
+ <condition>HAS_GL</condition>
+ <condition>HAVE_LCMS2</condition>
+ </and>
+ </requirement>
+ <level>3</level>
+ <default>0</default>
+ <constraints>
+ <options>cmswhitepoints</options>
+ </constraints>
+ <dependencies>
+ <dependency type="visible" setting="videoscreen.cmsenabled" operator="is">true</dependency>
+ <dependency type="visible" setting="videoscreen.cmsmode" operator="is">1</dependency>
+ </dependencies>
+ <control type="list" format="integer"/>
+ </setting>
+ <setting id="videoscreen.cmsprimaries" type="integer" label="36570" help="36571">
+ <requirement>
+ <and>
+ <condition>HAS_GL</condition>
+ <condition>HAVE_LCMS2</condition>
+ </and>
+ </requirement>
+ <level>3</level>
+ <default>0</default>
+ <constraints>
+ <options>cmsprimaries</options>
+ </constraints>
+ <dependencies>
+ <dependency type="visible" setting="videoscreen.cmsenabled" operator="is">true</dependency>
+ <dependency type="visible" setting="videoscreen.cmsmode" operator="is">1</dependency>
+ </dependencies>
+ <control type="list" format="integer"/>
+ </setting>
+ <setting id="videoscreen.cmsgammamode" type="integer" label="36572" help="36573">
+ <requirement>
+ <and>
+ <condition>HAS_GL</condition>
+ <condition>HAVE_LCMS2</condition>
+ </and>
+ </requirement>
+ <level>3</level>
+ <default>0</default>
+ <constraints>
+ <options>cmsgammamodes</options>
+ </constraints>
+ <dependencies>
+ <dependency type="visible" setting="videoscreen.cmsenabled" operator="is">true</dependency>
+ <dependency type="visible" setting="videoscreen.cmsmode" operator="is">1</dependency>
+ </dependencies>
+ <control type="list" format="integer"/>
+ </setting>
+ <setting id="videoscreen.cmsgamma" type="integer" label="36574" help="36575">
+ <requirement>
+ <and>
+ <condition>HAS_GL</condition>
+ <condition>HAVE_LCMS2</condition>
+ </and>
+ </requirement>
+ <level>3</level>
+ <default>220</default>
+ <constraints>
+ <minimum>160</minimum>
+ <step>005</step>
+ <maximum>280</maximum>
+ </constraints>
+ <dependencies>
+ <dependency type="visible" setting="videoscreen.cmsenabled" operator="is">true</dependency>
+ <dependency type="visible" setting="videoscreen.cmsmode" operator="is">1</dependency>
+ <dependency type="visible" setting="videoscreen.cmsgammamode" operator="!is">0</dependency>
+ </dependencies>
+ <control type="spinner" format="integer" />
+ </setting>
+ <setting id="videoscreen.cmslutsize" type="integer" label="36576" help="36577">
+ <requirement>HAS_GL</requirement>
+ <level>3</level>
+ <default>6</default>
+ <constraints>
+ <minimum>4</minimum>
+ <step>1</step>
+ <maximum>8</maximum>
+ </constraints>
+ <dependencies>
+ <dependency type="visible" setting="videoscreen.cmsenabled" operator="is">true</dependency>
+ <dependency type="visible" setting="videoscreen.cmsmode" operator="is">1</dependency>
+ </dependencies>
+ <control type="spinner" format="integer" />
+ </setting>
</group>
</category>
<category id="cache" label="439" help="36399">
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/CMakeLists.txt b/xbmc/cores/VideoPlayer/VideoRenderers/CMakeLists.txt
index 4426735c03..3a1eb557c8 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/CMakeLists.txt
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/CMakeLists.txt
@@ -2,6 +2,7 @@ enable_language(CXX ASM)
set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp" )
set(SOURCES BaseRenderer.cpp
+ ColorManager.cpp
OverlayRenderer.cpp
OverlayRendererGUI.cpp
OverlayRendererUtil.cpp
@@ -11,6 +12,7 @@ set(SOURCES BaseRenderer.cpp
DebugRenderer.cpp)
set(HEADERS BaseRenderer.h
+ ColorManager.h
OverlayRenderer.h
OverlayRendererGUI.h
OverlayRendererUtil.h
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.cpp
new file mode 100644
index 0000000000..cea04a7ba8
--- /dev/null
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.cpp
@@ -0,0 +1,550 @@
+/*
+ * Copyright (C) 2016 Lauri Mylläri
+ * http://kodi.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <math.h>
+#include <string>
+
+#include "system.h"
+#include "ColorManager.h"
+#include "cores/VideoPlayer/VideoRenderers/RenderFlags.h"
+#include "filesystem/File.h"
+#include "settings/Settings.h"
+#include "utils/log.h"
+#include "utils/TimeUtils.h"
+
+using namespace XFILE;
+
+CColorManager &CColorManager::Get()
+{
+ static CColorManager s_colorManager;
+ return s_colorManager;
+}
+
+CColorManager::CColorManager()
+{
+ curVideoPrimaries = CMS_PRIMARIES_AUTO;
+ curClutSize = 0;
+ curCmsToken = 0;
+ curCmsMode = 0;
+ cur3dlutFile = "";
+ curIccProfile = "";
+}
+
+CColorManager::~CColorManager()
+{
+}
+
+bool CColorManager::IsEnabled()
+{
+ //TODO: check that the configuration is valid here (files exist etc)
+
+ return CSettings::GetInstance().GetBool("videoscreen.cmsenabled");
+}
+
+CMS_PRIMARIES videoFlagsToPrimaries(int flags)
+{
+ if (flags & CONF_FLAGS_COLPRI_BT709) return CMS_PRIMARIES_BT709;
+ if (flags & CONF_FLAGS_COLPRI_170M) return CMS_PRIMARIES_170M;
+ if (flags & CONF_FLAGS_COLPRI_BT470M) return CMS_PRIMARIES_BT470M;
+ if (flags & CONF_FLAGS_COLPRI_BT470BG) return CMS_PRIMARIES_BT470BG;
+ if (flags & CONF_FLAGS_COLPRI_240M) return CMS_PRIMARIES_240M;
+ return CMS_PRIMARIES_BT709; // default to bt.709
+}
+
+bool CColorManager::GetVideo3dLut(int videoFlags, int *cmsToken, int *clutSize, uint16_t **clutData)
+{
+ CMS_PRIMARIES videoPrimaries = videoFlagsToPrimaries(videoFlags);
+ CLog::Log(LOGDEBUG, "video primaries: %d\n", (int)videoPrimaries);
+ switch (CSettings::GetInstance().GetInt("videoscreen.cmsmode"))
+ {
+ case CMS_MODE_3DLUT:
+ CLog::Log(LOGDEBUG, "ColorManager: CMS_MODE_3DLUT\n");
+ cur3dlutFile = CSettings::GetInstance().GetString("videoscreen.cms3dlut");
+ if (!Load3dLut(cur3dlutFile, clutData, clutSize))
+ return false;
+ curCmsMode = CMS_MODE_3DLUT;
+ break;
+
+ case CMS_MODE_PROFILE:
+ CLog::Log(LOGDEBUG, "ColorManager: CMS_MODE_PROFILE\n");
+#if defined(HAVE_LCMS2)
+ {
+ bool changed = false;
+ // check if display profile is not loaded, or has changed
+ if (curIccProfile != CSettings::GetInstance().GetString("videoscreen.displayprofile"))
+ {
+ changed = true;
+ // free old profile if there is one
+ if (m_hProfile)
+ cmsCloseProfile(m_hProfile);
+ // load profile
+ m_hProfile = LoadIccDisplayProfile(CSettings::GetInstance().GetString("videoscreen.displayprofile"));
+ if (!m_hProfile)
+ return false;
+ // detect blackpoint
+ if (cmsDetectBlackPoint(&m_blackPoint, m_hProfile, INTENT_PERCEPTUAL, 0))
+ {
+ CLog::Log(LOGDEBUG, "black point: %f\n", m_blackPoint.Y);
+ }
+ curIccProfile = CSettings::GetInstance().GetString("videoscreen.displayprofile");
+ }
+ // create gamma curve
+ cmsToneCurve* gammaCurve;
+ curIccGammaMode = (CMS_TRC_TYPE)CSettings::GetInstance().GetInt("videoscreen.cmsgammamode");
+ curIccGamma = CSettings::GetInstance().GetInt("videoscreen.cmsgamma");
+ gammaCurve =
+ CreateToneCurve(curIccGammaMode, curIccGamma/100.0f, m_blackPoint);
+
+ // create source profile
+ curIccWhitePoint = (CMS_WHITEPOINT)CSettings::GetInstance().GetInt("videoscreen.cmswhitepoint");
+ curIccPrimaries = (CMS_PRIMARIES)CSettings::GetInstance().GetInt("videoscreen.cmsprimaries");
+ CLog::Log(LOGDEBUG, "primaries setting: %d\n", (int)curIccPrimaries);
+ if (curIccPrimaries == CMS_PRIMARIES_AUTO) curIccPrimaries = videoPrimaries;
+ CLog::Log(LOGDEBUG, "source profile primaries: %d\n", (int)curIccPrimaries);
+ cmsHPROFILE sourceProfile =
+ CreateSourceProfile(curIccPrimaries, gammaCurve, curIccWhitePoint);
+
+ // link profiles
+ // TODO: intent selection, switch output to 16 bits?
+ cmsSetAdaptationState(0.0);
+#ifdef _DEBUG
+ int64_t start;
+ start = CurrentHostCounter();
+#endif
+ cmsHTRANSFORM deviceLink =
+ cmsCreateTransform(sourceProfile, TYPE_RGB_FLT,
+ m_hProfile, TYPE_RGB_FLT,
+ INTENT_ABSOLUTE_COLORIMETRIC, 0);
+#ifdef _DEBUG
+ int64_t end, freq;
+ end = CurrentHostCounter();
+ freq = CurrentHostFrequency();
+ CLog::Log(LOGDEBUG,"Profile linking: %.2fms", 1000.f * (end - start) / freq);
+#endif
+
+ // sample the transformation
+ *clutSize = 1 << CSettings::GetInstance().GetInt("videoscreen.cmslutsize");
+#ifdef _DEBUG
+ start = CurrentHostCounter();
+#endif
+ Create3dLut(deviceLink, clutData, clutSize);
+#ifdef _DEBUG
+ end = CurrentHostCounter();
+ freq = CurrentHostFrequency();
+ CLog::Log(LOGDEBUG,"Profile sampling: %.2fms", 1000.f * (end - start) / freq);
+#endif
+
+ // free gamma curve, source profile and transformation
+ cmsDeleteTransform(deviceLink);
+ cmsCloseProfile(sourceProfile);
+ cmsFreeToneCurve(gammaCurve);
+ }
+
+ curCmsMode = CMS_MODE_PROFILE;
+ break;
+#else //defined(HAVE_LCMS2)
+ return false;
+#endif //defined(HAVE_LCMS2)
+
+ default:
+ CLog::Log(LOGDEBUG, "ColorManager: unknown CMS mode %d\n", CSettings::GetInstance().GetInt("videoscreen.cmsmode"));
+ return false;
+ }
+
+ // set current state
+ curVideoPrimaries = videoPrimaries;
+ curClutSize = *clutSize;
+ *cmsToken = ++curCmsToken;
+ return true;
+}
+
+bool CColorManager::CheckConfiguration(int cmsToken, int flags)
+{
+ if (cmsToken != curCmsToken)
+ return false;
+ if (curCmsMode != CSettings::GetInstance().GetInt("videoscreen.cmsmode"))
+ return false; // CMS mode has changed
+ switch (curCmsMode)
+ {
+ case CMS_MODE_3DLUT:
+ if (cur3dlutFile != CSettings::GetInstance().GetString("videoscreen.cms3dlut"))
+ return false; // different 3dlut file selected
+ break;
+ case CMS_MODE_PROFILE:
+ if (curIccProfile != CSettings::GetInstance().GetString("videoscreen.displayprofile"))
+ return false; // different ICC profile selected
+ if (curIccWhitePoint != CSettings::GetInstance().GetInt("videoscreen.cmswhitepoint"))
+ return false; // whitepoint changed
+ {
+ CMS_PRIMARIES primaries = (CMS_PRIMARIES)CSettings::GetInstance().GetInt("videoscreen.cmsprimaries");
+ if (primaries == CMS_PRIMARIES_AUTO) primaries = videoFlagsToPrimaries(flags);
+ if (curIccPrimaries != primaries)
+ return false; // primaries changed
+ }
+ if (curIccGammaMode != (CMS_TRC_TYPE)CSettings::GetInstance().GetInt("videoscreen.cmsgammamode"))
+ return false; // gamma mode changed
+ if (curIccGamma != CSettings::GetInstance().GetInt("videoscreen.cmsgamma"))
+ return false; // effective gamma changed
+ if (curClutSize != 1 << CSettings::GetInstance().GetInt("videoscreen.cmslutsize"))
+ return false; // CLUT size changed
+ // TODO: check other parameters
+ break;
+ default:
+ CLog::Log(LOGERROR, "%s: unexpected CMS mode: %d", __FUNCTION__, curCmsMode);
+ return false;
+ }
+ return true;
+}
+
+
+
+// madvr 3dlut file format support
+struct H3DLUT
+{
+ char signature[4]; // file signature; must be: '3DLT'
+ uint32_t fileVersion; // file format version number (currently "1")
+ char programName[32]; // name of the program that created the file
+ uint64_t programVersion; // version number of the program that created the file
+ uint32_t inputBitDepth[3]; // input bit depth per component (Y,Cb,Cr or R,G,B)
+ uint32_t inputColorEncoding; // input color encoding standard
+ uint32_t outputBitDepth; // output bit depth for all components (valid values are 8, 16 and 32)
+ uint32_t outputColorEncoding; // output color encoding standard
+ uint32_t parametersFileOffset; // number of bytes between the beginning of the file and array parametersData
+ uint32_t parametersSize; // size in bytes of the array parametersData
+ uint32_t lutFileOffset; // number of bytes between the beginning of the file and array lutData
+ uint32_t lutCompressionMethod; // type of compression used if any (0 = none, ...)
+ uint32_t lutCompressedSize; // size in bytes of the array lutData inside the file, whether compressed or not
+ uint32_t lutUncompressedSize; // true size in bytes of the array lutData when in memory for usage (outside the file)
+ // This header is followed by the char array 'parametersData', of length 'parametersSize',
+ // and by the array 'lutDataxx', of length 'lutCompressedSize'.
+};
+
+bool CColorManager::Probe3dLut(const std::string filename)
+{
+ struct H3DLUT header;
+ CFile lutFile;
+
+ if (!lutFile.Open(filename))
+ {
+ CLog::Log(LOGERROR, "%s: Could not open 3DLUT file: %s", __FUNCTION__, filename.c_str());
+ return false;
+ }
+
+ if (lutFile.Read(&header, sizeof(header)) < sizeof(header))
+ {
+ CLog::Log(LOGERROR, "%s: Could not read 3DLUT header: %s", __FUNCTION__, filename.c_str());
+ return false;
+ }
+
+ if ( !(header.signature[0]=='3'
+ && header.signature[1]=='D'
+ && header.signature[2]=='L'
+ && header.signature[3]=='T') )
+ {
+ CLog::Log(LOGERROR, "%s: Not a 3DLUT file: %s", __FUNCTION__, filename.c_str());
+ return false;
+ }
+
+ if ( header.fileVersion != 1
+ || header.lutCompressionMethod != 0
+ || header.inputColorEncoding != 0
+ || header.outputColorEncoding != 0 )
+ {
+ CLog::Log(LOGERROR, "%s: Unsupported 3DLUT file: %s", __FUNCTION__, filename.c_str());
+ return false;
+ }
+
+ lutFile.Close();
+ return true;
+}
+
+bool CColorManager::Load3dLut(const std::string filename, uint16_t **CLUT, int *CLUTsize)
+{
+ struct H3DLUT header;
+ CFile lutFile;
+
+ if (!lutFile.Open(filename))
+ {
+ CLog::Log(LOGERROR, "%s: Could not open 3DLUT file: %s", __FUNCTION__, filename.c_str());
+ return false;
+ }
+
+ if (lutFile.Read(&header, sizeof(header)) < sizeof(header))
+ {
+ CLog::Log(LOGERROR, "%s: Could not read 3DLUT header: %s", __FUNCTION__, filename.c_str());
+ return false;
+ }
+
+ int rSize = 1 << header.inputBitDepth[0];
+ int gSize = 1 << header.inputBitDepth[1];
+ int bSize = 1 << header.inputBitDepth[2];
+
+ if ( !((rSize == gSize) && (rSize == bSize)) )
+ {
+ CLog::Log(LOGERROR, "%s: Different channel resolutions unsupported: %s", __FUNCTION__, filename.c_str());
+ return false;
+ }
+
+ int lutsamples = rSize * gSize * bSize * 3;
+ *CLUTsize = rSize; // TODO: assumes cube
+ *CLUT = (uint16_t*)malloc(lutsamples * sizeof(uint16_t));
+
+ lutFile.Seek(header.lutFileOffset, SEEK_SET);
+
+ for (int rIndex=0; rIndex<rSize; rIndex++) {
+ for (int gIndex=0; gIndex<gSize; gIndex++) {
+ uint16_t input[bSize*3];
+ lutFile.Read(input, 3*bSize*sizeof(uint16_t));
+ int index = (rIndex + gIndex*rSize)*3;
+ for (int bIndex=0; bIndex<bSize; bIndex++) {
+ (*CLUT)[index+bIndex*rSize*gSize*3+0] = input[bIndex*3+2];
+ (*CLUT)[index+bIndex*rSize*gSize*3+1] = input[bIndex*3+1];
+ (*CLUT)[index+bIndex*rSize*gSize*3+2] = input[bIndex*3+0];
+ }
+ }
+ }
+
+ lutFile.Close();
+
+#ifdef _DEBUG // debug 3dLUT greyscale
+ for (int y=0; y<rSize; y+=1)
+ {
+ int index = 3*(y*rSize*rSize + y*rSize + y);
+ CLog::Log(LOGDEBUG, " %d (%d): %d %d %d\n",
+ (int)round(y * 255 / (rSize-1.0)), y,
+ (int)round((*CLUT)[index+0]/256),
+ (int)round((*CLUT)[index+1]/256),
+ (int)round((*CLUT)[index+2]/256));
+ }
+#endif
+
+ return true;
+}
+
+
+
+#if defined(HAVE_LCMS2)
+// ICC profile support
+
+cmsHPROFILE CColorManager::LoadIccDisplayProfile(const std::string filename)
+{
+ cmsHPROFILE hProfile;
+
+ hProfile = cmsOpenProfileFromFile(filename.c_str(), "r");
+ if (!hProfile)
+ {
+ CLog::Log(LOGERROR, "ICC profile not found\n");
+ }
+ return hProfile;
+}
+
+
+cmsToneCurve* CColorManager::CreateToneCurve(CMS_TRC_TYPE gammaType, float gammaValue, cmsCIEXYZ blackPoint)
+{
+ const int tableSize = 1024;
+ cmsFloat32Number gammaTable[tableSize];
+
+ switch (gammaType)
+ {
+ case CMS_TRC_INPUT_OFFSET:
+ // calculate gamma to match effective gamma provided, then fall through to bt.1886
+ {
+ double effectiveGamma = gammaValue;
+ double gammaLow = effectiveGamma; // low limit for infinite contrast ratio
+ double gammaHigh = 3.2; // high limit for 2.4 gamma on 200:1 contrast ratio
+ double gammaGuess = 0.0;
+#define TARGET(gamma) (pow(0.5, (gamma)))
+#define GAIN(bkpt, gamma) (pow(1-pow((bkpt), 1/(gamma)), (gamma)))
+#define LIFT(bkpt, gamma) (pow((bkpt), 1/(gamma)) / (1-pow((bkpt), 1/(gamma))))
+#define HALFPT(bkpt, gamma) (GAIN(bkpt, gamma)*pow(0.5+LIFT(bkpt, gamma), gamma))
+ for (int i=0; i<3; i++)
+ {
+ // calculate 50% output for gammaLow and gammaHigh, compare to target 50% output
+ gammaGuess = gammaLow + (gammaHigh-gammaLow)
+ * ((HALFPT(blackPoint.Y, gammaLow)-TARGET(effectiveGamma))
+ / (HALFPT(blackPoint.Y, gammaLow)-HALFPT(blackPoint.Y, gammaHigh)));
+ if (HALFPT(blackPoint.Y, gammaGuess) < TARGET(effectiveGamma))
+ {
+ // guess is too high
+ // move low limit half way to guess
+ gammaLow = gammaLow + (gammaGuess-gammaLow)/2;
+ // set high limit to guess
+ gammaHigh = gammaGuess;
+ }
+ else
+ {
+ // guess is too low
+ // set low limit to guess
+ gammaLow = gammaGuess;
+ // move high limit half way to guess
+ gammaHigh = gammaHigh + (gammaGuess-gammaLow)/2;
+ }
+ }
+ gammaValue = gammaGuess;
+ CLog::Log(LOGINFO, "calculated technical gamma %0.3f (50%% target %0.4f, output %0.4f)\n",
+ gammaValue,
+ TARGET(effectiveGamma),
+ HALFPT(blackPoint.Y, gammaValue));
+#undef TARGET
+#undef GAIN
+#undef LIFT
+#undef HALFPT
+ }
+ // fall through to bt.1886 with calculated technical gamma
+
+ case CMS_TRC_BT1886:
+ {
+ double bkipow = pow(blackPoint.Y, 1.0/gammaValue);
+ double wtipow = 1.0;
+ double lift = bkipow / (wtipow - bkipow);
+ double gain = pow(wtipow - bkipow, gammaValue);
+ for (int i=0; i<tableSize; i++)
+ {
+ gammaTable[i] = gain * pow(((double) i)/(tableSize-1) + lift, gammaValue);
+ }
+ }
+ break;
+
+ case CMS_TRC_OUTPUT_OFFSET:
+ {
+ double gain = 1-blackPoint.Y;
+ // TODO: here gamma is adjusted to match absolute gamma output at 50%
+ // - is it a good idea or should the provided gamma be kept?
+ double adjustedGamma = log(gain/(gain+pow(2,-gammaValue)-1))/log(2);
+ for (int i=0; i<tableSize; i++)
+ {
+ gammaTable[i] = gain * pow(((double) i)/(tableSize-1), adjustedGamma) + blackPoint.Y;
+ }
+ }
+ break;
+
+ case CMS_TRC_ABSOLUTE:
+ {
+ for (int i=0; i<tableSize; i++)
+ {
+ gammaTable[i] = fmax(blackPoint.Y, pow(((double) i)/(tableSize-1), gammaValue));
+ }
+ }
+ break;
+
+ default:
+ CLog::Log(LOGERROR, "gamma type %d not implemented\n", gammaType);
+ }
+
+ cmsToneCurve* result = cmsBuildTabulatedToneCurveFloat(0,
+ tableSize,
+ gammaTable);
+ return result;
+}
+
+
+cmsHPROFILE CColorManager::CreateSourceProfile(CMS_PRIMARIES primaries, cmsToneCurve *gamma, CMS_WHITEPOINT whitepoint)
+{
+ cmsToneCurve* Gamma3[3];
+ cmsHPROFILE hProfile;
+ cmsCIExyY whiteCoords[] = {
+ { 0.3127, 0.3290, 1.0 }, // D65 as specified in BT.709
+ { 0.2830, 0.2980, 1.0 } // Japanese D93 - is there a definitive source? NHK? ARIB TR-B9?
+ };
+ cmsCIExyYTRIPLE primaryCoords[] = {
+ { 0.640, 0.330, 1.0, // auto setting, these should not be used (BT.709 just in case)
+ 0.300, 0.600, 1.0,
+ 0.150, 0.060, 1.0 },
+ { 0.640, 0.330, 1.0, // BT.709 (HDTV, sRGB)
+ 0.300, 0.600, 1.0,
+ 0.150, 0.060, 1.0 },
+ { 0.630, 0.340, 1.0, // SMPTE 170M (SDTV)
+ 0.310, 0.595, 1.0,
+ 0.155, 0.070, 1.0 },
+ { 0.670, 0.330, 1.0, // BT.470 M (obsolete NTSC 1953)
+ 0.210, 0.710, 1.0,
+ 0.140, 0.080, 1.0 },
+ { 0.640, 0.330, 1.0, // BT.470 B/G (obsolete PAL/SECAM 1975)
+ 0.290, 0.600, 1.0,
+ 0.150, 0.060, 1.0 },
+ { 0.630, 0.340, 1.0, // SMPTE 240M (obsolete HDTV 1988)
+ 0.310, 0.595, 1.0,
+ 0.155, 0.070, 1.0 }
+ };
+
+ Gamma3[0] = Gamma3[1] = Gamma3[2] = gamma;
+ hProfile = cmsCreateRGBProfile(&whiteCoords[whitepoint],
+ &primaryCoords[primaries],
+ Gamma3);
+ return hProfile;
+}
+
+
+bool CColorManager::Create3dLut(cmsHTRANSFORM transform, uint16_t **clutData, int *clutSize)
+{
+ const int lutResolution = *clutSize;
+ int lutsamples = lutResolution * lutResolution * lutResolution * 3;
+ *clutData = (uint16_t*)malloc(lutsamples * sizeof(uint16_t));
+
+ cmsFloat32Number input[3*lutResolution];
+ cmsFloat32Number output[3*lutResolution];
+
+#define clamp(x, l, h) ( ((x) < (l)) ? (l) : ( ((x) > (h)) ? (h) : (x) ) )
+#define videoToPC(x) ( clamp((((x)*255)-16)/219,0,1) )
+#define PCToVideo(x) ( (((x)*219)+16)/255 )
+// #define videoToPC(x) ( x )
+// #define PCToVideo(x) ( x )
+ for (int bIndex=0; bIndex<lutResolution; bIndex++) {
+ for (int gIndex=0; gIndex<lutResolution; gIndex++) {
+ for (int rIndex=0; rIndex<lutResolution; rIndex++) {
+ input[rIndex*3+0] = videoToPC(rIndex / (lutResolution-1.0));
+ input[rIndex*3+1] = videoToPC(gIndex / (lutResolution-1.0));
+ input[rIndex*3+2] = videoToPC(bIndex / (lutResolution-1.0));
+ }
+ int index = (bIndex*lutResolution*lutResolution + gIndex*lutResolution)*3;
+ cmsDoTransform(transform, input, output, lutResolution);
+ for (int i=0; i<lutResolution*3; i++) {
+ (*clutData)[index+i] = PCToVideo(output[i]) * 65535;
+ }
+ }
+ }
+
+#ifdef _DEBUG // debug 3dLUT greyscale
+/* RGB stripes to verify near black resolution
+ (*clutData)[3*(0*lutResolution*lutResolution + 0*lutResolution + 0)] = 65535;
+ (*clutData)[3*(0*lutResolution*lutResolution + 0*lutResolution + 0)+1] = 0;
+ (*clutData)[3*(0*lutResolution*lutResolution + 0*lutResolution + 0)+2] = 0;
+ (*clutData)[3*(1*lutResolution*lutResolution + 1*lutResolution + 1)] = 0;
+ (*clutData)[3*(1*lutResolution*lutResolution + 1*lutResolution + 1)+1] = 65535;
+ (*clutData)[3*(1*lutResolution*lutResolution + 1*lutResolution + 1)+2] = 0;
+ (*clutData)[3*(2*lutResolution*lutResolution + 2*lutResolution + 2)] = 0;
+ (*clutData)[3*(2*lutResolution*lutResolution + 2*lutResolution + 2)+1] = 0;
+ (*clutData)[3*(2*lutResolution*lutResolution + 2*lutResolution + 2)+2] = 65535;
+*/
+ for (int y=0; y<lutResolution; y+=1)
+ {
+ int index = 3*(y*lutResolution*lutResolution + y*lutResolution + y);
+ CLog::Log(LOGDEBUG, " %d (%d): %d %d %d\n",
+ (int)round(y * 255 / (lutResolution-1.0)), y,
+ (int)round((*clutData)[index+0]),
+ (int)round((*clutData)[index+1]),
+ (int)round((*clutData)[index+2]));
+ }
+#endif
+
+}
+
+
+#endif //defined(HAVE_LCMS2)
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.h b/xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.h
new file mode 100644
index 0000000000..2c98a699f4
--- /dev/null
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/ColorManager.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2016 Lauri Mylläri
+ * http://kodi.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#if defined(HAVE_LCMS2)
+#include "lcms2.h"
+#endif
+
+#include <string>
+
+enum CMS_MODE
+{
+ CMS_MODE_3DLUT,
+ CMS_MODE_PROFILE,
+ CMS_MODE_COUNT
+};
+
+enum CMS_WHITEPOINT
+{
+ CMS_WHITEPOINT_D65,
+ CMS_WHITEPOINT_D93,
+ CMS_WHITEPOINT_COUNT
+};
+
+enum CMS_PRIMARIES
+{
+ CMS_PRIMARIES_AUTO,
+ CMS_PRIMARIES_BT709, // HDTV
+ CMS_PRIMARIES_170M, // SDTV
+ CMS_PRIMARIES_BT470M, // old NTSC (1953)
+ CMS_PRIMARIES_BT470BG, // old PAL/SECAM (1975)
+ CMS_PRIMARIES_240M, // old HDTV (1988)
+ CMS_PRIMARIES_COUNT
+};
+
+enum CMS_TRC_TYPE
+{
+ CMS_TRC_BT1886,
+ CMS_TRC_INPUT_OFFSET,
+ CMS_TRC_OUTPUT_OFFSET,
+ CMS_TRC_ABSOLUTE,
+ CMS_TRC_COUNT
+};
+
+class CColorManager
+{
+public:
+ /*!
+ \brief Access the global color management system
+ \return the global instance
+ */
+ static CColorManager& Get();
+
+ /*!
+ \brief Check if user has requested color management
+ \return true on enabled, false otherwise
+ */
+ bool IsEnabled();
+
+ /*!
+ \brief Get a 3D LUT for video color correction
+ \param primaries video primaries (see CONF_FLAGS_COLPRI)
+ \param cmsToken pointer to a color manager configuration token
+ \param clutSize pointer to CLUT resolution
+ \param clutData pointer to CLUT data (caller to free memory afterwards)
+ \return true on success, false otherwise
+ */
+ bool GetVideo3dLut(int primaries, int *cmsToken, int *clutSize, uint16_t **clutData);
+
+ /*!
+ \brief Check if a 3D LUT is still valid
+ \param cmsToken pointer to a color manager configuration token
+ \param flags video renderer flags (see CONF_FLAGS_COLPRI)
+ \return true on valid, false if 3D LUT should be reloaded
+ */
+ bool CheckConfiguration(int cmsToken, int flags);
+
+private:
+ // private constructor, use the Get() method to access an instance
+ CColorManager();
+ virtual ~CColorManager();
+
+ /*! \brief Check .3dlut file validity
+ \param filename full path and filename
+ \return true if the file can be loaded, false otherwise
+ */
+ bool Probe3dLut(const std::string filename);
+
+ /*! \brief Load a .3dlut file
+ \param filename full path and filename
+ \param clutSize pointer to CLUT resolution
+ \param clutData pointer to CLUT data
+ \return true on success, false otherwise
+ */
+ bool Load3dLut(const std::string filename, uint16_t **clutData, int *clutSize);
+
+
+#ifdef HAVE_LCMS2
+ // ProbeIccDisplayProfile
+
+ // ProbeIccDeviceLink (?)
+
+
+ /* \brief Load an ICC display profile
+ \param filename full path and filename
+ \return display profile (cmsHPROFILE)
+ */
+ cmsHPROFILE LoadIccDisplayProfile(const std::string filename);
+
+ /* \brief Load an ICC device link
+ \param filename full path and filename
+ \return device link (cmsHTRANSFORM)
+ */
+ // LoadIccDeviceLink (?)
+
+
+ // create a gamma curve
+ cmsToneCurve* CreateToneCurve(CMS_TRC_TYPE gammaType, float gammaValue, cmsCIEXYZ blackPoint);
+
+ // create a source profile
+ cmsHPROFILE CreateSourceProfile(CMS_PRIMARIES primaries, cmsToneCurve *gamma, CMS_WHITEPOINT whitepoint);
+
+
+ /* \brief Create 3D LUT
+ Samples a cmsHTRANSFORM object to create a 3D LUT of specified resolution
+ \param transform cmsHTRANSFORM object to sample
+ \param resolution size of the 3D LUT to create
+ \param clut pointer to LUT data
+ */
+ bool Create3dLut(cmsHTRANSFORM transform, uint16_t **clutData, int *clutSize);
+
+ // keep current display profile loaded here
+ cmsHPROFILE m_hProfile;
+ cmsCIEXYZ m_blackPoint = { 0, 0, 0 };
+
+#endif // HAVE_LCMS2
+
+ // current configuration:
+ CMS_PRIMARIES curVideoPrimaries;
+ int curClutSize;
+ int curCmsToken;
+ // (compare the following to system settings to see if configuration is still valid)
+ int curCmsMode;
+ std::string cur3dlutFile;
+ std::string curIccProfile;
+ // display parameters (gamma, input/output offset, primaries, whitepoint, intent?)
+ CMS_WHITEPOINT curIccWhitePoint;
+ CMS_PRIMARIES curIccPrimaries;
+ CMS_TRC_TYPE curIccGammaMode;
+ int curIccGamma; // gamma multiplied by 100
+
+
+};
+
+
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/Makefile.in b/xbmc/cores/VideoPlayer/VideoRenderers/Makefile.in
index c02e4172a4..83547f6cf5 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/Makefile.in
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/Makefile.in
@@ -1,4 +1,5 @@
SRCS = BaseRenderer.cpp
+SRCS += ColorManager.cpp
SRCS += OverlayRenderer.cpp
SRCS += OverlayRendererUtil.cpp
SRCS += OverlayRendererGUI.cpp
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/RenderFlags.h b/xbmc/cores/VideoPlayer/VideoRenderers/RenderFlags.h
index f65d4b2bcf..ac0dfe17e0 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/RenderFlags.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/RenderFlags.h
@@ -52,11 +52,11 @@
/* defines color primaries */
#define CONF_FLAGS_COLPRI_MASK(a) ((a) & 0xe0)
-#define CONF_FLAGS_COLPRI_BT709 0x20
-#define CONF_FLAGS_COLPRI_BT470M 0x40
-#define CONF_FLAGS_COLPRI_BT470BG 0x60
-#define CONF_FLAGS_COLPRI_170M 0x80
-#define CONF_FLAGS_COLPRI_240M 0xa0
+#define CONF_FLAGS_COLPRI_BT709 0x20 // sRGB, HDTV (ITU-R BT.709)
+#define CONF_FLAGS_COLPRI_BT470M 0x40 // NTSC (1953) (FCC 1953, ITU-R BT.470 System M)
+#define CONF_FLAGS_COLPRI_BT470BG 0x60 // PAL/SECAM (1970) (EBU Tech. 3213, ITU-R BT.470 System B, G)
+#define CONF_FLAGS_COLPRI_170M 0x80 // NTSC (1987) (SMPTE RP 145 "SMPTE C", SMPTE 170M)
+#define CONF_FLAGS_COLPRI_240M 0xa0 // SMPTE-240M
/* defines chroma subsampling sample location */
#define CONF_FLAGS_CHROMA_MASK(a) ((a) & 0x0300)
diff --git a/xbmc/guilib/GUIWindowManager.cpp b/xbmc/guilib/GUIWindowManager.cpp
index 0a952e3484..bcaf3ed4b4 100644
--- a/xbmc/guilib/GUIWindowManager.cpp
+++ b/xbmc/guilib/GUIWindowManager.cpp
@@ -79,6 +79,7 @@
#include "dialogs/GUIDialogTextViewer.h"
#include "network/GUIDialogNetworkSetup.h"
#include "dialogs/GUIDialogMediaSource.h"
+#include "video/dialogs/GUIDialogCMSSettings.h"
#include "video/dialogs/GUIDialogVideoSettings.h"
#include "video/dialogs/GUIDialogAudioSubtitleSettings.h"
#include "video/dialogs/GUIDialogVideoBookmarks.h"
@@ -213,6 +214,7 @@ void CGUIWindowManager::CreateWindows()
Add(new CGUIDialogSlider);
Add(new CGUIDialogMusicOSD);
Add(new CGUIDialogVisualisationPresetList);
+ Add(new CGUIDialogCMSSettings);
Add(new CGUIDialogVideoSettings);
Add(new CGUIDialogAudioSubtitleSettings);
Add(new CGUIDialogVideoBookmarks);
@@ -326,6 +328,7 @@ bool CGUIWindowManager::DestroyWindows()
Delete(WINDOW_DIALOG_LOCK_SETTINGS);
Delete(WINDOW_DIALOG_NETWORK_SETUP);
Delete(WINDOW_DIALOG_MEDIA_SOURCE);
+ Delete(WINDOW_DIALOG_CMS_OSD_SETTINGS);
Delete(WINDOW_DIALOG_VIDEO_OSD_SETTINGS);
Delete(WINDOW_DIALOG_AUDIO_OSD_SETTINGS);
Delete(WINDOW_DIALOG_VIDEO_BOOKMARKS);
diff --git a/xbmc/guilib/WindowIDs.h b/xbmc/guilib/WindowIDs.h
index fcfcc5ddec..b5ab401b10 100644
--- a/xbmc/guilib/WindowIDs.h
+++ b/xbmc/guilib/WindowIDs.h
@@ -100,6 +100,7 @@
#define WINDOW_DIALOG_AUDIO_DSP_MANAGER 10154
#define WINDOW_DIALOG_AUDIO_DSP_OSD_SETTINGS 10155
#define WINDOW_DIALOG_KEYBOARD_TOUCH 10156
+#define WINDOW_DIALOG_CMS_OSD_SETTINGS 10157
#define WINDOW_MUSIC_PLAYLIST 10500
#define WINDOW_MUSIC_NAV 10502
diff --git a/xbmc/input/ButtonTranslator.cpp b/xbmc/input/ButtonTranslator.cpp
index 7398fbf95e..b877126a44 100644
--- a/xbmc/input/ButtonTranslator.cpp
+++ b/xbmc/input/ButtonTranslator.cpp
@@ -353,6 +353,7 @@ static const ActionMapping windows[] =
{ "musicosd" , WINDOW_DIALOG_MUSIC_OSD },
{ "addonsettings" , WINDOW_DIALOG_ADDON_SETTINGS },
{ "visualisationpresetlist" , WINDOW_DIALOG_VIS_PRESET_LIST },
+ { "osdcmssettings" , WINDOW_DIALOG_CMS_OSD_SETTINGS },
{ "osdvideosettings" , WINDOW_DIALOG_VIDEO_OSD_SETTINGS },
{ "osdaudiosettings" , WINDOW_DIALOG_AUDIO_OSD_SETTINGS },
{ "audiodspmanager" , WINDOW_DIALOG_AUDIO_DSP_MANAGER },
diff --git a/xbmc/settings/DisplaySettings.cpp b/xbmc/settings/DisplaySettings.cpp
index 363757d131..f29e3ec3f7 100644
--- a/xbmc/settings/DisplaySettings.cpp
+++ b/xbmc/settings/DisplaySettings.cpp
@@ -27,6 +27,8 @@
#include <utility>
#include <vector>
+#include "cores/VideoPlayer/VideoRenderers/ColorManager.h"
+#include "dialogs/GUIDialogFileBrowser.h"
#include "guilib/GraphicContext.h"
#include "guilib/gui3d.h"
#include "guilib/LocalizeStrings.h"
@@ -36,6 +38,7 @@
#include "settings/AdvancedSettings.h"
#include "settings/lib/Setting.h"
#include "settings/Settings.h"
+#include "storage/MediaManager.h"
#include "threads/SingleLock.h"
#include "utils/log.h"
#include "utils/StringUtils.h"
@@ -221,6 +224,34 @@ void CDisplaySettings::Clear()
m_nonLinearStretched = false;
}
+void CDisplaySettings::OnSettingAction(const CSetting *setting)
+{
+ if (setting == NULL)
+ return;
+
+ const std::string &settingId = setting->GetId();
+ if (settingId == "videoscreen.cms3dlut")
+ {
+ std::string path = ((CSettingString*)setting)->GetValue();
+ VECSOURCES shares;
+ g_mediaManager.GetLocalDrives(shares);
+ if (CGUIDialogFileBrowser::ShowAndGetFile(shares, ".3dlut", g_localizeStrings.Get(36580), path))
+ {
+ ((CSettingString*)setting)->SetValue(path);
+ }
+ }
+ else if (settingId == "videoscreen.displayprofile")
+ {
+ std::string path = ((CSettingString*)setting)->GetValue();
+ VECSOURCES shares;
+ g_mediaManager.GetLocalDrives(shares);
+ if (CGUIDialogFileBrowser::ShowAndGetFile(shares, ".icc|.icm", g_localizeStrings.Get(36581), path))
+ {
+ ((CSettingString*)setting)->SetValue(path);
+ }
+ }
+}
+
bool CDisplaySettings::OnSettingChanging(const CSetting *setting)
{
if (setting == NULL)
@@ -767,3 +798,59 @@ void CDisplaySettings::ClearCustomResolutions()
m_resolutions.erase(firstCustom, m_resolutions.end());
}
}
+
+void CDisplaySettings::SettingOptionsCmsModesFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current, void *data)
+{
+ const static std::string cmsModeLabels[] = { "3DLUT", "ICC profile" }; // FIXME: should be moved to ColorManager.h?
+ for (int i = 0; i < CMS_MODE_COUNT; i++)
+ {
+ CMS_MODE mode = (CMS_MODE) i;
+#ifndef HAVE_LCMS2
+ if (mode == CMS_MODE_PROFILE) continue;
+#endif
+ list.push_back(std::make_pair(cmsModeLabels[i], mode));
+ }
+}
+
+void CDisplaySettings::SettingOptionsCmsWhitepointsFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current, void *data)
+{
+ const static std::string cmsWhitepointLabels[] = { "D65", "D93" }; // FIXME: should be moved to ColorManager.h?
+ for (int i = 0; i < CMS_WHITEPOINT_COUNT; i++)
+ {
+ CMS_WHITEPOINT whitepoint = (CMS_WHITEPOINT) i;
+ list.push_back(std::make_pair(cmsWhitepointLabels[i], whitepoint));
+ }
+}
+
+void CDisplaySettings::SettingOptionsCmsPrimariesFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current, void *data)
+{
+ const static std::string cmsPrimariesLabels[] = {
+ "Automatic",
+ "HDTV",
+ "SDTV",
+ "NTSC 1953",
+ "PAL/SECAM 1975",
+ "HDTV 1988",
+ }; // FIXME: should be moved to ColorManager.h?
+ for (int i = 0; i < CMS_PRIMARIES_COUNT; i++)
+ {
+ CMS_PRIMARIES primaries = (CMS_PRIMARIES) i;
+ list.push_back(std::make_pair(cmsPrimariesLabels[i], primaries));
+ }
+}
+
+void CDisplaySettings::SettingOptionsCmsGammaModesFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current, void *data)
+{
+ const static std::string cmsGammaModeLabels[] = {
+ "BT.1886",
+ "Input offset",
+ "Output offset",
+ "Absolute",
+ }; // FIXME: should be moved to ColorManager.h?
+ for (int i = 0; i < CMS_TRC_COUNT; i++)
+ {
+ CMS_TRC_TYPE mode = (CMS_TRC_TYPE) i;
+ list.push_back(std::make_pair(cmsGammaModeLabels[i], mode));
+ }
+}
+
diff --git a/xbmc/settings/DisplaySettings.h b/xbmc/settings/DisplaySettings.h
index 729bd94386..cd0773b96e 100644
--- a/xbmc/settings/DisplaySettings.h
+++ b/xbmc/settings/DisplaySettings.h
@@ -42,6 +42,7 @@ public:
virtual bool Save(TiXmlNode *settings) const override;
virtual void Clear() override;
+ virtual void OnSettingAction(const CSetting *setting);
virtual bool OnSettingChanging(const CSetting *setting) override;
virtual bool OnSettingUpdate(CSetting* &setting, const char *oldSettingId, const TiXmlNode *oldSettingNode) override;
@@ -97,6 +98,11 @@ public:
static void SettingOptionsStereoscopicModesFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current, void *data);
static void SettingOptionsPreferredStereoscopicViewModesFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current, void *data);
static void SettingOptionsMonitorsFiller(const CSetting *setting, std::vector< std::pair<std::string, std::string> > &list, std::string &current, void *data);
+ static void SettingOptionsCmsModesFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current, void *data);
+ static void SettingOptionsCmsWhitepointsFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current, void *data);
+ static void SettingOptionsCmsPrimariesFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current, void *data);
+ static void SettingOptionsCmsGammaModesFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int &current, void *data);
+
protected:
CDisplaySettings();
diff --git a/xbmc/settings/SettingConditions.cpp b/xbmc/settings/SettingConditions.cpp
index fede2136eb..7870ce0807 100644
--- a/xbmc/settings/SettingConditions.cpp
+++ b/xbmc/settings/SettingConditions.cpp
@@ -326,6 +326,9 @@ void CSettingConditions::Initialize()
m_simpleConditions.insert("has_dx");
m_simpleConditions.insert("hasdxva2");
#endif
+#ifdef HAVE_LCMS2
+ m_simpleConditions.insert("have_lcms2");
+#endif
if (g_application.IsStandAlone())
m_simpleConditions.insert("isstandalone");
diff --git a/xbmc/settings/Settings.cpp b/xbmc/settings/Settings.cpp
index 1d9e02bbbb..1e877cd6e3 100644
--- a/xbmc/settings/Settings.cpp
+++ b/xbmc/settings/Settings.cpp
@@ -341,6 +341,8 @@ const std::string CSettings::SETTING_VIDEOSCREEN_BLANKDISPLAYS = "videoscreen.bl
const std::string CSettings::SETTING_VIDEOSCREEN_STEREOSCOPICMODE = "videoscreen.stereoscopicmode";
const std::string CSettings::SETTING_VIDEOSCREEN_PREFEREDSTEREOSCOPICMODE = "videoscreen.preferedstereoscopicmode";
const std::string CSettings::SETTING_VIDEOSCREEN_NOOFBUFFERS = "videoscreen.noofbuffers";
+const std::string CSettings::SETTING_VIDEOSCREEN_3DLUT = "videoscreen.cms3dlut";
+const std::string CSettings::SETTING_VIDEOSCREEN_DISPLAYPROFILE = "videoscreen.displayprofile";
const std::string CSettings::SETTING_VIDEOSCREEN_GUICALIBRATION = "videoscreen.guicalibration";
const std::string CSettings::SETTING_VIDEOSCREEN_TESTPATTERN = "videoscreen.testpattern";
const std::string CSettings::SETTING_VIDEOSCREEN_LIMITEDRANGE = "videoscreen.limitedrange";
@@ -575,6 +577,10 @@ void CSettings::Uninitialize()
m_settingsManager->UnregisterSettingOptionsFiller("stereoscopicmodes");
m_settingsManager->UnregisterSettingOptionsFiller("preferedstereoscopicviewmodes");
m_settingsManager->UnregisterSettingOptionsFiller("monitors");
+ m_settingsManager->UnregisterSettingOptionsFiller("cmsmodes");
+ m_settingsManager->UnregisterSettingOptionsFiller("cmswhitepoints");
+ m_settingsManager->UnregisterSettingOptionsFiller("cmsprimaries");
+ m_settingsManager->UnregisterSettingOptionsFiller("cmsgammamodes");
m_settingsManager->UnregisterSettingOptionsFiller("videoseeksteps");
m_settingsManager->UnregisterSettingOptionsFiller("shutdownstates");
m_settingsManager->UnregisterSettingOptionsFiller("startupwindows");
@@ -931,6 +937,10 @@ void CSettings::InitializeOptionFillers()
m_settingsManager->RegisterSettingOptionsFiller("stereoscopicmodes", CDisplaySettings::SettingOptionsStereoscopicModesFiller);
m_settingsManager->RegisterSettingOptionsFiller("preferedstereoscopicviewmodes", CDisplaySettings::SettingOptionsPreferredStereoscopicViewModesFiller);
m_settingsManager->RegisterSettingOptionsFiller("monitors", CDisplaySettings::SettingOptionsMonitorsFiller);
+ m_settingsManager->RegisterSettingOptionsFiller("cmsmodes", CDisplaySettings::SettingOptionsCmsModesFiller);
+ m_settingsManager->RegisterSettingOptionsFiller("cmswhitepoints", CDisplaySettings::SettingOptionsCmsWhitepointsFiller);
+ m_settingsManager->RegisterSettingOptionsFiller("cmsprimaries", CDisplaySettings::SettingOptionsCmsPrimariesFiller);
+ m_settingsManager->RegisterSettingOptionsFiller("cmsgammamodes", CDisplaySettings::SettingOptionsCmsGammaModesFiller);
m_settingsManager->RegisterSettingOptionsFiller("videoseeksteps", CSeekHandler::SettingOptionsSeekStepsFiller);
m_settingsManager->RegisterSettingOptionsFiller("shutdownstates", CPowerManager::SettingOptionsShutdownStatesFiller);
m_settingsManager->RegisterSettingOptionsFiller("startupwindows", ADDON::CSkinInfo::SettingOptionsStartupWindowsFiller);
@@ -1029,6 +1039,8 @@ void CSettings::InitializeISettingCallbacks()
settingSet.insert(CSettings::SETTING_VIDEOSCREEN_SCREENMODE);
settingSet.insert(CSettings::SETTING_VIDEOSCREEN_MONITOR);
settingSet.insert(CSettings::SETTING_VIDEOSCREEN_PREFEREDSTEREOSCOPICMODE);
+ settingSet.insert(CSettings::SETTING_VIDEOSCREEN_3DLUT);
+ settingSet.insert(CSettings::SETTING_VIDEOSCREEN_DISPLAYPROFILE);
m_settingsManager->RegisterCallback(&CDisplaySettings::GetInstance(), settingSet);
settingSet.clear();
diff --git a/xbmc/settings/Settings.h b/xbmc/settings/Settings.h
index f6d1d425bd..c81b347e59 100644
--- a/xbmc/settings/Settings.h
+++ b/xbmc/settings/Settings.h
@@ -298,6 +298,8 @@ public:
static const std::string SETTING_VIDEOSCREEN_STEREOSCOPICMODE;
static const std::string SETTING_VIDEOSCREEN_PREFEREDSTEREOSCOPICMODE;
static const std::string SETTING_VIDEOSCREEN_NOOFBUFFERS;
+ static const std::string SETTING_VIDEOSCREEN_3DLUT;
+ static const std::string SETTING_VIDEOSCREEN_DISPLAYPROFILE;
static const std::string SETTING_VIDEOSCREEN_GUICALIBRATION;
static const std::string SETTING_VIDEOSCREEN_TESTPATTERN;
static const std::string SETTING_VIDEOSCREEN_LIMITEDRANGE;
diff --git a/xbmc/video/dialogs/CMakeLists.txt b/xbmc/video/dialogs/CMakeLists.txt
index 38d6850581..d0a7df6e24 100644
--- a/xbmc/video/dialogs/CMakeLists.txt
+++ b/xbmc/video/dialogs/CMakeLists.txt
@@ -1,4 +1,5 @@
set(SOURCES GUIDialogAudioSubtitleSettings.cpp
+ GUIDialogCMSSettings.cpp
GUIDialogFullScreenInfo.cpp
GUIDialogSubtitles.cpp
GUIDialogTeletext.cpp
@@ -8,6 +9,7 @@ set(SOURCES GUIDialogAudioSubtitleSettings.cpp
GUIDialogVideoSettings.cpp)
set(HEADERS GUIDialogAudioSubtitleSettings.h
+ GUIDialogCMSSettings.h
GUIDialogFullScreenInfo.h
GUIDialogSubtitles.h
GUIDialogTeletext.h
diff --git a/xbmc/video/dialogs/GUIDialogCMSSettings.cpp b/xbmc/video/dialogs/GUIDialogCMSSettings.cpp
new file mode 100644
index 0000000000..38c7b3c580
--- /dev/null
+++ b/xbmc/video/dialogs/GUIDialogCMSSettings.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2005-2014 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// FIXME: clean up includes
+#include "system.h"
+#include "cores/VideoPlayer/VideoRenderers/ColorManager.h"
+#include "FileItem.h"
+#include "GUIDialogCMSSettings.h"
+#include "GUIPassword.h"
+#include "addons/Skin.h"
+#ifdef HAS_VIDEO_PLAYBACK
+#include "cores/VideoPlayer/VideoRenderers/RenderManager.h"
+#endif
+#include "dialogs/GUIDialogYesNo.h"
+#include "filesystem/Directory.h"
+#include "filesystem/File.h"
+#include "guilib/GUIWindowManager.h"
+#include "profiles/ProfilesManager.h"
+#include "settings/Settings.h"
+#include "settings/lib/Setting.h"
+#include "settings/lib/SettingsManager.h"
+#include "utils/log.h"
+#include "utils/URIUtils.h"
+#include "video/VideoDatabase.h"
+#include "utils/Variant.h"
+
+#include <vector>
+
+#define SETTING_VIDEO_CMSENABLE "videoscreen.cmsenabled"
+#define SETTING_VIDEO_CMSMODE "videoscreen.cmsmode"
+#define SETTING_VIDEO_CMS3DLUT "videoscreen.cms3dlut"
+#define SETTING_VIDEO_CMSWHITEPOINT "videoscreen.cmswhitepoint"
+#define SETTING_VIDEO_CMSPRIMARIES "videoscreen.cmsprimaries"
+#define SETTING_VIDEO_CMSGAMMAMODE "videoscreen.cmsgammamode"
+#define SETTING_VIDEO_CMSGAMMA "videoscreen.cmsgamma"
+#define SETTING_VIDEO_CMSLUTSIZE "videoscreen.cmslutsize"
+
+CGUIDialogCMSSettings::CGUIDialogCMSSettings()
+ : CGUIDialogSettingsManualBase(WINDOW_DIALOG_CMS_OSD_SETTINGS, "DialogSettings.xml")
+{ }
+
+CGUIDialogCMSSettings::~CGUIDialogCMSSettings()
+{ }
+
+void CGUIDialogCMSSettings::SetupView()
+{
+ CGUIDialogSettingsManualBase::SetupView();
+
+ SetHeading(36560);
+ SET_CONTROL_HIDDEN(CONTROL_SETTINGS_OKAY_BUTTON);
+ SET_CONTROL_HIDDEN(CONTROL_SETTINGS_CUSTOM_BUTTON);
+ SET_CONTROL_LABEL(CONTROL_SETTINGS_CANCEL_BUTTON, 15067);
+}
+
+void CGUIDialogCMSSettings::InitializeSettings()
+{
+ CGUIDialogSettingsManualBase::InitializeSettings();
+
+ CSettingCategory *category = AddCategory("cms", -1);
+ if (category == NULL)
+ {
+ CLog::Log(LOGERROR, "CGUIDialogCMSSettings: unable to setup settings");
+ return;
+ }
+
+ // get all necessary setting groups
+ CSettingGroup *groupColorManagement = AddGroup(category);
+ if (groupColorManagement == NULL)
+ {
+ CLog::Log(LOGERROR, "CGUIDialogCMSSettings: unable to setup settings");
+ return;
+ }
+
+ bool usePopup = g_SkinInfo->HasSkinFile("DialogSlider.xml");
+
+ StaticIntegerSettingOptions entries;
+
+ // create "depsCmsEnabled" for settings depending on CMS being enabled
+ CSettingDependency dependencyCmsEnabled(SettingDependencyTypeEnable, m_settingsManager);
+ dependencyCmsEnabled.Or()
+ ->Add(CSettingDependencyConditionPtr(new CSettingDependencyCondition(SETTING_VIDEO_CMSENABLE, "true", SettingDependencyOperatorEquals, false, m_settingsManager)));
+ SettingDependencies depsCmsEnabled;
+ depsCmsEnabled.push_back(dependencyCmsEnabled);
+
+ // create "depsCms3dlut" for 3dlut settings
+ CSettingDependency dependencyCms3dlut(SettingDependencyTypeVisible, m_settingsManager);
+ dependencyCms3dlut.And()
+ ->Add(CSettingDependencyConditionPtr(new CSettingDependencyCondition(SETTING_VIDEO_CMSMODE, std::to_string(CMS_MODE_3DLUT), SettingDependencyOperatorEquals, false, m_settingsManager)));
+ SettingDependencies depsCms3dlut;
+ depsCms3dlut.push_back(dependencyCmsEnabled);
+ depsCms3dlut.push_back(dependencyCms3dlut);
+
+ // create "depsCmsIcc" for display settings with icc profile
+ CSettingDependency dependencyCmsIcc(SettingDependencyTypeVisible, m_settingsManager);
+ dependencyCmsIcc.And()
+ ->Add(CSettingDependencyConditionPtr(new CSettingDependencyCondition(SETTING_VIDEO_CMSMODE, std::to_string(CMS_MODE_PROFILE), SettingDependencyOperatorEquals, false, m_settingsManager)));
+ SettingDependencies depsCmsIcc;
+ depsCmsIcc.push_back(dependencyCmsEnabled);
+ depsCmsIcc.push_back(dependencyCmsIcc);
+
+ // create "depsCmsGamma" for effective gamma adjustment (not available with bt.1886)
+ CSettingDependency dependencyCmsGamma(SettingDependencyTypeVisible, m_settingsManager);
+ dependencyCmsGamma.And()
+ ->Add(CSettingDependencyConditionPtr(new CSettingDependencyCondition(SETTING_VIDEO_CMSGAMMAMODE, std::to_string(CMS_TRC_BT1886), SettingDependencyOperatorEquals, true, m_settingsManager)));
+ SettingDependencies depsCmsGamma;
+ depsCmsGamma.push_back(dependencyCmsEnabled);
+ depsCmsGamma.push_back(dependencyCmsIcc);
+ depsCmsGamma.push_back(dependencyCmsGamma);
+
+ // color management settings
+ AddToggle(groupColorManagement, SETTING_VIDEO_CMSENABLE, 36560, 0, CSettings::GetInstance().GetBool(SETTING_VIDEO_CMSENABLE));
+
+ int currentMode = CSettings::GetInstance().GetInt(SETTING_VIDEO_CMSMODE);
+ entries.clear();
+ // entries.push_back(std::make_pair(16039, CMS_MODE_OFF)); // FIXME: get from CMS class
+ entries.push_back(std::make_pair(36580, CMS_MODE_3DLUT));
+#ifdef HAVE_LCMS2
+ entries.push_back(std::make_pair(36581, CMS_MODE_PROFILE));
+#endif
+ CSettingInt *settingCmsMode = AddSpinner(groupColorManagement, SETTING_VIDEO_CMSMODE, 36562, 0, currentMode, entries);
+ settingCmsMode->SetDependencies(depsCmsEnabled);
+
+ std::string current3dLUT = CSettings::GetInstance().GetString(SETTING_VIDEO_CMS3DLUT);
+ CSettingString *settingCms3dlut = AddList(groupColorManagement, SETTING_VIDEO_CMS3DLUT, 36564, 0, current3dLUT, Cms3dLutsFiller, 36564);
+ settingCms3dlut->SetDependencies(depsCms3dlut);
+
+ // display settings
+ int currentWhitepoint = CSettings::GetInstance().GetInt(SETTING_VIDEO_CMSWHITEPOINT);
+ entries.clear();
+ entries.push_back(std::make_pair(36586, CMS_WHITEPOINT_D65));
+ entries.push_back(std::make_pair(36587, CMS_WHITEPOINT_D93));
+ CSettingInt *settingCmsWhitepoint = AddSpinner(groupColorManagement, SETTING_VIDEO_CMSWHITEPOINT, 36568, 0, currentWhitepoint, entries);
+ settingCmsWhitepoint->SetDependencies(depsCmsIcc);
+
+ int currentPrimaries = CSettings::GetInstance().GetInt(SETTING_VIDEO_CMSPRIMARIES);
+ entries.clear();
+ entries.push_back(std::make_pair(36588, CMS_PRIMARIES_AUTO));
+ entries.push_back(std::make_pair(36589, CMS_PRIMARIES_BT709));
+ entries.push_back(std::make_pair(36590, CMS_PRIMARIES_170M));
+ entries.push_back(std::make_pair(36591, CMS_PRIMARIES_BT470M));
+ entries.push_back(std::make_pair(36592, CMS_PRIMARIES_BT470BG));
+ entries.push_back(std::make_pair(36593, CMS_PRIMARIES_240M));
+ CSettingInt *settingCmsPrimaries = AddSpinner(groupColorManagement, SETTING_VIDEO_CMSPRIMARIES, 36570, 0, currentPrimaries, entries);
+ settingCmsPrimaries->SetDependencies(depsCmsIcc);
+
+ int currentGammaMode = CSettings::GetInstance().GetInt(SETTING_VIDEO_CMSGAMMAMODE);
+ entries.clear();
+ entries.push_back(std::make_pair(36582, CMS_TRC_BT1886));
+ entries.push_back(std::make_pair(36583, CMS_TRC_INPUT_OFFSET));
+ entries.push_back(std::make_pair(36584, CMS_TRC_OUTPUT_OFFSET));
+ entries.push_back(std::make_pair(36585, CMS_TRC_ABSOLUTE));
+ CSettingInt *settingCmsGammaMode = AddSpinner(groupColorManagement, SETTING_VIDEO_CMSGAMMAMODE, 36572, 0, currentGammaMode, entries);
+ settingCmsGammaMode->SetDependencies(depsCmsIcc);
+
+ float currentGamma = CSettings::GetInstance().GetInt(SETTING_VIDEO_CMSGAMMA)/100.0f;
+ if (currentGamma == 0.0) currentGamma = 2.20;
+ CSettingNumber *settingCmsGamma = AddSlider(groupColorManagement, SETTING_VIDEO_CMSGAMMA, 36574, 0, currentGamma, 36597, 1.6, 0.05, 2.8, 36574, usePopup);
+ settingCmsGamma->SetDependencies(depsCmsGamma);
+
+ int currentLutSize = CSettings::GetInstance().GetInt(SETTING_VIDEO_CMSLUTSIZE);
+ entries.clear();
+ entries.push_back(std::make_pair(36594, 4));
+ entries.push_back(std::make_pair(36595, 6));
+ entries.push_back(std::make_pair(36596, 8));
+ CSettingInt *settingCmsLutSize = AddSpinner(groupColorManagement, SETTING_VIDEO_CMSLUTSIZE, 36576, 0, currentLutSize, entries);
+ settingCmsLutSize->SetDependencies(depsCmsIcc);
+}
+
+void CGUIDialogCMSSettings::OnSettingChanged(const CSetting *setting)
+{
+ if (setting == NULL)
+ return;
+
+ CGUIDialogSettingsManualBase::OnSettingChanged(setting);
+
+ const std::string &settingId = setting->GetId();
+ if (settingId == SETTING_VIDEO_CMSENABLE)
+ CSettings::GetInstance().SetBool(SETTING_VIDEO_CMSENABLE, (static_cast<const CSettingBool*>(setting)->GetValue()));
+ else if (settingId == SETTING_VIDEO_CMSMODE)
+ CSettings::GetInstance().SetInt(SETTING_VIDEO_CMSMODE, static_cast<int>(static_cast<const CSettingInt*>(setting)->GetValue()));
+ else if (settingId == SETTING_VIDEO_CMS3DLUT)
+ CSettings::GetInstance().SetString(SETTING_VIDEO_CMS3DLUT, static_cast<std::string>(static_cast<const CSettingString*>(setting)->GetValue()));
+ else if (settingId == SETTING_VIDEO_CMSWHITEPOINT)
+ CSettings::GetInstance().SetInt(SETTING_VIDEO_CMSWHITEPOINT, static_cast<int>(static_cast<const CSettingInt*>(setting)->GetValue()));
+ else if (settingId == SETTING_VIDEO_CMSPRIMARIES)
+ CSettings::GetInstance().SetInt(SETTING_VIDEO_CMSPRIMARIES, static_cast<int>(static_cast<const CSettingInt*>(setting)->GetValue()));
+ else if (settingId == SETTING_VIDEO_CMSGAMMAMODE)
+ CSettings::GetInstance().SetInt(SETTING_VIDEO_CMSGAMMAMODE, static_cast<int>(static_cast<const CSettingInt*>(setting)->GetValue()));
+ else if (settingId == SETTING_VIDEO_CMSGAMMA)
+ CSettings::GetInstance().SetInt(SETTING_VIDEO_CMSGAMMA, static_cast<float>(static_cast<const CSettingNumber*>(setting)->GetValue())*100);
+ else if (settingId == SETTING_VIDEO_CMSLUTSIZE)
+ CSettings::GetInstance().SetInt(SETTING_VIDEO_CMSLUTSIZE, static_cast<int>(static_cast<const CSettingInt*>(setting)->GetValue()));
+}
+
+bool CGUIDialogCMSSettings::OnBack(int actionID)
+{
+ Save();
+ return CGUIDialogSettingsBase::OnBack(actionID);
+}
+
+void CGUIDialogCMSSettings::Save()
+{
+ CLog::Log(LOGINFO, "CGUIDialogCMSSettings: Save() called");
+ CSettings::GetInstance().Save();
+}
+
+void CGUIDialogCMSSettings::Cms3dLutsFiller(
+ const CSetting *setting,
+ std::vector< std::pair<std::string, std::string> > &list,
+ std::string &current,
+ void *data)
+{
+ // get 3dLut directory from settings
+ CFileItemList items;
+
+ // list .3dlut files
+ std::string current3dlut = CSettings::GetInstance().GetString(SETTING_VIDEO_CMS3DLUT);
+ if (!current3dlut.empty())
+ current3dlut = URIUtils::GetDirectory(current3dlut);
+ XFILE::CDirectory::GetDirectory(current3dlut, items, ".3dlut");
+
+ for (int i = 0; i < items.Size(); i++)
+ {
+ list.push_back(make_pair(items[i]->GetLabel(), items[i]->GetPath()));
+ }
+}
diff --git a/xbmc/video/dialogs/GUIDialogCMSSettings.h b/xbmc/video/dialogs/GUIDialogCMSSettings.h
new file mode 100644
index 0000000000..614924076a
--- /dev/null
+++ b/xbmc/video/dialogs/GUIDialogCMSSettings.h
@@ -0,0 +1,52 @@
+#pragma once
+
+/*
+ * Copyright (C) 2005-2014 Team XBMC
+ * http://xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "settings/dialogs/GUIDialogSettingsManualBase.h"
+
+class CGUIDialogCMSSettings : public CGUIDialogSettingsManualBase
+{
+public:
+ CGUIDialogCMSSettings();
+ virtual ~CGUIDialogCMSSettings();
+
+protected:
+ // implementations of ISettingCallback
+ virtual void OnSettingChanged(const CSetting *setting);
+ // virtual void OnSettingAction(const CSetting *setting);
+
+ // specialization of CGUIDialogSettingsBase
+ virtual bool AllowResettingSettings() const { return false; }
+ virtual bool OnBack(int actionID);
+ virtual void Save();
+ virtual void SetupView();
+
+ // specialization of CGUIDialogSettingsManualBase
+ virtual void InitializeSettings();
+
+private:
+ bool m_viewModeChanged;
+ static void Cms3dLutsFiller(
+ const CSetting *setting,
+ std::vector< std::pair<std::string, std::string> > &list,
+ std::string &current,
+ void *data);
+};
diff --git a/xbmc/video/dialogs/GUIDialogVideoOSD.cpp b/xbmc/video/dialogs/GUIDialogVideoOSD.cpp
index c1e99cfc12..e498e1fd47 100644
--- a/xbmc/video/dialogs/GUIDialogVideoOSD.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoOSD.cpp
@@ -46,6 +46,7 @@ void CGUIDialogVideoOSD::FrameMove()
|| g_windowManager.IsWindowActive(WINDOW_DIALOG_AUDIO_OSD_SETTINGS)
|| g_windowManager.IsWindowActive(WINDOW_DIALOG_AUDIO_DSP_OSD_SETTINGS)
|| g_windowManager.IsWindowActive(WINDOW_DIALOG_VIDEO_OSD_SETTINGS)
+ || g_windowManager.IsWindowActive(WINDOW_DIALOG_CMS_OSD_SETTINGS)
|| g_windowManager.IsWindowActive(WINDOW_DIALOG_VIDEO_BOOKMARKS)
|| g_windowManager.IsWindowActive(WINDOW_DIALOG_PVR_OSD_CHANNELS)
|| g_windowManager.IsWindowActive(WINDOW_DIALOG_PVR_OSD_GUIDE)
diff --git a/xbmc/video/dialogs/Makefile b/xbmc/video/dialogs/Makefile
index 0480a6d859..fd27b660ec 100644
--- a/xbmc/video/dialogs/Makefile
+++ b/xbmc/video/dialogs/Makefile
@@ -1,4 +1,5 @@
SRCS=GUIDialogAudioSubtitleSettings.cpp \
+ GUIDialogCMSSettings.cpp \
GUIDialogFullScreenInfo.cpp \
GUIDialogSubtitles.cpp \
GUIDialogTeletext.cpp \