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