MythTV  master
mythopenglinterop.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QWaitCondition>
3 
4 // MythTV
5 #include "mythplayer.h"
6 #include "mythcorecontext.h"
7 #include "videocolourspace.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 
78 {
79  // cache supported formats to avoid potentially expensive callbacks
80  static QMutex s_lock(QMutex::Recursive);
81  static QHash<VideoFrameType,Type> s_supported;
82 
83  Type supported = Unsupported;
84  bool alreadychecked = false;
85 
86  // have we checked this format already
87  s_lock.lock();
88  if (s_supported.contains(Format))
89  {
90  supported = s_supported.value(Format);
91  alreadychecked = true;
92  }
93  s_lock.unlock();
94 
95  // need to check
96  if (!alreadychecked)
97  {
98  if (!gCoreContext->IsUIThread())
99  {
100  if (!Player)
101  {
102  LOG(VB_GENERAL, LOG_ERR, LOC +
103  "GetInteropType called from another thread without player");
104  }
105  else
106  {
107  Player->HandleDecoderCallback("interop check",
109  &Format, &supported);
110  }
111  return supported;
112  }
113 
114  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Checking interop support for %1")
116 
117 #ifdef USING_VTB
118  if (FMT_VTB == Format)
120 #endif
121 #ifdef USING_VAAPI
122  if (FMT_VAAPI == Format)
124 #endif
125 #ifdef USING_MEDIACODEC
126  if (FMT_MEDIACODEC == Format)
127  supported = MEDIACODEC;
128 #endif
129 #ifdef USING_VDPAU
130  if (FMT_VDPAU == Format)
132 #endif
133 #ifdef USING_NVDEC
134  if (FMT_NVDEC == Format)
136 #endif
137 #ifdef USING_MMAL
138  if (FMT_MMAL == Format)
140 #endif
141 #ifdef USING_EGL
142  if (FMT_DRMPRIME == Format)
144 #endif
145  // update supported formats
146  s_lock.lock();
147  s_supported.insert(Format, supported);
148  s_lock.unlock();
149  }
150 
151  if (Unsupported == supported)
152  {
153  LOG(VB_GENERAL, LOG_WARNING, LOC + QString("No render support for frame type '%1'")
155  }
156  else
157  {
158  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Rendering supported for frame type '%1' with %2")
159  .arg(format_description(Format)).arg(TypeToString(supported)));
160  }
161  return supported;
162 }
163 
165  VideoColourSpace *ColourSpace,
166  VideoFrame *Frame,
167  FrameScanType Scan)
168 {
169  vector<MythVideoTexture*> result;
170  if (!(Context && Frame))
171  return result;
172 
173  if (!(Frame->priv[1] && format_is_hw(Frame->codec) &&
174  (Frame->codec == PixelFormatToFrameType(static_cast<AVPixelFormat>(Frame->pix_fmt)))))
175  {
176  LOG(VB_GENERAL, LOG_WARNING, LOC + "Not a valid hardware frame");
177  return result;
178  }
179 
180  MythOpenGLInterop* interop = nullptr;
181  if ((Frame->codec == FMT_VTB) || (Frame->codec == FMT_MEDIACODEC) ||
182  (Frame->codec == FMT_MMAL) || (Frame->codec == FMT_DRMPRIME))
183  {
184  interop = reinterpret_cast<MythOpenGLInterop*>(Frame->priv[1]);
185  }
186  else
187  {
188  // Unpick
189  auto* buffer = reinterpret_cast<AVBufferRef*>(Frame->priv[1]);
190  if (!buffer || (buffer && !buffer->data))
191  return result;
192  if (Frame->codec == FMT_NVDEC)
193  {
194  auto* context = reinterpret_cast<AVHWDeviceContext*>(buffer->data);
195  if (!context || (context && !context->user_opaque))
196  return result;
197  interop = reinterpret_cast<MythOpenGLInterop*>(context->user_opaque);
198  }
199  else
200  {
201  auto* frames = reinterpret_cast<AVHWFramesContext*>(buffer->data);
202  if (!frames || (frames && !frames->user_opaque))
203  return result;
204  interop = reinterpret_cast<MythOpenGLInterop*>(frames->user_opaque);
205  }
206  }
207 
208  if (interop)
209  return interop->Acquire(Context, ColourSpace, Frame, Scan);
210  LOG(VB_GENERAL, LOG_ERR, LOC + "No OpenGL interop found");
211  return result;
212 }
213 
215  : ReferenceCounter("GLInterop", true),
216  m_context(Context),
217  m_type(InteropType)
218 {
219  if (m_context)
220  m_context->IncrRef();
221 }
222 
224 {
226  if (m_context)
227  m_context->DecrRef();
228 }
229 
231 {
232  // This is used to store AVHWDeviceContext free and user_opaque when
233  // set by the decoder in use. This usually applies to VAAPI and VDPAU
234  // and we do not always want or need to use MythRenderOpenGL e.g. when
235  // checking functionality only.
236  return new MythOpenGLInterop(nullptr, DUMMY);
237 }
238 
239 vector<MythVideoTexture*> MythOpenGLInterop::Acquire(MythRenderOpenGL* /*Context*/,
240  VideoColourSpace* /*ColourSpace*/,
241  VideoFrame* /*Frame*/, FrameScanType /*Scan*/)
242 {
243  return vector<MythVideoTexture*>();
244 }
245 
247 {
248  if (m_context && !m_openglTextures.isEmpty())
249  {
250  OpenGLLocker locker(m_context);
251  int count = 0;
252  for (auto it = m_openglTextures.constBegin(); it != m_openglTextures.constEnd(); ++it)
253  {
254  vector<MythVideoTexture*> textures = it.value();
255  for (auto & texture : textures)
256  {
257  if (texture->m_textureId)
258  m_context->glDeleteTextures(1, &texture->m_textureId);
260  count++;
261  }
262  textures.clear();
263  }
264  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Deleted %1 textures in %2 groups")
265  .arg(count).arg(m_openglTextures.size()));
266  m_openglTextures.clear();
267  }
268 }
269 
271 {
272  return m_type;
273 }
274 
276 {
277  return m_player;
278 }
279 
281 {
282  m_player = Player;
283 }
284 
286 {
287  m_defaultFree = FreeContext;
288 }
289 
291 {
292  m_defaultUserOpaque = UserOpaque;
293 }
294 
296 {
297  return m_defaultFree;
298 }
299 
301 {
302  return m_defaultUserOpaque;
303 }
FMT_MEDIACODEC
@ FMT_MEDIACODEC
Definition: mythframe.h:65
mythvaapiinterop.h
MythOpenGLInterop::GetPlayer
MythPlayer * GetPlayer(void)
Definition: mythopenglinterop.cpp:275
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:230
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:66
MythOpenGLInterop::m_player
MythPlayer * m_player
Definition: mythopenglinterop.h:80
FMT_DRMPRIME
@ FMT_DRMPRIME
Definition: mythframe.h:68
MythOpenGLInterop::m_defaultUserOpaque
void * m_defaultUserOpaque
Definition: mythopenglinterop.h:79
mythopenglinterop.h
MythOpenGLInterop::GetType
Type GetType(void)
Definition: mythopenglinterop.cpp:270
MythOpenGLInterop::SetDefaultFree
void SetDefaultFree(FreeAVHWDeviceContext FreeContext)
Definition: mythopenglinterop.cpp:285
Frame
Definition: zmdefines.h:93
MythOpenGLInterop::Acquire
virtual vector< MythVideoTexture * > Acquire(MythRenderOpenGL *Context, VideoColourSpace *ColourSpace, VideoFrame *Frame, FrameScanType Scan)
Definition: mythopenglinterop.cpp:239
arg
arg(title).arg(filename).arg(doDelete))
PixelFormatToFrameType
VideoFrameType PixelFormatToFrameType(AVPixelFormat fmt)
Definition: mythavutil.cpp:69
FrameScanType
FrameScanType
Definition: videoouttypes.h:78
MythCoreContext::IsUIThread
bool IsUIThread(void)
Definition: mythcorecontext.cpp:1329
MythOpenGLInterop::SetPlayer
void SetPlayer(MythPlayer *Player)
Definition: mythopenglinterop.cpp:280
Context
QHash< QString, Action * > Context
Definition: action.h:77
MythDate::Format
Format
Definition: mythdate.h:12
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MythMMALInterop::GetInteropType
static Type GetInteropType(VideoFrameType Format)
Definition: mythmmalinterop.cpp:25
mythplayer.h
MythPlayer
Definition: mythplayer.h:164
VideoFrame
Definition: mythframe.h:137
MythOpenGLInterop::SetDefaultUserOpaque
void SetDefaultUserOpaque(void *UserOpaque)
Definition: mythopenglinterop.cpp:290
MythOpenGLInterop::DUMMY
@ DUMMY
Definition: mythopenglinterop.h:42
MythOpenGLInterop::~MythOpenGLInterop
~MythOpenGLInterop() override
Definition: mythopenglinterop.cpp:223
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
mythrenderopengl.h
MythNVDECInterop::GetInteropType
static Type GetInteropType(VideoFrameType Format)
Definition: mythnvdecinterop.cpp:85
format_is_hw
static bool format_is_hw(VideoFrameType Type)
Definition: mythframe.h:73
MythOpenGLInterop
Definition: mythopenglinterop.h:23
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:214
MythOpenGLInterop::GetDefaultFree
FreeAVHWDeviceContext GetDefaultFree(void)
Definition: mythopenglinterop.cpp:295
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:57
MythOpenGLInterop::VAAPIGLXCOPY
@ VAAPIGLXCOPY
Definition: mythopenglinterop.h:32
mythmediacodeccontext.h
videocolourspace.h
MythOpenGLInterop::Type
Type
Definition: mythopenglinterop.h:29
MythOpenGLInterop::DRMPRIME
@ DRMPRIME
Definition: mythopenglinterop.h:41
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:67
MythOpenGLInterop::VTBSURFACE
@ VTBSURFACE
Definition: mythopenglinterop.h:36
MythRenderOpenGL
Definition: mythrenderopengl.h:86
VideoColourSpace
VideoColourSpace contains a QMatrix4x4 that can convert YCbCr data to RGB.
Definition: videocolourspace.h:17
MythOpenGLInterop::Retrieve
static vector< MythVideoTexture * > Retrieve(MythRenderOpenGL *Context, VideoColourSpace *ColourSpace, VideoFrame *Frame, FrameScanType Scan)
Definition: mythopenglinterop.cpp:164
mythcorecontext.h
FMT_VDPAU
@ FMT_VDPAU
Definition: mythframe.h:61
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:64
VideoFrameType
VideoFrameType
Definition: mythframe.h:24
FMT_VAAPI
@ FMT_VAAPI
Definition: mythframe.h:62
Player
Definition: zmliveplayer.h:35
MythOpenGLInterop::DeleteTextures
virtual void DeleteTextures(void)
Definition: mythopenglinterop.cpp:246
MythOpenGLInterop::GetInteropType
static Type GetInteropType(VideoFrameType Format, MythPlayer *Player)
Check whether we support direct rendering for the given VideoFrameType.
Definition: mythopenglinterop.cpp:77
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
format_description
const char * format_description(VideoFrameType Type)
Definition: mythframe.cpp:33
MythOpenGLInterop::GetDefaultUserOpaque
void * GetDefaultUserOpaque(void)
Definition: mythopenglinterop.cpp:300
ReferenceCounter
General purpose reference counter.
Definition: referencecounter.h:26
OpenGLLocker
Definition: mythrenderopengl.h:244