MythTV  master
mythopenglinterop.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QWaitCondition>
3 
4 // MythTV
5 #include "mythplayerui.h"
6 #include "mythcorecontext.h"
7 #include "mythvideocolourspace.h"
9 #include "mythopenglinterop.h"
10 
11 #ifdef USING_VAAPI
12 #include "mythvaapiinterop.h"
13 #endif
14 #ifdef USING_VTB
15 #include "mythvtbinterop.h"
16 #endif
17 #ifdef USING_MEDIACODEC
18 #include "mythmediacodeccontext.h"
19 #endif
20 #ifdef USING_VDPAU
21 #include "mythvdpauinterop.h"
22 #endif
23 #ifdef USING_NVDEC
24 #include "mythnvdecinterop.h"
25 #endif
26 #ifdef USING_MMAL
27 #include "mythmmalinterop.h"
28 #endif
29 #ifdef USING_EGL
30 #include "mythdrmprimeinterop.h"
31 #endif
32 
33 #define LOC QString("OpenGLInterop: ")
34 
36 {
37  if (InteropType == VAAPIEGLDRM) return "VAAPI DRM";
38  if (InteropType == VAAPIGLXPIX) return "VAAPI GLX Pixmap";
39  if (InteropType == VAAPIGLXCOPY) return "VAAPI GLX Copy";
40  if (InteropType == VTBOPENGL) return "VTB OpenGL";
41  if (InteropType == VTBSURFACE) return "VTB IOSurface";
42  if (InteropType == MEDIACODEC) return "MediaCodec Surface";
43  if (InteropType == VDPAU) return "VDPAU";
44  if (InteropType == NVDEC) return "NVDEC";
45  if (InteropType == MMAL) return "MMAL";
46  if (InteropType == DRMPRIME) return "DRM PRIME";
47  if (InteropType == DUMMY) return "DUMMY";
48  return "Unsupported";
49 }
50 
52 {
53  QStringList result;
54  if (GetInteropType(Format, nullptr) != Unsupported)
55  result << "opengl-hw";
56  return result;
57 }
58 
59 void MythOpenGLInterop::GetInteropTypeCallback(void *Wait, void *Format, void *Result)
60 {
61  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Check interop callback");
62  auto *wait = reinterpret_cast<QWaitCondition*>(Wait);
63  auto *format = reinterpret_cast<VideoFrameType*>(Format);
64  auto *result = reinterpret_cast<MythOpenGLInterop::Type*>(Result);
65 
66  if (format && result)
67  *result = MythOpenGLInterop::GetInteropType(*format, nullptr);
68  if (wait)
69  wait->wakeAll();
70 }
71 
75 {
76  // cache supported formats to avoid potentially expensive callbacks
77  static QMutex s_lock(QMutex::Recursive);
78  static QHash<VideoFrameType,Type> s_supported;
79 
80  Type supported = Unsupported;
81  bool alreadychecked = false;
82 
83  // have we checked this format already
84  s_lock.lock();
85  if (s_supported.contains(Format))
86  {
87  supported = s_supported.value(Format);
88  alreadychecked = true;
89  }
90  s_lock.unlock();
91 
92  // need to check
93  if (!alreadychecked)
94  {
95  if (!gCoreContext->IsUIThread())
96  {
97  if (!Player)
98  {
99  LOG(VB_GENERAL, LOG_ERR, LOC +
100  "GetInteropType called from another thread without player");
101  }
102  else
103  {
104  // Note - this is a callback into the same function from the main thread
105  Player->HandleDecoderCallback("interop check",
107  &Format, &supported);
108  }
109  return supported;
110  }
111 
112  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Checking interop support for %1")
114 
115 #ifdef USING_VTB
116  if (FMT_VTB == Format)
118 #endif
119 #ifdef USING_VAAPI
120  if (FMT_VAAPI == Format)
122 #endif
123 #ifdef USING_MEDIACODEC
124  if (FMT_MEDIACODEC == Format)
125  supported = MEDIACODEC;
126 #endif
127 #ifdef USING_VDPAU
128  if (FMT_VDPAU == Format)
130 #endif
131 #ifdef USING_NVDEC
132  if (FMT_NVDEC == Format)
134 #endif
135 #ifdef USING_MMAL
136  if (FMT_MMAL == Format)
138 #endif
139 #ifdef USING_EGL
140  if (FMT_DRMPRIME == Format)
142 #endif
143  // update supported formats
144  s_lock.lock();
145  s_supported.insert(Format, supported);
146  s_lock.unlock();
147  }
148 
149  if (Unsupported == supported)
150  {
151  LOG(VB_GENERAL, LOG_WARNING, LOC + QString("No render support for frame type '%1'")
153  }
154  else
155  {
156  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Rendering supported for frame type '%1' with %2")
158  }
159  return supported;
160 }
161 
163  MythVideoColourSpace *ColourSpace,
165  FrameScanType Scan)
166 {
167  vector<MythVideoTexture*> result;
168  if (!(Context && Frame))
169  return result;
170 
171  if (!(Frame->m_priv[1] && MythVideoFrame::HardwareFormat(Frame->m_type) &&
172  (Frame->m_type == MythAVUtil::PixelFormatToFrameType(static_cast<AVPixelFormat>(Frame->m_pixFmt)))))
173  {
174  LOG(VB_GENERAL, LOG_WARNING, LOC + "Not a valid hardware frame");
175  return result;
176  }
177 
178  MythOpenGLInterop* interop = nullptr;
179  if ((Frame->m_type == FMT_VTB) || (Frame->m_type == FMT_MEDIACODEC) ||
180  (Frame->m_type == FMT_MMAL) || (Frame->m_type == FMT_DRMPRIME))
181  {
182  interop = reinterpret_cast<MythOpenGLInterop*>(Frame->m_priv[1]);
183  }
184  else
185  {
186  // Unpick
187  auto* buffer = reinterpret_cast<AVBufferRef*>(Frame->m_priv[1]);
188  if (!buffer || !buffer->data)
189  return result;
190  if (Frame->m_type == FMT_NVDEC)
191  {
192  auto* context = reinterpret_cast<AVHWDeviceContext*>(buffer->data);
193  if (!context || !context->user_opaque)
194  return result;
195  interop = reinterpret_cast<MythOpenGLInterop*>(context->user_opaque);
196  }
197  else
198  {
199  auto* frames = reinterpret_cast<AVHWFramesContext*>(buffer->data);
200  if (!frames || !frames->user_opaque)
201  return result;
202  interop = reinterpret_cast<MythOpenGLInterop*>(frames->user_opaque);
203  }
204  }
205 
206  if (interop)
207  return interop->Acquire(Context, ColourSpace, Frame, Scan);
208  LOG(VB_GENERAL, LOG_ERR, LOC + "No OpenGL interop found");
209  return result;
210 }
211 
213  : ReferenceCounter("GLInterop", true),
214  m_context(Context),
215  m_type(InteropType)
216 {
217  if (m_context)
218  m_context->IncrRef();
219 }
220 
222 {
224  if (m_context)
225  m_context->DecrRef();
226 }
227 
229 {
230  // This is used to store AVHWDeviceContext free and user_opaque when
231  // set by the decoder in use. This usually applies to VAAPI and VDPAU
232  // and we do not always want or need to use MythRenderOpenGL e.g. when
233  // checking functionality only.
234  return new MythOpenGLInterop(nullptr, DUMMY);
235 }
236 
237 vector<MythVideoTexture*> MythOpenGLInterop::Acquire(MythRenderOpenGL* /*Context*/,
238  MythVideoColourSpace* /*ColourSpace*/,
239  MythVideoFrame* /*Frame*/, FrameScanType /*Scan*/)
240 {
241  return vector<MythVideoTexture*>();
242 }
243 
245 {
246  if (m_context && !m_openglTextures.isEmpty())
247  {
248  OpenGLLocker locker(m_context);
249  int count = 0;
250  for (auto it = m_openglTextures.constBegin(); it != m_openglTextures.constEnd(); ++it)
251  {
252  vector<MythVideoTexture*> textures = it.value();
253  for (auto & texture : textures)
254  {
255  if (texture->m_textureId)
256  m_context->glDeleteTextures(1, &texture->m_textureId);
258  count++;
259  }
260  textures.clear();
261  }
262  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Deleted %1 textures in %2 groups")
263  .arg(count).arg(m_openglTextures.size()));
264  m_openglTextures.clear();
265  }
266 }
267 
269 {
270  return m_type;
271 }
272 
274 {
275  return m_player;
276 }
277 
279 {
280  m_player = Player;
281 }
282 
284 {
285  m_defaultFree = FreeContext;
286 }
287 
289 {
290  m_defaultUserOpaque = UserOpaque;
291 }
292 
294 {
295  return m_defaultFree;
296 }
297 
299 {
300  return m_defaultUserOpaque;
301 }
FMT_MEDIACODEC
@ FMT_MEDIACODEC
Definition: mythframe.h:56
mythvaapiinterop.h
ReferenceCounter::DecrRef
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
Definition: referencecounter.cpp:125
MythOpenGLInterop::CreateDummy
static MythOpenGLInterop * CreateDummy(void)
Definition: mythopenglinterop.cpp:228
mythplayerui.h
MythVTBInterop::GetInteropType
static Type GetInteropType(VideoFrameType Format)
Definition: mythvtbinterop.cpp:9
mythvdpauinterop.h
MythVideoTexture::DeleteTexture
static void DeleteTexture(MythRenderOpenGL *Context, MythVideoTexture *Texture)
Definition: mythvideotexture.cpp:17
FMT_VTB
@ FMT_VTB
Definition: mythframe.h:57
FMT_DRMPRIME
@ FMT_DRMPRIME
Definition: mythframe.h:59
MythOpenGLInterop::m_defaultUserOpaque
void * m_defaultUserOpaque
Definition: mythopenglinterop.h:79
mythopenglinterop.h
MythOpenGLInterop::GetType
Type GetType(void)
Definition: mythopenglinterop.cpp:268
MythOpenGLInterop::SetDefaultFree
void SetDefaultFree(FreeAVHWDeviceContext FreeContext)
Definition: mythopenglinterop.cpp:283
Frame
Definition: zmdefines.h:94
MythOpenGLInterop::Acquire
virtual vector< MythVideoTexture * > Acquire(MythRenderOpenGL *Context, MythVideoColourSpace *ColourSpace, MythVideoFrame *Frame, FrameScanType Scan)
Definition: mythopenglinterop.cpp:237
arg
arg(title).arg(filename).arg(doDelete))
FrameScanType
FrameScanType
Definition: videoouttypes.h:95
MythCoreContext::IsUIThread
bool IsUIThread(void)
Definition: mythcorecontext.cpp:1357
Context
QHash< QString, Action * > Context
Definition: action.h:77
MythDate::Format
Format
Definition: mythdate.h:13
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MythOpenGLInterop::m_player
MythPlayerUI * m_player
Definition: mythopenglinterop.h:80
MythMMALInterop::GetInteropType
static Type GetInteropType(VideoFrameType Format)
Definition: mythmmalinterop.cpp:25
MythVideoFrame::HardwareFormat
static bool HardwareFormat(VideoFrameType Type)
Definition: mythframe.h:408
MythOpenGLInterop::SetDefaultUserOpaque
void SetDefaultUserOpaque(void *UserOpaque)
Definition: mythopenglinterop.cpp:288
MythOpenGLInterop::DUMMY
@ DUMMY
Definition: mythopenglinterop.h:42
MythOpenGLInterop::~MythOpenGLInterop
~MythOpenGLInterop() override
Definition: mythopenglinterop.cpp:221
true
VERBOSE_PREAMBLE Most true
Definition: verbosedefs.h:91
MythOpenGLInterop::m_type
Type m_type
Definition: mythopenglinterop.h:74
MythOpenGLInterop::VDPAU
@ VDPAU
Definition: mythopenglinterop.h:38
MythOpenGLInterop::Retrieve
static vector< MythVideoTexture * > Retrieve(MythRenderOpenGL *Context, MythVideoColourSpace *ColourSpace, MythVideoFrame *Frame, FrameScanType Scan)
Definition: mythopenglinterop.cpp:162
mythrenderopengl.h
MythPlayerUI
Definition: mythplayerui.h:11
mythvideocolourspace.h
MythNVDECInterop::GetInteropType
static Type GetInteropType(VideoFrameType Format)
Definition: mythnvdecinterop.cpp:85
MythOpenGLInterop::SetPlayer
void SetPlayer(MythPlayerUI *Player)
Definition: mythopenglinterop.cpp:278
MythOpenGLInterop
Definition: mythopenglinterop.h:24
MythOpenGLInterop::Unsupported
@ Unsupported
Definition: mythopenglinterop.h:31
MythVDPAUInterop::GetInteropType
static Type GetInteropType(VideoFrameType Format)
Definition: mythvdpauinterop.cpp:16
MythOpenGLInterop::MMAL
@ MMAL
Definition: mythopenglinterop.h:40
MythOpenGLInterop::NVDEC
@ NVDEC
Definition: mythopenglinterop.h:39
MythOpenGLInterop::GetAllowedRenderers
static QStringList GetAllowedRenderers(VideoFrameType Format)
Definition: mythopenglinterop.cpp:51
MythOpenGLInterop::GetInteropTypeCallback
static void GetInteropTypeCallback(void *Wait, void *Format, void *Result)
Definition: mythopenglinterop.cpp:59
MythOpenGLInterop::MythOpenGLInterop
MythOpenGLInterop(MythRenderOpenGL *Context, Type InteropType)
Definition: mythopenglinterop.cpp:212
MythOpenGLInterop::GetInteropType
static Type GetInteropType(VideoFrameType Format, MythPlayerUI *Player)
Check whether we support direct rendering for the given VideoFrameType.
Definition: mythopenglinterop.cpp:74
MythOpenGLInterop::GetDefaultFree
FreeAVHWDeviceContext GetDefaultFree(void)
Definition: mythopenglinterop.cpp:293
mythvtbinterop.h
mythmmalinterop.h
MythOpenGLInterop::MEDIACODEC
@ MEDIACODEC
Definition: mythopenglinterop.h:37
MythOpenGLInterop::m_context
MythRenderOpenGL * m_context
Definition: mythopenglinterop.h:73
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:60
MythOpenGLInterop::VAAPIGLXCOPY
@ VAAPIGLXCOPY
Definition: mythopenglinterop.h:32
mythmediacodeccontext.h
MythOpenGLInterop::Type
Type
Definition: mythopenglinterop.h:30
MythOpenGLInterop::DRMPRIME
@ DRMPRIME
Definition: mythopenglinterop.h:41
MythAVUtil::PixelFormatToFrameType
static VideoFrameType PixelFormatToFrameType(AVPixelFormat Fmt)
Definition: mythavutil.cpp:74
MythDRMPRIMEInterop::GetInteropType
static Type GetInteropType(VideoFrameType Format)
Definition: mythdrmprimeinterop.cpp:58
MythOpenGLInterop::VTBOPENGL
@ VTBOPENGL
Definition: mythopenglinterop.h:35
LOC
#define LOC
Definition: mythopenglinterop.cpp:33
MythOpenGLInterop::VAAPIGLXPIX
@ VAAPIGLXPIX
Definition: mythopenglinterop.h:33
FMT_NVDEC
@ FMT_NVDEC
Definition: mythframe.h:58
MythOpenGLInterop::VTBSURFACE
@ VTBSURFACE
Definition: mythopenglinterop.h:36
MythRenderOpenGL
Definition: mythrenderopengl.h:99
MythOpenGLInterop::GetPlayer
MythPlayerUI * GetPlayer(void)
Definition: mythopenglinterop.cpp:273
MythVideoFrame::FormatDescription
static QString FormatDescription(VideoFrameType Type)
Definition: mythframe.cpp:363
mythcorecontext.h
FMT_VDPAU
@ FMT_VDPAU
Definition: mythframe.h:52
MythVAAPIInterop::GetInteropType
static Type GetInteropType(VideoFrameType Format)
Return an 'interoperability' method that is supported by the current render device.
Definition: mythvaapiinterop.cpp:31
MythOpenGLInterop::VAAPIEGLDRM
@ VAAPIEGLDRM
Definition: mythopenglinterop.h:34
MythOpenGLInterop::m_defaultFree
FreeAVHWDeviceContext m_defaultFree
Definition: mythopenglinterop.h:78
mythdrmprimeinterop.h
FreeAVHWDeviceContext
void(*)(struct AVHWDeviceContext *) FreeAVHWDeviceContext
Definition: mythopenglinterop.h:20
mythnvdecinterop.h
MythOpenGLInterop::TypeToString
static QString TypeToString(Type InteropType)
Definition: mythopenglinterop.cpp:35
FMT_MMAL
@ FMT_MMAL
Definition: mythframe.h:55
VideoFrameType
VideoFrameType
Definition: mythframe.h:16
FMT_VAAPI
@ FMT_VAAPI
Definition: mythframe.h:53
Player
Definition: zmliveplayer.h:35
MythVideoFrame
Definition: mythframe.h:83
MythOpenGLInterop::DeleteTextures
virtual void DeleteTextures(void)
Definition: mythopenglinterop.cpp:244
MythOpenGLInterop::m_openglTextures
QHash< unsigned long long, vector< MythVideoTexture * > > m_openglTextures
Definition: mythopenglinterop.h:75
ReferenceCounter::IncrRef
virtual int IncrRef(void)
Increments reference count.
Definition: referencecounter.cpp:101
MythOpenGLInterop::GetDefaultUserOpaque
void * GetDefaultUserOpaque(void)
Definition: mythopenglinterop.cpp:298
MythVideoColourSpace
MythVideoColourSpace contains a QMatrix4x4 that can convert YCbCr data to RGB.
Definition: mythvideocolourspace.h:21
ReferenceCounter
General purpose reference counter.
Definition: referencecounter.h:27
OpenGLLocker
Definition: mythrenderopengl.h:255