Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
libmythtv: Add some HDR tracking classess
- these are a work in progress and are likely to change significantly
- Loading branch information
1 parent
9b91d60
commit b5465c0
Showing
5 changed files
with
220 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
// MythTV | ||
#include "mythlogging.h" | ||
#include "mythframe.h" | ||
#include "drm/mythhdrtrackerdrm.h" | ||
#include "platforms/mythdisplaydrm.h" | ||
|
||
#define LOC QString("HDRDrm: ") | ||
|
||
HDRTracker MythHDRTrackerDRM::Create(MythDisplay* _Display, int HDRSupport) | ||
{ | ||
auto * display = dynamic_cast<MythDisplayDRM*>(_Display); | ||
if (!display) | ||
return nullptr; | ||
|
||
// Display support for HDR formats has already been checked. We need to check | ||
// here that we have a valid, authenticated DRM device and that the connector | ||
// supports the HDR_OUTPUT_METADATA property | ||
auto device = display->GetDevice(); | ||
if (!(device && device->Authenticated() && device->Atomic())) | ||
return nullptr; | ||
|
||
if (auto connector = device->GetConnector(); connector.get()) | ||
if (auto hdrprop = MythDRMProperty::GetProperty("HDR_OUTPUT_METADATA", connector->m_properties); hdrprop.get()) | ||
return std::shared_ptr<MythHDRTracker>(new MythHDRTrackerDRM(device, connector, hdrprop, HDRSupport)); | ||
|
||
return nullptr; | ||
} | ||
|
||
MythHDRTrackerDRM::MythHDRTrackerDRM(MythDRMPtr Device, DRMConn Connector, DRMProp HDRProp, int HDRSupport) | ||
: MythHDRTracker(HDRSupport), | ||
m_device(Device), | ||
m_connector(Connector), | ||
m_hdrProp(HDRProp) | ||
{ | ||
m_connector = m_device->GetConnector(); | ||
m_hdrProp = MythDRMProperty::GetProperty("HDR_OUTPUT_METADATA", m_connector->m_properties); | ||
LOG(VB_GENERAL, LOG_INFO, LOC + QString("Tracking HDR signalling for: %1") | ||
.arg(MythEDID::EOTFToStrings(m_hdrSupport).join(","))); | ||
} | ||
|
||
MythHDRTrackerDRM::~MythHDRTrackerDRM() | ||
{ | ||
MythHDRTrackerDRM::Reset(); | ||
} | ||
|
||
void MythHDRTrackerDRM::Reset() | ||
{ | ||
if (m_hdrBlob) | ||
{ | ||
m_device->QueueAtomics({{ m_connector->m_id, m_hdrProp->m_id, 0 }}); | ||
drmModeDestroyPropertyBlob(m_device->GetFD(), m_hdrBlob); | ||
m_hdrBlob = 0; | ||
} | ||
} | ||
|
||
void MythHDRTrackerDRM::Update(MythVideoFrame* Frame) | ||
{ | ||
if (!Frame) | ||
return; | ||
|
||
// Do we have an HDR EOTF that is supported by the display and HDR Metadata blob support | ||
if (auto eotf = MythVideoDRMUtils::FFmpegTransferToEOTF(Frame->m_colortransfer, m_hdrSupport); | ||
eotf >= HDMI_EOTF_SMPTE_ST2084) | ||
{ | ||
bool needhdrblob = false; | ||
// HLG has no static metadata | ||
if (HDMI_EOTF_BT_2100_HLG == eotf) | ||
{ | ||
if (!(m_hdrBlob && m_drmMetadata.hdmi_metadata_type1.eotf == HDMI_EOTF_BT_2100_HLG)) | ||
{ | ||
needhdrblob = true; | ||
m_ffmpegMetadata = nullptr; | ||
m_drmMetadata = MythVideoDRMUtils::s_defaultMetadata; | ||
m_drmMetadata.hdmi_metadata_type1.eotf = eotf; | ||
} | ||
} | ||
// We need static metadata for HDR10 | ||
else if (Frame->m_hdrMetadata.get()) | ||
{ | ||
if (!m_ffmpegMetadata.get() || !m_ffmpegMetadata.get()->Equals(Frame->m_hdrMetadata.get()) || | ||
m_drmMetadata.hdmi_metadata_type1.eotf != HDMI_EOTF_SMPTE_ST2084) | ||
{ | ||
needhdrblob = true; | ||
m_ffmpegMetadata = Frame->m_hdrMetadata; | ||
m_drmMetadata = MythVideoDRMUtils::s_defaultMetadata; | ||
m_drmMetadata.hdmi_metadata_type1.eotf = eotf; | ||
m_drmMetadata.hdmi_metadata_type1.max_display_mastering_luminance = m_ffmpegMetadata->m_maxMasteringLuminance; | ||
m_drmMetadata.hdmi_metadata_type1.min_display_mastering_luminance = m_ffmpegMetadata->m_minMasteringLuminance; | ||
m_drmMetadata.hdmi_metadata_type1.max_cll = m_ffmpegMetadata->m_maxContentLightLevel; | ||
m_drmMetadata.hdmi_metadata_type1.max_fall = m_ffmpegMetadata->m_maxFrameAverageLightLevel; | ||
m_drmMetadata.hdmi_metadata_type1.white_point.x = m_ffmpegMetadata->m_whitePoint[0]; | ||
m_drmMetadata.hdmi_metadata_type1.white_point.y = m_ffmpegMetadata->m_whitePoint[1]; | ||
for (size_t i = 0; i < 3; ++i) | ||
{ | ||
m_drmMetadata.hdmi_metadata_type1.display_primaries[i].x = m_ffmpegMetadata->m_displayPrimaries[i][0]; | ||
m_drmMetadata.hdmi_metadata_type1.display_primaries[i].y = m_ffmpegMetadata->m_displayPrimaries[i][1]; | ||
} | ||
} | ||
} | ||
|
||
if (needhdrblob) | ||
{ | ||
if (m_hdrBlob) | ||
drmModeDestroyPropertyBlob(m_device->GetFD(), m_hdrBlob); | ||
LOG(VB_GENERAL, LOG_INFO, LOC + QString("Creating HDR info frame for %1") | ||
.arg(eotf == HDMI_EOTF_BT_2100_HLG ? "HLG" : "HDR10")); | ||
drmModeCreatePropertyBlob(m_device->GetFD(), &m_drmMetadata, sizeof(m_drmMetadata), &m_hdrBlob); | ||
m_device->QueueAtomics({{ m_connector->m_id, m_hdrProp->m_id, m_hdrBlob }}); | ||
} | ||
} | ||
else | ||
{ | ||
Reset(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#ifndef MYTHHDRTRACKERDRM_H | ||
#define MYTHHDRTRACKERDRM_H | ||
|
||
// MythTV | ||
#include "mythhdrtracker.h" | ||
#include "drm/mythvideodrmutils.h" | ||
#include "platforms/mythdrmdevice.h" | ||
#include "platforms/drm/mythdrmproperty.h" | ||
|
||
using DRMMeta = hdr_output_metadata; | ||
|
||
class MythHDRTrackerDRM : public MythHDRTracker | ||
{ | ||
public: | ||
static HDRTracker Create(MythDisplay* _Display, int HDRSupport); | ||
~MythHDRTrackerDRM() override; | ||
void Update(MythVideoFrame* Frame) override; | ||
void Reset() override; | ||
|
||
protected: | ||
MythHDRTrackerDRM(MythDRMPtr Device, DRMConn Connector, DRMProp HDRProp, int HDRSupport); | ||
|
||
MythDRMPtr m_device { nullptr }; | ||
DRMConn m_connector { nullptr }; | ||
DRMProp m_hdrProp { nullptr }; | ||
DRMMeta m_drmMetadata; | ||
uint32_t m_hdrBlob { 0 }; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// MythTV | ||
#ifdef USING_DRM_VIDEO | ||
#include "drm/mythhdrtrackerdrm.h" | ||
#endif | ||
#include "mythhdrtracker.h" | ||
|
||
HDRTracker MythHDRTracker::Create(MythDisplay* _Display) | ||
{ | ||
if (!_Display) | ||
return nullptr; | ||
|
||
// Check the EDID for HDR support first | ||
const auto & edid = _Display->GetEDID(); | ||
if (!edid.Valid()) | ||
return nullptr; | ||
|
||
auto [types, metadata] = edid.GetHDRSupport(); | ||
|
||
// We only support HDR10 and HLG | ||
if (types < MythEDID::HDR10) | ||
{ | ||
LOG(VB_PLAYBACK, LOG_INFO, "No HDR support detected for this display"); | ||
return nullptr; | ||
} | ||
|
||
// We only know how to deal with HDR Static Metablock Type 1 (which is the only type) | ||
if ((metadata & MythEDID::Static1) != MythEDID::Static1) | ||
return nullptr; | ||
|
||
HDRTracker result = nullptr; | ||
#ifdef USING_DRM_VIDEO | ||
result = MythHDRTrackerDRM::Create(_Display, types); | ||
#endif | ||
|
||
if (!result.get()) | ||
LOG(VB_PLAYBACK, LOG_INFO, "HDR signalling support not available"); | ||
return result; | ||
} | ||
|
||
MythHDRTracker::MythHDRTracker(int HDRSupport) | ||
: m_hdrSupport(HDRSupport) | ||
{ | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#ifndef MYTHHDRTRACKER_H | ||
#define MYTHHDRTRACKER_H | ||
|
||
// MythTV | ||
#include "mythhdrmetadata.h" | ||
|
||
// Std | ||
#include <memory> | ||
|
||
using HDRTracker = std::shared_ptr<class MythHDRTracker>; | ||
|
||
class MythHDRTracker | ||
{ | ||
public: | ||
static HDRTracker Create(class MythDisplay* _Display); | ||
virtual void Update(class MythVideoFrame* Frame) = 0; | ||
virtual void Reset() = 0; | ||
|
||
protected: | ||
explicit MythHDRTracker(int HDRSupport); | ||
virtual ~MythHDRTracker() = default; | ||
|
||
MythHDRPtr m_ffmpegMetadata { nullptr }; | ||
int m_hdrSupport { 0 }; | ||
}; | ||
|
||
#endif |
b5465c0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On my system compilation of mythhdrtracker.cpp fails:
mythhdrtracker.cpp: In static member function ‘static HDRTracker MythHDRTracker::Create(MythDisplay*)’:
mythhdrtracker.cpp:13:33: error: invalid use of incomplete type ‘class MythDisplay’
13 | const auto & edid = _Display->GetEDID();
Adding #include "mythdisplay.h" to get MythDisplay (and a lot more) defined fixes it for me.