aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/modules/FindLibDisplayInfo.cmake36
-rw-r--r--cmake/platform/linux/gbm.cmake2
-rw-r--r--tools/depends/target/Makefile5
-rw-r--r--tools/depends/target/hwdata/Makefile28
-rw-r--r--tools/depends/target/libdisplay-info/Makefile54
-rw-r--r--xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.cpp8
-rw-r--r--xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.h3
-rw-r--r--xbmc/utils/CMakeLists.txt5
-rw-r--r--xbmc/utils/DisplayInfo.cpp165
-rw-r--r--xbmc/utils/DisplayInfo.h64
-rw-r--r--xbmc/windowing/gbm/WinSystemGbm.cpp41
-rw-r--r--xbmc/windowing/gbm/WinSystemGbm.h11
-rw-r--r--xbmc/windowing/gbm/drm/DRMConnector.cpp28
-rw-r--r--xbmc/windowing/gbm/drm/DRMConnector.h2
14 files changed, 439 insertions, 13 deletions
diff --git a/cmake/modules/FindLibDisplayInfo.cmake b/cmake/modules/FindLibDisplayInfo.cmake
new file mode 100644
index 0000000000..add628d8c7
--- /dev/null
+++ b/cmake/modules/FindLibDisplayInfo.cmake
@@ -0,0 +1,36 @@
+#.rst:
+# FindLibDisplayInfo
+# -------
+# Finds the libdisplay-info library
+#
+# This will define the following variables::
+#
+# LIBDISPLAYINFO_FOUND - system has LIBDISPLAY-INFO
+# LIBDISPLAYINFO_INCLUDE_DIRS - the LIBDISPLAY-INFO include directory
+# LIBDISPLAYINFO_LIBRARIES - the LIBDISPLAY-INFO libraries
+# LIBDISPLAYINFO_DEFINITIONS - the LIBDISPLAY-INFO definitions
+#
+
+if(PKG_CONFIG_FOUND)
+ pkg_check_modules(PC_LIBDISPLAYINFO libdisplay-info QUIET)
+endif()
+
+find_path(LIBDISPLAYINFO_INCLUDE_DIR libdisplay-info/edid.h
+ PATHS ${PC_LIBDISPLAYINFO_INCLUDEDIR})
+
+find_library(LIBDISPLAYINFO_LIBRARY NAMES display-info
+ PATHS ${PC_LIBDISPLAYINFO_LIBDIR})
+
+set(LIBDISPLAYINFO_VERSION ${PC_LIBDISPLAYINFO_VERSION})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LibDisplayInfo
+ REQUIRED_VARS LIBDISPLAYINFO_LIBRARY LIBDISPLAYINFO_INCLUDE_DIR
+ VERSION_VAR LIBDISPLAYINFO_VERSION)
+
+if(LIBDISPLAYINFO_FOUND)
+ set(LIBDISPLAYINFO_LIBRARIES ${LIBDISPLAYINFO_LIBRARY})
+ set(LIBDISPLAYINFO_INCLUDE_DIRS ${LIBDISPLAYINFO_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(LIBDISPLAYINFO_INCLUDE_DIR LIBDISPLAYINFO_LIBRARY)
diff --git a/cmake/platform/linux/gbm.cmake b/cmake/platform/linux/gbm.cmake
index 5e0475a67c..d250326589 100644
--- a/cmake/platform/linux/gbm.cmake
+++ b/cmake/platform/linux/gbm.cmake
@@ -1,4 +1,4 @@
-list(APPEND PLATFORM_REQUIRED_DEPS GBM LibDRM LibInput Xkbcommon UDEV)
+list(APPEND PLATFORM_REQUIRED_DEPS GBM LibDRM LibInput Xkbcommon UDEV LibDisplayInfo)
list(APPEND PLATFORM_OPTIONAL_DEPS VAAPI)
if(APP_RENDER_SYSTEM STREQUAL "gl")
diff --git a/tools/depends/target/Makefile b/tools/depends/target/Makefile
index 656f2c7a75..07619fcc77 100644
--- a/tools/depends/target/Makefile
+++ b/tools/depends/target/Makefile
@@ -136,6 +136,10 @@ ifeq ($(OS),linux)
DEPENDS += wayland waylandpp wayland-protocols webos-wayland-extensions webos-userland
EXCLUDED_DEPENDS += dbus libcec linux-system-x11-libs pipewire mesa
endif
+
+ ifneq (,$(findstring gbm,$(TARGET_PLATFORM)))
+ DEPENDS += hwdata libdisplay-info
+ endif
endif
DEPENDS := $(filter-out $(EXCLUDED_DEPENDS),$(DEPENDS))
@@ -160,6 +164,7 @@ libbluray: fontconfig freetype2 $(ICONV) udfread libxml2
libcdio-gplv3: $(ICONV)
libcdio: $(ICONV)
libcec: p8-platform
+libdisplay-info: meson-cross-file hwdata
libdrm: meson-cross-file
libevdev: libudev
libgcrypt: libgpg-error
diff --git a/tools/depends/target/hwdata/Makefile b/tools/depends/target/hwdata/Makefile
new file mode 100644
index 0000000000..8e1155e59d
--- /dev/null
+++ b/tools/depends/target/hwdata/Makefile
@@ -0,0 +1,28 @@
+include ../../Makefile.include
+DEPS =../../Makefile.include Makefile ../../download-files.include
+
+LIBNAME=hwdata
+VERSION=0.368
+ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+SHA512=a38adffa503f6f37ddefbad9a0fe9694605ffe54781fc88dd91937a09a54a7de70e027138f34a64bc3a701ab91656c1ae2dc938ed7cb0f73652d34a2ae917690
+include ../../download-files.include
+
+all: .installed-$(PLATFORM)
+
+download: $(TARBALLS_LOCATION)/$(ARCHIVE)
+
+$(PLATFORM): $(DEPS) | $(TARBALLS_LOCATION)/$(ARCHIVE).$(HASH_TYPE)
+ rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
+ cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
+
+.installed-$(PLATFORM): $(PLATFORM)
+ cd $(PLATFORM); ./configure --prefix=$(PREFIX) --datarootdir=$(PREFIX)/share --disable-blacklist
+ cd $(PLATFORM); make install
+ touch $@
+
+clean:
+ $(MAKE) -C $(PLATFORM) clean
+ rm -f .installed-$(PLATFORM)
+
+distclean:
+ rm -rf $(PLATFORM) .installed-$(PLATFORM)
diff --git a/tools/depends/target/libdisplay-info/Makefile b/tools/depends/target/libdisplay-info/Makefile
new file mode 100644
index 0000000000..561a5aeb49
--- /dev/null
+++ b/tools/depends/target/libdisplay-info/Makefile
@@ -0,0 +1,54 @@
+include ../../Makefile.include
+DEPS =../../Makefile.include Makefile ../../download-files.include
+
+LIBNAME=libdisplay-info
+VERSION=0.1.1
+ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+SHA512=8b11c35315f3f16f6853b2ba5daa39c622f2326cfa01d54574beb577efd38d25b8260f7d74c63924473a0487bffdbff727ddc05b12d36e2106b78aadc7d4ff42
+include ../../download-files.include
+
+MESON_BUILD_TYPE=release
+
+ifeq ($(DEBUG_BUILD), yes)
+ MESON_BUILD_TYPE=debug
+endif
+
+# configuration settings
+CONFIGURE = $(NATIVEPREFIX)/bin/python3 $(NATIVEPREFIX)/bin/meson \
+ --prefix=$(PREFIX) \
+ --libdir=lib \
+ --buildtype=$(MESON_BUILD_TYPE)
+
+
+ifeq ($(CROSS_COMPILING), yes)
+CONFIGURE += --cross-file $(PREFIX)/share/cross-file.meson
+export CC=$(CC_FOR_BUILD)
+export CXX=$(CXX_FOR_BUILD)
+export CFLAGS=$(CFLAGS_FOR_BUILD)
+export CXXFLAGS=$(CXXFLAGS_FOR_BUILD)
+else
+export CC CXX CFLAGS CXXFLAGS
+endif
+export PKG_CONFIG_LIBDIR=$(PREFIX)/share/pkgconfig
+
+all: .installed-$(PLATFORM)
+
+download: $(TARBALLS_LOCATION)/$(ARCHIVE)
+
+$(PLATFORM): $(DEPS) | $(TARBALLS_LOCATION)/$(ARCHIVE).$(HASH_TYPE)
+ rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
+ cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
+
+.installed-$(PLATFORM): $(PLATFORM)
+ cd $(PLATFORM); rm -rf build; mkdir -p build
+ cd $(PLATFORM); $(CONFIGURE) . build
+ cd $(PLATFORM)/build; $(NATIVEPREFIX)/bin/ninja -v
+ cd $(PLATFORM)/build; $(NATIVEPREFIX)/bin/ninja -v install
+ touch $@
+
+clean:
+ $(MAKE) -C $(PLATFORM) clean
+ rm -f .installed-$(PLATFORM)
+
+distclean:
+ rm -rf $(PLATFORM) .installed-$(PLATFORM)
diff --git a/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.cpp b/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.cpp
index b1c23ffc3d..4f7bd602e5 100644
--- a/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.cpp
+++ b/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.cpp
@@ -50,17 +50,17 @@ std::string GetColorRange(const VideoPicture& picture)
return "YCbCr limited range";
}
-uint8_t GetEOTF(const VideoPicture& picture)
+KODI::UTILS::Eotf GetEOTF(const VideoPicture& picture)
{
switch (picture.color_transfer)
{
case AVCOL_TRC_SMPTE2084:
- return HDMI_EOTF_SMPTE_ST2084;
+ return KODI::UTILS::Eotf::PQ;
case AVCOL_TRC_ARIB_STD_B67:
case AVCOL_TRC_BT2020_10:
- return HDMI_EOTF_BT_2100_HLG;
+ return KODI::UTILS::Eotf::HLG;
default:
- return HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
+ return KODI::UTILS::Eotf::TRADITIONAL_SDR;
}
}
diff --git a/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.h b/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.h
index e77f75b58b..28496466cd 100644
--- a/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.h
+++ b/xbmc/cores/VideoPlayer/Buffers/VideoBufferDRMPRIME.h
@@ -10,6 +10,7 @@
#include "cores/VideoPlayer/Buffers/VideoBuffer.h"
#include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodec.h"
+#include "utils/DisplayInfo.h"
extern "C"
{
@@ -36,7 +37,7 @@ enum hdmi_eotf
std::string GetColorEncoding(const VideoPicture& picture);
std::string GetColorRange(const VideoPicture& picture);
-uint8_t GetEOTF(const VideoPicture& picture);
+KODI::UTILS::Eotf GetEOTF(const VideoPicture& picture);
const AVMasteringDisplayMetadata* GetMasteringDisplayMetadata(const VideoPicture& picture);
const AVContentLightMetadata* GetContentLightMetadata(const VideoPicture& picture);
diff --git a/xbmc/utils/CMakeLists.txt b/xbmc/utils/CMakeLists.txt
index 8e1328999f..4f6c12dd29 100644
--- a/xbmc/utils/CMakeLists.txt
+++ b/xbmc/utils/CMakeLists.txt
@@ -237,6 +237,11 @@ if("gbm" IN_LIST CORE_PLATFORM_NAME_LC OR "wayland" IN_LIST CORE_PLATFORM_NAME_L
list(APPEND SOURCES DRMHelpers.cpp)
list(APPEND HEADERS DRMHelpers.h)
endif()
+
+ if(LIBDISPLAYINFO_FOUND)
+ list(APPEND SOURCES DisplayInfo.cpp)
+ list(APPEND HEADERS DisplayInfo.h)
+ endif()
endif()
core_add_library(utils)
diff --git a/xbmc/utils/DisplayInfo.cpp b/xbmc/utils/DisplayInfo.cpp
new file mode 100644
index 0000000000..655a55d375
--- /dev/null
+++ b/xbmc/utils/DisplayInfo.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2023 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "DisplayInfo.h"
+
+#include "utils/log.h"
+
+extern "C"
+{
+#include <libdisplay-info/cta.h>
+#include <libdisplay-info/edid.h>
+#include <libdisplay-info/info.h>
+}
+
+using namespace KODI;
+using namespace UTILS;
+
+void CDisplayInfo::DiInfoDeleter::operator()(di_info* p)
+{
+ di_info_destroy(p);
+}
+
+std::unique_ptr<CDisplayInfo> CDisplayInfo::Create(const std::vector<uint8_t>& edid)
+{
+ auto info = std::unique_ptr<CDisplayInfo>(new CDisplayInfo(edid));
+ if (!info->IsValid())
+ return {};
+
+ info->Parse();
+
+ info->LogInfo();
+
+ return info;
+}
+
+CDisplayInfo::CDisplayInfo(const std::vector<uint8_t>& edid)
+{
+ m_info.reset(di_info_parse_edid(edid.data(), edid.size()));
+}
+
+CDisplayInfo::~CDisplayInfo() = default;
+
+bool CDisplayInfo::IsValid() const
+{
+ if (!m_info)
+ return false;
+
+ const char* error = di_info_get_failure_msg(m_info.get());
+ if (error)
+ {
+ CLog::Log(LOGERROR, "[display-info] error: {}", error);
+ return false;
+ }
+
+ return true;
+}
+
+void CDisplayInfo::Parse()
+{
+ char* str = nullptr;
+
+ str = di_info_get_make(m_info.get());
+ m_make = str ? str : "unknown";
+ free(str);
+
+ str = di_info_get_model(m_info.get());
+ m_model = str ? str : "unknown";
+ free(str);
+
+ const di_edid* edid = di_info_get_edid(m_info.get());
+
+ const di_edid_ext* const* extensions = di_edid_get_extensions(edid);
+ for (const di_edid_ext* extension = *extensions; extension != nullptr;
+ extension = *(++extensions))
+ {
+ di_edid_ext_tag tag = di_edid_ext_get_tag(extension);
+
+ switch (tag)
+ {
+ case DI_EDID_EXT_CEA:
+ {
+ const di_edid_cta* cta = di_edid_ext_get_cta(extension);
+
+ const di_cta_data_block* const* blocks = di_edid_cta_get_data_blocks(cta);
+ for (const di_cta_data_block* block = *blocks; block != nullptr; block = *(++blocks))
+ {
+ di_cta_data_block_tag cta_tag = di_cta_data_block_get_tag(block);
+
+ switch (cta_tag)
+ {
+ case DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA:
+ {
+ m_hdr_static_metadata = di_cta_data_block_get_hdr_static_metadata(block);
+
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+void CDisplayInfo::LogInfo() const
+{
+ CLog::Log(LOGINFO, "[display-info] make: '{}' model: '{}'", m_make, m_model);
+
+ if (m_hdr_static_metadata)
+ {
+ CLog::Log(LOGINFO, "[display-info] supports hdr static metadata type1: {}",
+ m_hdr_static_metadata->descriptors->type1);
+
+ CLog::Log(LOGINFO, "[display-info] supported eotf:");
+ CLog::Log(LOGINFO, "[display-info] traditional sdr: {}",
+ m_hdr_static_metadata->eotfs->traditional_sdr);
+ CLog::Log(LOGINFO, "[display-info] traditional hdr: {}",
+ m_hdr_static_metadata->eotfs->traditional_hdr);
+ CLog::Log(LOGINFO, "[display-info] traditional pq: {}", m_hdr_static_metadata->eotfs->pq);
+ CLog::Log(LOGINFO, "[display-info] traditional hlg: {}", m_hdr_static_metadata->eotfs->hlg);
+
+ CLog::Log(LOGINFO, "[display-info] luma min: '{}' avg: '{}' max: '{}'",
+ m_hdr_static_metadata->desired_content_min_luminance,
+ m_hdr_static_metadata->desired_content_max_frame_avg_luminance,
+ m_hdr_static_metadata->desired_content_max_luminance);
+ }
+}
+
+bool CDisplayInfo::SupportsHDRStaticMetadataType1() const
+{
+ if (!m_hdr_static_metadata)
+ return false;
+
+ return m_hdr_static_metadata->descriptors->type1;
+}
+
+bool CDisplayInfo::SupportsEOTF(Eotf eotf) const
+{
+ if (!m_hdr_static_metadata)
+ return false;
+
+ switch (eotf)
+ {
+ case Eotf::TRADITIONAL_SDR:
+ return m_hdr_static_metadata->eotfs->traditional_sdr;
+ case Eotf::TRADITIONAL_HDR:
+ return m_hdr_static_metadata->eotfs->traditional_hdr;
+ case Eotf::PQ:
+ return m_hdr_static_metadata->eotfs->pq;
+ case Eotf::HLG:
+ return m_hdr_static_metadata->eotfs->hlg;
+ default:
+ return false;
+ }
+}
diff --git a/xbmc/utils/DisplayInfo.h b/xbmc/utils/DisplayInfo.h
new file mode 100644
index 0000000000..8f01113dd2
--- /dev/null
+++ b/xbmc/utils/DisplayInfo.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include <memory>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+struct di_info;
+struct di_cta_hdr_static_metadata_block;
+
+namespace KODI
+{
+namespace UTILS
+{
+
+enum class Eotf
+{
+ TRADITIONAL_SDR,
+ TRADITIONAL_HDR,
+ PQ,
+ HLG,
+};
+
+class CDisplayInfo
+{
+public:
+ static std::unique_ptr<CDisplayInfo> Create(const std::vector<uint8_t>& edid);
+
+ ~CDisplayInfo();
+
+ bool SupportsHDRStaticMetadataType1() const;
+
+ bool SupportsEOTF(Eotf eotf) const;
+
+private:
+ explicit CDisplayInfo(const std::vector<uint8_t>& edid);
+
+ bool IsValid() const;
+ void Parse();
+ void LogInfo() const;
+
+ struct DiInfoDeleter
+ {
+ void operator()(di_info* p);
+ };
+
+ std::unique_ptr<di_info, DiInfoDeleter> m_info;
+
+ std::string m_make;
+ std::string m_model;
+
+ const di_cta_hdr_static_metadata_block* m_hdr_static_metadata = nullptr;
+};
+
+} // namespace UTILS
+} // namespace KODI
diff --git a/xbmc/windowing/gbm/WinSystemGbm.cpp b/xbmc/windowing/gbm/WinSystemGbm.cpp
index 9e6d0971ad..f33b6dde41 100644
--- a/xbmc/windowing/gbm/WinSystemGbm.cpp
+++ b/xbmc/windowing/gbm/WinSystemGbm.cpp
@@ -21,6 +21,7 @@
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "settings/lib/Setting.h"
+#include "utils/DisplayInfo.h"
#include "utils/StringUtils.h"
#include "utils/log.h"
#include "windowing/GraphicContext.h"
@@ -70,6 +71,8 @@ CWinSystemGbm::CWinSystemGbm() :
m_libinput->Start();
}
+CWinSystemGbm::~CWinSystemGbm() = default;
+
bool CWinSystemGbm::InitWindowSystem()
{
const char* x11 = getenv("DISPLAY");
@@ -106,6 +109,16 @@ bool CWinSystemGbm::InitWindowSystem()
}
}
+ CDRMConnector* connector = m_DRM->GetConnector();
+ if (connector)
+ {
+ std::vector<uint8_t> edid = connector->GetEDID();
+ if (!edid.empty())
+ {
+ m_info = UTILS::CDisplayInfo::Create(edid);
+ }
+ }
+
if (!m_GBM->CreateDevice(m_DRM->GetFileDescriptor()))
{
m_GBM.reset();
@@ -345,13 +358,16 @@ bool CWinSystemGbm::SetHDR(const VideoPicture* videoPicture)
return true;
}
+ KODI::UTILS::Eotf eotf = DRMPRIME::GetEOTF(*videoPicture);
+
auto connector = drm->GetConnector();
- if (connector->SupportsProperty("HDR_OUTPUT_METADATA"))
+ if (connector->SupportsProperty("HDR_OUTPUT_METADATA") && m_info &&
+ m_info->SupportsHDRStaticMetadataType1() && m_info->SupportsEOTF(eotf))
{
hdr_output_metadata hdr_metadata = {};
hdr_metadata.metadata_type = DRMPRIME::HDMI_STATIC_METADATA_TYPE1;
- hdr_metadata.hdmi_metadata_type1.eotf = DRMPRIME::GetEOTF(*videoPicture);
+ hdr_metadata.hdmi_metadata_type1.eotf = static_cast<uint8_t>(eotf);
hdr_metadata.hdmi_metadata_type1.metadata_type = DRMPRIME::HDMI_STATIC_METADATA_TYPE1;
if (m_hdr_blob_id)
@@ -437,7 +453,22 @@ bool CWinSystemGbm::IsHDRDisplay()
if (!connector)
return false;
- //! @todo: improve detection (edid?)
- // we have no way to know if the display is actually HDR capable and we blindly set the HDR metadata
- return connector->SupportsProperty("HDR_OUTPUT_METADATA");
+ return connector->SupportsProperty("HDR_OUTPUT_METADATA") && m_info &&
+ m_info->SupportsHDRStaticMetadataType1();
+}
+
+CHDRCapabilities CWinSystemGbm::GetDisplayHDRCapabilities() const
+{
+ if (!m_info)
+ return {};
+
+ CHDRCapabilities caps;
+
+ if (m_info->SupportsEOTF(UTILS::Eotf::PQ))
+ caps.SetHDR10();
+
+ if (m_info->SupportsEOTF(UTILS::Eotf::HLG))
+ caps.SetHLG();
+
+ return caps;
}
diff --git a/xbmc/windowing/gbm/WinSystemGbm.h b/xbmc/windowing/gbm/WinSystemGbm.h
index b313d331d5..f57739ee3b 100644
--- a/xbmc/windowing/gbm/WinSystemGbm.h
+++ b/xbmc/windowing/gbm/WinSystemGbm.h
@@ -24,6 +24,10 @@ class IDispResource;
namespace KODI
{
+namespace UTILS
+{
+class CDisplayInfo;
+}
namespace WINDOWING
{
namespace GBM
@@ -33,7 +37,7 @@ class CWinSystemGbm : public CWinSystemBase
{
public:
CWinSystemGbm();
- ~CWinSystemGbm() override = default;
+ ~CWinSystemGbm() override;
const std::string GetName() override { return "gbm"; }
@@ -59,6 +63,7 @@ public:
bool SetHDR(const VideoPicture* videoPicture) override;
bool IsHDRDisplay() override;
+ CHDRCapabilities GetDisplayHDRCapabilities() const override;
std::shared_ptr<CVideoLayerBridge> GetVideoLayerBridge() const { return m_videoLayerBridge; }
void RegisterVideoLayerBridge(std::shared_ptr<CVideoLayerBridge> bridge)
@@ -89,8 +94,10 @@ protected:
private:
uint32_t m_hdr_blob_id = 0;
+
+ std::unique_ptr<UTILS::CDisplayInfo> m_info;
};
}
}
-}
+} // namespace KODI
diff --git a/xbmc/windowing/gbm/drm/DRMConnector.cpp b/xbmc/windowing/gbm/drm/DRMConnector.cpp
index fc76b90575..94f8e909ff 100644
--- a/xbmc/windowing/gbm/drm/DRMConnector.cpp
+++ b/xbmc/windowing/gbm/drm/DRMConnector.cpp
@@ -97,3 +97,31 @@ std::string CDRMConnector::GetName()
{
return GetType() + "-" + std::to_string(m_connector->connector_type_id);
}
+
+std::vector<uint8_t> CDRMConnector::GetEDID() const
+{
+ auto property = std::find_if(m_propsInfo.begin(), m_propsInfo.end(),
+ [](auto& prop) { return prop->name == std::string_view("EDID"); });
+
+ if (property == m_propsInfo.end())
+ {
+ CLog::LogF(LOGDEBUG, "failed to find EDID property for connector: {}",
+ m_connector->connector_id);
+ return {};
+ }
+
+ uint64_t blob_id = m_props->prop_values[std::distance(m_propsInfo.begin(), property)];
+ if (blob_id == 0)
+ return {};
+
+ drmModePropertyBlobPtr blob = drmModeGetPropertyBlob(m_fd, blob_id);
+ if (!blob)
+ return {};
+
+ auto data = static_cast<uint8_t*>(blob->data);
+ auto edid = std::vector<uint8_t>(data, data + blob->length);
+
+ drmModeFreePropertyBlob(blob);
+
+ return edid;
+}
diff --git a/xbmc/windowing/gbm/drm/DRMConnector.h b/xbmc/windowing/gbm/drm/DRMConnector.h
index 5a29222f12..cde242d49f 100644
--- a/xbmc/windowing/gbm/drm/DRMConnector.h
+++ b/xbmc/windowing/gbm/drm/DRMConnector.h
@@ -39,6 +39,8 @@ public:
bool IsConnected() { return m_connector->connection == DRM_MODE_CONNECTED; }
bool CheckConnector();
+ std::vector<uint8_t> GetEDID() const;
+
private:
struct DrmModeConnectorDeleter
{