MythTV  master
mythvideooutopengl.cpp
Go to the documentation of this file.
1 // C/C++
2 #include <utility>
3 
4 // MythTV
5 #include "libmyth/mythcontext.h"
11 
13 #include "mythplayer.h"
14 #include "mythvideoprofile.h"
16 #include "opengl/mythopenglvideo.h"
18 #include "osd.h"
19 
20 #define LOC QString("VidOutGL: ")
21 
29 {
30  QStringList safe;
31  safe << "opengl" << "opengl-yv12";
32 
33  // all profiles can handle all software frames
34  (*Options.safe_renderers)["dummy"].append(safe);
35  if (Options.decoders->contains("ffmpeg"))
36  (*Options.safe_renderers)["ffmpeg"].append(safe);
37  if (Options.decoders->contains("mediacodec-dec"))
38  (*Options.safe_renderers)["mediacodec-dec"].append(safe);
39  if (Options.decoders->contains("vaapi-dec"))
40  (*Options.safe_renderers)["vaapi-dec"].append(safe);
41  if (Options.decoders->contains("vdpau-dec"))
42  (*Options.safe_renderers)["vdpau-dec"].append(safe);
43  if (Options.decoders->contains("nvdec-dec"))
44  (*Options.safe_renderers)["nvdec-dec"].append(safe);
45  if (Options.decoders->contains("vtb-dec"))
46  (*Options.safe_renderers)["vtb-dec"].append(safe);
47  if (Options.decoders->contains("v4l2-dec"))
48  (*Options.safe_renderers)["v4l2-dec"].append(safe);
49  if (Options.decoders->contains("mmal-dec"))
50  (*Options.safe_renderers)["mmal-dec"].append(safe);
51 
52  // OpenGL UYVY
53  Options.renderers->append("opengl");
54  Options.priorities->insert("opengl", 65);
55 
56  // OpenGL YV12
57  Options.renderers->append("opengl-yv12");
58  Options.priorities->insert("opengl-yv12", 65);
59 
60 #if defined(USING_VAAPI) || defined (USING_VTB) || defined (USING_MEDIACODEC) || defined (USING_VDPAU) || defined (USING_NVDEC) || defined (USING_MMAL) || defined (USING_V4L2PRIME) || defined (USING_EGL)
61  Options.renderers->append("opengl-hw");
62  (*Options.safe_renderers)["dummy"].append("opengl-hw");
63  Options.priorities->insert("opengl-hw", 110);
64 #endif
65 #ifdef USING_VAAPI
66  if (Options.decoders->contains("vaapi"))
67  (*Options.safe_renderers)["vaapi"].append("opengl-hw");
68 #endif
69 #ifdef USING_VTB
70  if (Options.decoders->contains("vtb"))
71  (*Options.safe_renderers)["vtb"].append("opengl-hw");
72 #endif
73 #ifdef USING_MEDIACODEC
74  if (Options.decoders->contains("mediacodec"))
75  (*Options.safe_renderers)["mediacodec"].append("opengl-hw");
76 #endif
77 #ifdef USING_VDPAU
78  if (Options.decoders->contains("vdpau"))
79  (*Options.safe_renderers)["vdpau"].append("opengl-hw");
80 #endif
81 #ifdef USING_NVDEC
82  if (Options.decoders->contains("nvdec"))
83  (*Options.safe_renderers)["nvdec"].append("opengl-hw");
84 #endif
85 #ifdef USING_MMAL
86  if (Options.decoders->contains("mmal"))
87  (*Options.safe_renderers)["mmal"].append("opengl-hw");
88 #endif
89 #ifdef USING_V4L2PRIME
90  if (Options.decoders->contains("v4l2"))
91  (*Options.safe_renderers)["v4l2"].append("opengl-hw");
92 #endif
93 #ifdef USING_EGL
94  if (Options.decoders->contains("drmprime"))
95  (*Options.safe_renderers)["drmprime"].append("opengl-hw");
96 #endif
97 }
98 
100  MythRenderOpenGL* Render,
101  MythOpenGLPainter* Painter,
102  MythDisplay *Display,
103  const MythVideoProfilePtr& VideoProfile,
104  QString &Profile)
105  : MythVideoOutputGPU(MainWindow, Render, Painter, Display, VideoProfile, Profile),
106  m_openglRender(Render)
107 {
108  // Complete list of formats supported for OpenGL 2.0 and higher and OpenGL ES3.X
109  static VideoFrameTypes s_openglRenderFormats =
110  {
116  };
117 
118  // OpenGL ES 2.0 and OpenGL1.X only allow luminance textures
119  static VideoFrameTypes s_openglRenderFormatsLegacy =
120  {
122  };
123 
124  // Retrieve render context
125  if (!m_openglRender)
126  {
127  LOG(VB_GENERAL, LOG_ERR, LOC + "No OpenGL context");
128  return;
129  }
130 
132 
133  // Enable performance monitoring if requested
134  // This will report the execution time for the key GL code blocks
135  // N.B. 'Upload' should always be zero when using hardware decoding and direct
136  // rendering. Any copy cost for direct rendering will be included within 'Render'
137  if (VERBOSE_LEVEL_CHECK(VB_GPUVIDEO, LOG_INFO))
138  {
139  m_openGLPerf = new MythOpenGLPerf("GLVidPerf: ", { "Upload:", "Clear:", "Render:", "Flush:", "Swap:" });
140  if (!m_openGLPerf->isCreated())
141  {
142  delete m_openGLPerf;
143  m_openGLPerf = nullptr;
144  }
145  }
146 
147  // Disallow unsupported video texturing on GLES2/GL1.X
149  m_renderFormats = &s_openglRenderFormatsLegacy;
150  else
151  m_renderFormats = &s_openglRenderFormats;
152 
153  if (!qobject_cast<MythOpenGLPainter*>(m_painter))
154  LOG(VB_GENERAL, LOG_ERR, LOC + "No OpenGL painter");
155 
156  // Create OpenGLVideo
158  if (m_video)
159  {
161  if (!m_video->IsValid())
162  {
163  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create valid OpenGL video");
164  delete m_video;
165  m_video = nullptr;
166  }
167  }
168 }
169 
171 {
172  if (m_openglRender)
173  {
175  delete m_openGLPerf;
177  }
178 }
179 
180 bool MythVideoOutputOpenGL::Init(const QSize VideoDim, const QSize VideoDispDim,
181  float Aspect, const QRect DisplayVisibleRect, MythCodecID CodecId)
182 {
183  if (!(m_openglRender && m_painter && m_video))
184  {
185  LOG(VB_GENERAL, LOG_ERR, LOC + "Fatal error");
186  return false;
187  }
188 
189  if (!gCoreContext->IsUIThread())
190  {
191  LOG(VB_GENERAL, LOG_ERR, LOC + "Cannot initialise OpenGL video from this thread");
192  return false;
193  }
194 
195  OpenGLLocker ctx_lock(m_openglRender);
196 
197  if (!MythVideoOutputGPU::Init(VideoDim, VideoDispDim, Aspect, DisplayVisibleRect, CodecId))
198  return false;
199 
200  // This works around an issue with VDPAU direct rendering using legacy drivers
202 
203  return true;
204 }
205 
208 {
209  QRect dvr = GetDisplayVisibleRect();
210  if (!m_mainWindow)
211  return dvr;
212 
213  QSize size = m_mainWindow->size();
214 
215  // may be called before m_window is initialised fully
216  if (dvr.isEmpty())
217  dvr = QRect(QPoint(0, 0), size);
218 
219  // If the Video screen mode has vertically less pixels
220  // than the GUI screen mode - OpenGL coordinate adjustments
221  // must be made to put the video at the top of the display
222  // area instead of at the bottom.
223  if (dvr.height() < size.height())
224  dvr.setTop(dvr.top() - size.height() + dvr.height());
225 
226  // If the Video screen mode has horizontally less pixels
227  // than the GUI screen mode - OpenGL width must be set
228  // as the higher GUI width so that the Program Guide
229  // invoked from playback is not cut off.
230  if (dvr.width() < size.width())
231  dvr.setWidth(size.width());
232 
233  return dvr;
234 }
235 
237 {
238  if (!m_openglRender)
239  return;
240 
241  // Lock
242  OpenGLLocker ctx_lock(m_openglRender);
243 
244  // Start the first timer
245  if (m_openGLPerf)
247 
248  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
249  m_openglRender->logDebugMarker(LOC + "PROCESS_FRAME_START");
250 
251  // Update software frames
253 
254  // Time texture update
255  if (m_openGLPerf)
257 
258  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
259  m_openglRender->logDebugMarker(LOC + "PROCESS_FRAME_END");
260 }
261 
263 {
264  if (!m_openglRender)
265  return;
266 
267  // Input changes need to be handled in ProcessFrame
268  if (m_newCodecId != kCodec_NONE)
269  return;
270 
271  // Lock
272  OpenGLLocker ctx_lock(m_openglRender);
273 
274  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
275  m_openglRender->logDebugMarker(LOC + "RENDER_FRAME_START");
276 
277  // If process frame has not been called (double rate hardware deint), then
278  // we need to start the first 2 performance timers here
279  if (m_openGLPerf)
280  {
282  {
285  }
286  }
287 
289 
290  // Clear framebuffer
291  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
292  m_openglRender->logDebugMarker(LOC + "CLEAR_START");
293 
294  if (!Frame || Frame->m_dummy || m_needFullClear || ((m_openglRender->GetExtraFeatures() & kGLTiled) != 0))
295  {
298  }
299  // Avoid clearing the framebuffer if it will be entirely overwritten by video
300  else if (!VideoIsFullScreen())
301  {
302  if (IsEmbedding())
303  {
304  // use MythRenderOpenGL rendering as it will clear to the appropriate 'black level'
306  }
307  else
308  {
309  // in the vast majority of cases it is significantly quicker to just
310  // clear the unused portions of the screen
311  QRegion toclear = GetBoundingRegion();
312  for (const auto& rect : qAsConst(toclear))
314  }
315  }
316 
317  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
318  m_openglRender->logDebugMarker(LOC + "CLEAR_END");
319 
320  // Time framebuffer clearing
321  if (m_openGLPerf)
323 
324  // Render
326 
327  // Time rendering
328  if (m_openGLPerf)
330 
331  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
332  m_openglRender->logDebugMarker(LOC + "RENDER_FRAME_END");
333 }
334 
336 {
337  // Flush and time
339  if (m_openGLPerf)
341 }
342 
344 {
345  if (!m_openglRender || IsErrored())
346  return;
347 
349 
350  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
351  m_openglRender->logDebugMarker(LOC + "SHOW");
352 
354 
355  if (m_openGLPerf)
356  {
357  // Time buffer swap and log
358  // Results will normally be available on the next pass - and we will typically
359  // test every other frame as a result to avoid blocking in the driver.
360  // With the default of averaging over 30 samples this should give a 30 sample
361  // average over 60 frames
364  }
365 
367 }
368 
371 QStringList MythVideoOutputOpenGL::GetAllowedRenderers(MythRenderOpenGL *Render, MythCodecID CodecId, QSize /*VideoDim*/)
372 {
373  QStringList allowed;
374  if (!Render)
375  return allowed;
376 
377  if (codec_sw_copy(CodecId))
378  {
379  allowed << "opengl" << "opengl-yv12";
380  return allowed;
381  }
382 
383  if (auto format = FrameTypeForCodec(CodecId); FMT_NONE != format)
384  {
385  MythInteropGPU::InteropMap supported;
386  if (MythOpenGLInterop::GetTypes(Render, supported); supported.find(format) != supported.cend())
387  allowed << "opengl-hw";
388  }
389  return allowed;
390 }
MythOpenGLPainter
Definition: mythpainteropengl.h:28
MythVideoBounds::IsEmbedding
bool IsEmbedding(void) const
Definition: mythvideobounds.h:68
FMT_YUV420P10
@ FMT_YUV420P10
Definition: mythframe.h:26
MythRenderOpenGL::SetBackground
void SetBackground(uint8_t Red, uint8_t Green, uint8_t Blue, uint8_t Alpha)
Definition: mythrenderopengl.cpp:618
FMT_YUV420P16
@ FMT_YUV420P16
Definition: mythframe.h:29
RenderOptions::renderers
QStringList * renderers
Definition: mythvideoprofile.h:47
FMT_YUV420P14
@ FMT_YUV420P14
Definition: mythframe.h:28
MythRenderOpenGL::ClearFramebuffer
void ClearFramebuffer(void)
Definition: mythrenderopengl.cpp:805
kCodec_NONE
@ kCodec_NONE
Definition: mythcodecid.h:14
MythRenderOpenGL::ClearRect
void ClearRect(QOpenGLFramebufferObject *Target, QRect Area, int Color, int Alpha)
An optimised method to clear a QRect to the given color.
Definition: mythrenderopengl.cpp:959
FMT_YUV444P10
@ FMT_YUV444P10
Definition: mythframe.h:46
MythVideoOutputOpenGL::EndFrame
void EndFrame() override
Definition: mythvideooutopengl.cpp:343
FMT_YUV422P14
@ FMT_YUV422P14
Definition: mythframe.h:41
mythopenglinterop.h
MythVideoBounds::GetDisplayVisibleRect
QRect GetDisplayVisibleRect(void) const
Definition: mythvideobounds.h:73
MythVideoGPU::IsValid
bool IsValid() const
Definition: mythvideogpu.cpp:73
Frame
Definition: zmdefines.h:93
MythVideoOutputOpenGL::Init
bool Init(QSize VideoDim, QSize VideoDispDim, float Aspect, QRect DisplayVisibleRect, MythCodecID CodecId) override
Definition: mythvideooutopengl.cpp:180
FMT_P010
@ FMT_P010
Definition: mythframe.h:54
MythRenderOpenGL::logDebugMarker
void logDebugMarker(const QString &Message)
Definition: mythrenderopengl.cpp:193
VERBOSE_LEVEL_CHECK
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
Definition: mythlogging.h:29
MythOpenGLPerf::GetTimersRunning
int GetTimersRunning(void) const
Definition: mythopenglperf.cpp:34
FrameScanType
FrameScanType
Definition: videoouttypes.h:94
MythVideoOutputOpenGL::GetRenderOptions
static void GetRenderOptions(RenderOptions &Options)
Generate the list of available OpenGL profiles.
Definition: mythvideooutopengl.cpp:28
osd.h
MythCoreContext::IsUIThread
bool IsUIThread(void)
Definition: mythcorecontext.cpp:1347
FMT_YUV422P
@ FMT_YUV422P
Definition: mythframe.h:37
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythVideoOutputGPU::m_profile
QString m_profile
Definition: mythvideooutgpu.h:78
mythplayer.h
kGLLegacyTextures
@ kGLLegacyTextures
Definition: mythrenderopengl.h:51
MythVideoOutputOpenGL::m_openglRender
MythRenderOpenGL * m_openglRender
Definition: mythvideooutopengl.h:42
MythOpenGLPerf::LogSamples
void LogSamples(void)
Definition: mythopenglperf.cpp:48
codec_sw_copy
static bool codec_sw_copy(MythCodecID id)
Definition: mythcodecid.h:371
MythVideoOutputOpenGL::GetAllowedRenderers
static QStringList GetAllowedRenderers(MythRenderOpenGL *Render, MythCodecID CodecId, QSize VideoDim)
Generate a list of supported OpenGL profiles.
Definition: mythvideooutopengl.cpp:371
mythopenglvideo.h
FMT_YUV444P14
@ FMT_YUV444P14
Definition: mythframe.h:48
MythVideoOutputGPU::Init
bool Init(QSize VideoDim, QSize VideoDispDim, float Aspect, QRect DisplayVisibleRect, MythCodecID CodecId) override
Definition: mythvideooutgpu.cpp:287
FMT_YUV444P
@ FMT_YUV444P
Definition: mythframe.h:44
FMT_NONE
@ FMT_NONE
Definition: mythframe.h:22
MythInteropGPU::InteropMap
std::map< VideoFrameType, InteropTypes > InteropMap
Definition: mythinteropgpu.h:44
MythVideoOutputOpenGL::GetDisplayVisibleRectAdj
QRect GetDisplayVisibleRectAdj() override
Adjust the display rectangle for OpenGL coordinates in some cases.
Definition: mythvideooutopengl.cpp:207
MythCodecID
MythCodecID
Definition: mythcodecid.h:10
mythrenderopengl.h
MythVideoOutputGPU::m_mainWindow
MythMainWindow * m_mainWindow
Definition: mythvideooutgpu.h:68
RenderOptions::decoders
QStringList * decoders
Definition: mythvideoprofile.h:51
RenderOptions
Definition: mythvideoprofile.h:45
MythVideoOutput::m_clearAlpha
uint8_t m_clearAlpha
Definition: mythvideoout.h:97
MythRenderOpenGL::Flush
void Flush(void)
Definition: mythrenderopengl.cpp:597
FMT_YUV444P9
@ FMT_YUV444P9
Definition: mythframe.h:45
FMT_YV12
@ FMT_YV12
Definition: mythframe.h:24
FMT_YUV422P10
@ FMT_YUV422P10
Definition: mythframe.h:39
FMT_YUV444P16
@ FMT_YUV444P16
Definition: mythframe.h:49
MythVideoOutputOpenGL::m_openGLPerf
MythOpenGLPerf * m_openGLPerf
Definition: mythvideooutopengl.h:43
VideoFrameTypes
std::vector< VideoFrameType > VideoFrameTypes
Definition: mythframe.h:83
MythVideoOutputGPU::m_newCodecId
MythCodecID m_newCodecId
Definition: mythvideooutgpu.h:72
MythVideoOutput::m_videoProfile
MythVideoProfilePtr m_videoProfile
Definition: mythvideoout.h:100
MythVideoGPU::SetViewportRect
void SetViewportRect(QRect DisplayVisibleRect)
Definition: mythvideogpu.cpp:132
FMT_YUV420P12
@ FMT_YUV420P12
Definition: mythframe.h:27
RenderOptions::safe_renderers
QMap< QString, QStringList > * safe_renderers
Definition: mythvideoprofile.h:48
LOC
#define LOC
Definition: mythvideooutopengl.cpp:20
MythRenderOpenGL::swapBuffers
void swapBuffers()
Definition: mythrenderopengl.cpp:511
MythRenderOpenGL::makeCurrent
void makeCurrent()
Definition: mythrenderopengl.cpp:566
mythopenglperf.h
MythRenderOpenGL::GetExtraFeatures
int GetExtraFeatures(void) const
Definition: mythrenderopengl.cpp:455
mythvideoprofile.h
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
MythDisplay
Definition: mythdisplay.h:22
MythVideoOutputGPU::PrepareFrame
void PrepareFrame(MythVideoFrame *Frame, FrameScanType Scan) override
Definition: mythvideooutgpu.cpp:587
MythOpenGLPerf
A simple overload of QOpenGLTimeMonitor to record and log OpenGL execution intervals.
Definition: mythopenglperf.h:37
FMT_YUV444P12
@ FMT_YUV444P12
Definition: mythframe.h:47
MythVideoOutputGPU::m_needFullClear
bool m_needFullClear
Definition: mythvideooutgpu.h:79
MythVideoOutputGPU::FrameTypeForCodec
static VideoFrameType FrameTypeForCodec(MythCodecID CodecId)
Definition: mythvideooutgpu.cpp:177
MythVideoOutput::IsErrored
bool IsErrored() const
Definition: mythvideoout.cpp:255
MythVideoOutputOpenGL::PrepareFrame
void PrepareFrame(MythVideoFrame *Frame, FrameScanType Scan) override
Definition: mythvideooutopengl.cpp:236
MythRenderOpenGL::doneCurrent
void doneCurrent()
Definition: mythrenderopengl.cpp:574
mythuihelper.h
mythpainteropengl.h
MythRenderOpenGL
Definition: mythrenderopengl.h:100
FMT_YUV422P9
@ FMT_YUV422P9
Definition: mythframe.h:38
MythVideoOutput::m_renderFormats
const VideoFrameTypes * m_renderFormats
Definition: mythvideoout.h:106
FMT_YUV420P9
@ FMT_YUV420P9
Definition: mythframe.h:25
MythRenderOpenGL::BindFramebuffer
void BindFramebuffer(QOpenGLFramebufferObject *Framebuffer)
Definition: mythrenderopengl.cpp:785
MythOpenGLVideo
Definition: mythopenglvideo.h:22
MythVideoBounds::GetBoundingRegion
QRegion GetBoundingRegion(void) const
Return the region of DisplayVisibleRect that lies outside of DisplayVideoRect.
Definition: mythvideobounds.cpp:755
FMT_YUV422P16
@ FMT_YUV422P16
Definition: mythframe.h:42
MythVideoOutputOpenGL::RenderFrame
void RenderFrame(MythVideoFrame *Frame, FrameScanType Scan) override
Definition: mythvideooutopengl.cpp:262
MythVideoOutputGPU::RenderFrame
void RenderFrame(MythVideoFrame *Frame, FrameScanType Scan) override
Definition: mythvideooutgpu.cpp:612
FMT_YUV422P12
@ FMT_YUV422P12
Definition: mythframe.h:40
MythVideoOutput::m_clearColor
uint8_t m_clearColor
Definition: mythvideoout.h:96
mythcontext.h
mythvideooutopengl.h
MythVideoOutputOpenGL::~MythVideoOutputOpenGL
~MythVideoOutputOpenGL() override
Definition: mythvideooutopengl.cpp:170
MythVideoOutputGPU
Common code shared between GPU accelerated sub-classes (e.g. OpenGL)
Definition: mythvideooutgpu.h:12
MythVideoOutputOpenGL::MythVideoOutputOpenGL
MythVideoOutputOpenGL(MythMainWindow *MainWindow, MythRenderOpenGL *Render, MythOpenGLPainter *Painter, MythDisplay *Display, const MythVideoProfilePtr &VideoProfile, QString &Profile)
Definition: mythvideooutopengl.cpp:99
mythcodeccontext.h
MythVideoOutputGPU::m_video
MythVideoGPU * m_video
Definition: mythvideooutgpu.h:70
MythVideoProfilePtr
std::shared_ptr< MythVideoProfile > MythVideoProfilePtr
Definition: mythvideogpu.h:18
MythVideoOutputGPU::m_painter
MythPainterGPU * m_painter
Definition: mythvideooutgpu.h:71
MythVideoBounds::GetWindowRect
QRect GetWindowRect(void) const
Definition: mythvideobounds.h:74
MythVideoFrame
Definition: mythframe.h:88
FMT_NV12
@ FMT_NV12
Definition: mythframe.h:53
MythOpenGLPerf::RecordSample
void RecordSample(void)
Definition: mythopenglperf.cpp:39
FMT_P016
@ FMT_P016
Definition: mythframe.h:55
mythmainwindow.h
MythVideoBounds::VideoIsFullScreen
bool VideoIsFullScreen(void) const
Check whether the video display rect covers the entire window/framebuffer.
Definition: mythvideobounds.cpp:743
kGLTiled
@ kGLTiled
Definition: mythrenderopengl.h:50
MythVideoOutputOpenGL::RenderEnd
void RenderEnd() override
Definition: mythvideooutopengl.cpp:335
MythMainWindow
Definition: mythmainwindow.h:28
MythOpenGLInterop::GetTypes
static void GetTypes(MythRender *Render, MythInteropGPU::InteropMap &Types)
Definition: mythopenglinterop.cpp:33
MythVideoOutput::m_videoColourSpace
MythVideoColourSpace m_videoColourSpace
Definition: mythvideoout.h:94
RenderOptions::priorities
QMap< QString, uint > * priorities
Definition: mythvideoprofile.h:50
OpenGLLocker
Definition: mythrenderopengl.h:263