MythTV  master
mythdrmprimeinterop.cpp
Go to the documentation of this file.
1 // MythTV
2 #include "mythvideocolourspace.h"
3 #include "mythdrmprimeinterop.h"
4 
5 // FFmpeg
6 extern "C" {
7 #include "libavutil/hwcontext_drm.h"
8 #include "libavutil/pixdesc.h"
9 }
10 
11 #define LOC QString("DRMInterop: ")
12 
14  : MythOpenGLInterop(Context, DRMPRIME),
16 {
17 }
18 
20 {
22 }
23 
25 {
26  OpenGLLocker locker(m_context);
27 
28  if (!m_openglTextures.isEmpty() && m_context->IsEGL())
29  {
30  int count = 0;
31  for (auto it = m_openglTextures.constBegin(); it != m_openglTextures.constEnd(); ++it)
32  {
33  vector<MythVideoTexture*> textures = it.value();
34  for (auto & texture : textures)
35  {
36  if (texture->m_data)
37  {
39  texture->m_data = nullptr;
40  count++;
41  }
42  }
43  }
44  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Deleted %1 EGL images in %2 groups")
45  .arg(count).arg(m_openglTextures.size()));
46  }
47 
49 }
50 
52 {
53  if (Context && (InteropType == DRMPRIME))
54  return new MythDRMPRIMEInterop(Context);
55  return nullptr;
56 }
57 
59 {
60  if (FMT_DRMPRIME != Format)
61  return Unsupported;
63  if (!context)
64  return Unsupported;
65  return HaveDMABuf(context) ? DRMPRIME : Unsupported;
66 }
67 
69 {
70  AVDRMFrameDescriptor* result = nullptr;
71 
72  if ((Frame->m_pixFmt != AV_PIX_FMT_DRM_PRIME) || (Frame->m_type != FMT_DRMPRIME) ||
73  !Frame->m_buffer || !Frame->m_priv[0])
74  {
75  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Invalid DRM PRIME buffer %1 %2 %3 %4")
76  .arg(Frame->m_buffer != nullptr).arg(Frame->m_priv[0] != nullptr)
78  .arg(av_get_pix_fmt_name(static_cast<AVPixelFormat>(Frame->m_pixFmt))));
79  return result;
80  }
81 
82  // Sanity check the context
83  if (m_context != Context)
84  {
85  LOG(VB_GENERAL, LOG_ERR, LOC + "Mismatched OpenGL contexts!");
86  return result;
87  }
88 
89  // Check size
90  QSize surfacesize(Frame->m_width, Frame->m_height);
91  if (m_openglTextureSize != surfacesize)
92  {
93  if (!m_openglTextureSize.isEmpty())
94  LOG(VB_GENERAL, LOG_WARNING, LOC + "Video texture size changed!");
95  m_openglTextureSize = surfacesize;
96  }
97 
98  return reinterpret_cast<AVDRMFrameDescriptor*>(Frame->m_buffer);
99 }
100 
102  MythVideoColourSpace *ColourSpace,
104  FrameScanType Scan)
105 {
106  vector<MythVideoTexture*> result;
107  if (!Frame)
108  return result;
109 
110  auto *drmdesc = VerifyBuffer(Context, Frame);
111  if (!drmdesc)
112  return result;
113 
114  bool firstpass = m_openglTextures.isEmpty();
115  bool interlaced = is_interlaced(Scan);
116  bool composed = static_cast<uint>(drmdesc->nb_layers) == 1 && m_composable;
117  auto id = reinterpret_cast<unsigned long long>(drmdesc);
118 
119  auto Separate = [=]()
120  {
121  vector<MythVideoTexture*> textures;
122  if (!m_openglTextures.contains(id))
123  {
124  textures = CreateTextures(drmdesc, m_context, Frame, true);
125  m_openglTextures.insert(id, textures);
126  }
127  else
128  {
129  textures = m_openglTextures[id];
130  }
131 
132  if (textures.empty() ? false : MythVideoFrame::YUVFormat(textures[0]->m_frameFormat))
133  {
134  // Enable colour controls for YUV frame
135  if (firstpass)
137  ColourSpace->UpdateColourSpace(Frame);
138  // and shader based deinterlacing
139  Frame->m_deinterlaceAllowed = Frame->m_deinterlaceAllowed | DEINT_SHADER;
140  }
141  return textures;
142  };
143 
144  // Separate texture for each plane
145  if (!composed)
146  return Separate();
147 
148  // Single RGB texture
149  // Disable picture attributes
150  if (firstpass)
152 
153  // Is deinterlacing selected? Accept any value as RGB frames can only be deinterlaced here
154  bool doublerate = false;
155  MythDeintType option = Frame->GetDoubleRateOption(DEINT_CPU | DEINT_SHADER | DEINT_DRIVER, DEINT_ALL);
156  if (option != DEINT_NONE)
157  doublerate = true;
158  else
159  option = Frame->GetSingleRateOption(DEINT_CPU | DEINT_SHADER | DEINT_DRIVER, DEINT_ALL);
160  interlaced &= option != DEINT_NONE;
161 
162  // Clear redundant frame caches
163  if (interlaced && !m_deinterlacing)
164  {
165  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Clearing progessive frame cache");
166  DeleteTextures();
167  }
168  else if (m_deinterlacing && !interlaced)
169  {
170  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Clearing interlaced field cache");
171  DeleteTextures();
172  }
173  m_deinterlacing = interlaced;
174 
175  if (!m_openglTextures.contains(id))
176  {
177  // This will create 2 half height textures representing the top and bottom fields
178  // if deinterlacing
179  result = CreateTextures(drmdesc, m_context, Frame, false,
181  // Fallback to separate textures if the driver does not support composition
182  if (result.empty())
183  {
184  m_composable = false;
185  m_deinterlacing = false;
186  DeleteTextures();
187  LOG(VB_GENERAL, LOG_INFO, LOC + "YUV composition failed. Trying separate textures.");
188  return Separate();
189  }
190  m_openglTextures.insert(id, result);
191  }
192  else
193  {
194  result = m_openglTextures[id];
195  }
196 
197  if (m_deinterlacing)
198  {
199  result.clear();
200  Frame->m_deinterlaceInuse = DEINT_DRIVER | DEINT_BASIC;
201  Frame->m_deinterlaceInuse2x = doublerate;
202  bool tff = Frame->m_interlacedReverse ? !Frame->m_topFieldFirst : Frame->m_topFieldFirst;
203  result.emplace_back(m_openglTextures[id].at(Scan == kScan_Interlaced ? (tff ? 1 : 0) : tff ? 0 : 1));
204  }
205 
206  return result;
207 }
208 
DEINT_DRIVER
@ DEINT_DRIVER
Definition: mythframe.h:70
LOC
#define LOC
Definition: mythdrmprimeinterop.cpp:11
DEINT_SHADER
@ DEINT_SHADER
Definition: mythframe.h:69
MythDRMPRIMEInterop
Definition: mythdrmprimeinterop.h:11
FMT_DRMPRIME
@ FMT_DRMPRIME
Definition: mythframe.h:59
MythEGL::GetEGLDisplay
void * GetEGLDisplay(void)
Definition: mythegl.cpp:80
Frame
Definition: zmdefines.h:94
MythDRMPRIMEInterop::DeleteTextures
void DeleteTextures(void) override
Definition: mythdrmprimeinterop.cpp:24
MythVideoColourSpace::UpdateColourSpace
bool UpdateColourSpace(const MythVideoFrame *Frame)
Set the current colourspace to use.
Definition: mythvideocolourspace.cpp:329
DEINT_NONE
@ DEINT_NONE
Definition: mythframe.h:64
arg
arg(title).arg(filename).arg(doDelete))
FrameScanType
FrameScanType
Definition: videoouttypes.h:95
Context
QHash< QString, Action * > Context
Definition: action.h:77
MythDate::Format
Format
Definition: mythdate.h:13
MythDRMPRIMEInterop::Create
static MythDRMPRIMEInterop * Create(MythRenderOpenGL *Context, Type InteropType)
Definition: mythdrmprimeinterop.cpp:51
MythVideoColourSpace::SetSupportedAttributes
void SetSupportedAttributes(PictureAttributeSupported Supported)
Enable the given set of picture attributes.
Definition: mythvideocolourspace.cpp:122
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MythEGLDMABUF
Definition: mythegldmabuf.h:16
DEINT_ALL
@ DEINT_ALL
Definition: mythframe.h:71
MythEGLDMABUF::CreateTextures
std::vector< MythVideoTexture * > CreateTextures(AVDRMFrameDescriptor *Desc, MythRenderOpenGL *Context, MythVideoFrame *Frame, bool UseSeparate, FrameScanType Scan=kScan_Progressive)
Definition: mythegldmabuf.cpp:366
MythEGLDMABUF::HaveDMABuf
static bool HaveDMABuf(MythRenderOpenGL *Context)
Definition: mythegldmabuf.cpp:25
MythEGL::eglDestroyImageKHR
void eglDestroyImageKHR(void *Disp, void *Image)
Definition: mythegl.cpp:160
kPictureAttributeSupported_None
@ kPictureAttributeSupported_None
Definition: videoouttypes.h:118
DEINT_CPU
@ DEINT_CPU
Definition: mythframe.h:68
MythDRMPRIMEInterop::m_composable
bool m_composable
Definition: mythdrmprimeinterop.h:29
MythVideoFrame::YUVFormat
static bool YUVFormat(VideoFrameType Type)
Definition: mythframe.h:449
mythvideocolourspace.h
MythOpenGLInterop
Definition: mythopenglinterop.h:24
MythOpenGLInterop::Unsupported
@ Unsupported
Definition: mythopenglinterop.h:31
kScan_Progressive
@ kScan_Progressive
Definition: videoouttypes.h:100
MythEGL::IsEGL
bool IsEGL(void)
Definition: mythegl.cpp:29
MythDRMPRIMEInterop::m_deinterlacing
bool m_deinterlacing
Definition: mythdrmprimeinterop.h:28
uint
unsigned int uint
Definition: compat.h:141
MythOpenGLInterop::m_context
MythRenderOpenGL * m_context
Definition: mythopenglinterop.h:73
MythDRMPRIMEInterop::Acquire
vector< MythVideoTexture * > Acquire(MythRenderOpenGL *Context, MythVideoColourSpace *ColourSpace, MythVideoFrame *Frame, FrameScanType Scan) override
Definition: mythdrmprimeinterop.cpp:101
MythOpenGLInterop::Type
Type
Definition: mythopenglinterop.h:30
MythOpenGLInterop::DRMPRIME
@ DRMPRIME
Definition: mythopenglinterop.h:41
ALL_PICTURE_ATTRIBUTES
#define ALL_PICTURE_ATTRIBUTES
Definition: videoouttypes.h:127
MythDRMPRIMEInterop::GetInteropType
static Type GetInteropType(VideoFrameType Format)
Definition: mythdrmprimeinterop.cpp:58
MythRenderOpenGL
Definition: mythrenderopengl.h:99
MythDeintType
MythDeintType
Definition: mythframe.h:63
MythDRMPRIMEInterop::MythDRMPRIMEInterop
MythDRMPRIMEInterop(MythRenderOpenGL *Context)
Definition: mythdrmprimeinterop.cpp:13
MythVideoFrame::FormatDescription
static QString FormatDescription(VideoFrameType Type)
Definition: mythframe.cpp:363
kScan_Interlaced
@ kScan_Interlaced
Definition: videoouttypes.h:98
MythRenderOpenGL::GetOpenGLRender
static MythRenderOpenGL * GetOpenGLRender(void)
Definition: mythrenderopengl.cpp:66
MythDRMPRIMEInterop::VerifyBuffer
AVDRMFrameDescriptor * VerifyBuffer(MythRenderOpenGL *Context, MythVideoFrame *Frame)
Definition: mythdrmprimeinterop.cpp:68
mythdrmprimeinterop.h
MythDRMPRIMEInterop::~MythDRMPRIMEInterop
~MythDRMPRIMEInterop() override
Definition: mythdrmprimeinterop.cpp:19
VideoFrameType
VideoFrameType
Definition: mythframe.h:16
MythVideoFrame
Definition: mythframe.h:83
MythOpenGLInterop::DeleteTextures
virtual void DeleteTextures(void)
Definition: mythopenglinterop.cpp:244
DEINT_BASIC
@ DEINT_BASIC
Definition: mythframe.h:65
MythOpenGLInterop::m_openglTextures
QHash< unsigned long long, vector< MythVideoTexture * > > m_openglTextures
Definition: mythopenglinterop.h:75
is_interlaced
bool is_interlaced(FrameScanType Scan)
Definition: videoouttypes.h:188
MythOpenGLInterop::m_openglTextureSize
QSize m_openglTextureSize
Definition: mythopenglinterop.h:76
MythVideoColourSpace
MythVideoColourSpace contains a QMatrix4x4 that can convert YCbCr data to RGB.
Definition: mythvideocolourspace.h:21
OpenGLLocker
Definition: mythrenderopengl.h:255