MythTV master
mythvideodrm.cpp
Go to the documentation of this file.
1// Qt
2#include <QGuiApplication>
3#include <qpa/qplatformnativeinterface.h>
4
5// MythTV
8#include "mythframe.h"
13#include "drm/mythvideodrm.h"
14
15// Std
16#include <unistd.h>
17
18#define LOC QString("DRMVideo: ")
19
21 : m_colourSpace(ColourSpace)
22{
23 if (m_colourSpace)
25
26 if (auto *drmdisplay = HasMythMainWindow() ? dynamic_cast<MythDisplayDRM*>(GetMythMainWindow()->GetDisplay()) : nullptr; drmdisplay)
27 {
28 if (m_device = drmdisplay->GetDevice(); m_device && m_device->Atomic() && m_device->Authenticated())
29 {
30 if (m_videoPlane = m_device->GetVideoPlane(); m_videoPlane.get() && m_videoPlane->m_id)
31 {
32 m_valid = m_videoPlane->m_fbIdProp && m_videoPlane->m_crtcIdProp &&
33 m_videoPlane->m_srcWProp && m_videoPlane->m_srcHProp &&
34 m_videoPlane->m_srcXProp && m_videoPlane->m_srcYProp &&
35 m_videoPlane->m_crtcXProp && m_videoPlane->m_crtcYProp &&
36 m_videoPlane->m_crtcWProp && m_videoPlane->m_crtcHProp;
37 }
38 }
39 }
40
41 if (m_valid)
42 {
43 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Using Plane #%1 for video").arg(m_videoPlane->m_id));
44
45 // Set the CRTC for the plane. No need to do this for every frame.
46 m_device->QueueAtomics({{ m_videoPlane->m_id, m_videoPlane->m_crtcIdProp->m_id, m_device->GetCrtc()->m_id }});
47
48 // Set colourspace and listen for changes
49 if (m_colourSpace)
50 {
51 // Disable colour adjustments.
52 // Note: If DRM subsequently fails, these should be re-enabled by
53 // the OpenGL code.
56 ColourSpaceUpdated(true/*??*/);
57 }
58 }
59 else
60 {
61 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to setup DRM video");
62 }
63}
64
66{
67 LOG(VB_GENERAL, LOG_INFO, LOC + "Closing");
68
69 // Release colourspace
70 if (m_colourSpace)
72
73 // Disable our video plane
74 //m_device->DisableVideoPlane();
75}
76
77void MythVideoDRM::ColourSpaceUpdated(bool /*PrimariesChanged*/)
78{
79 if (!(m_colourSpace && m_device && m_videoPlane.get()))
80 return;
81
82 MythAtomics queue; // NOLINT(cppcoreguidelines-init-variables)
83 if (auto range = MythDRMProperty::GetProperty("COLOR_RANGE", m_videoPlane->m_properties); range.get())
84 {
86 queue.emplace_back(m_videoPlane->m_id, range->m_id, rangev);
87 }
88
89 if (auto encoding = MythDRMProperty::GetProperty("COLOR_ENCODING", m_videoPlane->m_properties); encoding.get())
90 {
92 queue.emplace_back(m_videoPlane->m_id, encoding->m_id, encv);
93 }
94
95 if (!queue.empty())
96 m_device->QueueAtomics(queue);
97}
98
99bool MythVideoDRM::RenderFrame(AVDRMFrameDescriptor* DRMDesc, MythVideoFrame* Frame)
100{
101 if (!m_valid)
102 return false;
103
104 if (!(DRMDesc && Frame))
105 {
106 m_valid = false;
107 return false;
108 }
109
110 if (!m_handles.contains(DRMDesc))
111 {
112 auto buffer = MythVideoDRMBuffer::Create(m_device, DRMDesc, { Frame->m_width, Frame->m_height });
113 if (!buffer.get())
114 {
115 m_valid = false;
116 return false;
117 }
118 m_handles.insert(DRMDesc, buffer);
119 }
120
121 Frame->m_displayed = true;
122 auto handle = m_handles[DRMDesc];
123 auto id = m_videoPlane->m_id;
124
125 if (m_lastSrc != Frame->m_srcRect)
126 {
127 m_lastSrc = Frame->m_srcRect;
128 m_device->QueueAtomics({
129 { id, m_videoPlane->m_srcXProp->m_id, m_lastSrc.left() << 16 },
130 { id, m_videoPlane->m_srcYProp->m_id, m_lastSrc.top() << 16 },
131 { id, m_videoPlane->m_srcWProp->m_id, m_lastSrc.width() << 16 },
132 { id, m_videoPlane->m_srcHProp->m_id, m_lastSrc.height() << 16 }});
133 }
134
135 if (m_lastDst != Frame->m_dstRect)
136 {
137 m_lastDst = Frame->m_dstRect;
138 m_device->QueueAtomics({
139 { id, m_videoPlane->m_crtcXProp->m_id, (m_lastDst.left() + 1) & ~1 },
140 { id, m_videoPlane->m_crtcYProp->m_id, (m_lastDst.top() + 1) & ~1 },
141 { id, m_videoPlane->m_crtcWProp->m_id, (m_lastDst.width() + 1) & ~1 },
142 { id, m_videoPlane->m_crtcHProp->m_id, (m_lastDst.height() + 1) & ~1 }});
143 }
144
145 return m_device->QueueAtomics({{ id, m_videoPlane->m_fbIdProp->m_id, handle->GetFB() }});
146}
static DRMProp GetProperty(const QString &Name, const DRMProps &Properties)
MythVideoColourSpace contains a QMatrix4x4 that can convert YCbCr data to RGB.
void SetSupportedAttributes(PictureAttributeSupported Supported)
Enable the given set of picture attributes.
void Updated(bool PrimariesChanged)
static DRMHandle Create(MythDRMPtr Device, AVDRMFrameDescriptor *DRMDesc, QSize Size)
static uint64_t FFmpegColorRangeToDRM(const DRMProp &Property, int Range)
static uint64_t FFmpegColorEncodingToDRM(const DRMProp &Property, int Encoding)
~MythVideoDRM() override
QMap< AVDRMFrameDescriptor *, DRMHandle > m_handles
Definition: mythvideodrm.h:34
void ColourSpaceUpdated(bool)
MythDRMPtr m_device
Definition: mythvideodrm.h:30
MythVideoColourSpace * m_colourSpace
Definition: mythvideodrm.h:35
QRect m_lastSrc
Definition: mythvideodrm.h:32
QRect m_lastDst
Definition: mythvideodrm.h:33
DRMPlane m_videoPlane
Definition: mythvideodrm.h:31
bool RenderFrame(AVDRMFrameDescriptor *DRMDesc, MythVideoFrame *Frame)
MythVideoDRM(MythVideoColourSpace *ColourSpace)
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
virtual int IncrRef(void)
Increments reference count.
std::vector< MythAtomic > MythAtomics
Definition: mythdrmdevice.h:21
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
bool HasMythMainWindow(void)
MythMainWindow * GetMythMainWindow(void)
#define LOC
@ kPictureAttributeSupported_None