MythTV  master
mythopenglvideo.cpp
Go to the documentation of this file.
1 // std
2 #include <utility>
3 
4 // Qt
5 #include <QPen>
6 
7 // MythTV
8 #include "libmyth/mythcontext.h"
10 #include "mythavutil.h"
12 #include "opengl/mythopenglvideo.h"
14 #include "tv.h"
15 
16 // FFmpeg
17 extern "C" {
18 #include "libavutil/stereo3d.h"
19 }
20 
21 #define LOC QString("GLVid: ")
22 // static constexpr int8_t MAX_VIDEO_TEXTURES { 10 }; // YV12 Kernel deinterlacer + 1
23 
35  MythVideoBounds* Bounds, const MythVideoProfilePtr& VideoProfile, const QString& Profile)
36  : MythVideoGPU(Render, ColourSpace, Bounds, VideoProfile, Profile),
37  m_openglRender(Render)
38 {
40  {
41  LOG(VB_GENERAL, LOG_ERR, LOC + "Fatal error");
42  return;
43  }
44 
45  OpenGLLocker ctx_lock(m_openglRender);
46  if (m_openglRender->isOpenGLES())
47  m_gles = m_openglRender->format().majorVersion();
48 
49  // Set OpenGL feature support
52  m_valid = true;
53 
54  m_chromaUpsamplingFilter = gCoreContext->GetBoolSetting("ChromaUpsamplingFilter", true);
55  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Chroma upsampling filter %1")
56  .arg(m_chromaUpsamplingFilter ? "enabled" : "disabled"));
57 }
58 
60 {
61  if (!m_openglRender)
62  return;
63 
66  delete m_toneMap;
68 }
69 
70 void MythOpenGLVideo::ColourSpaceUpdate(bool PrimariesChanged)
71 {
73 
74  // if input/output type are unset - we haven't created the shaders yet
75  if (PrimariesChanged && (m_outputType != FMT_NONE))
76  {
77  LOG(VB_GENERAL, LOG_INFO, LOC + "Primaries conversion changed - recreating shaders");
79  }
80 
81  float colourgamma = m_videoColourSpace->GetColourGamma();
82  float displaygamma = 1.0F / m_videoColourSpace->GetDisplayGamma();
83  QMatrix4x4 primary = m_videoColourSpace->GetPrimaryMatrix();
84  for (size_t i = Progressive; i < ShaderCount; ++i)
85  {
87  m_openglRender->SetShaderProgramParams(m_shaders[i], primary, "m_primaryMatrix");
88  if (m_shaders[i])
89  {
90  m_shaders[i]->setUniformValue("m_colourGamma", colourgamma);
91  m_shaders[i]->setUniformValue("m_displayGamma", displaygamma);
92  }
93  }
94 }
95 
97 {
98  if (m_inputTextureSize.isEmpty())
99  return;
100 
102  bool rect = m_textureTarget == QOpenGLTexture::TargetRectangle;
103  GLfloat lineheight = rect ? 1.0F : 1.0F / m_inputTextureSize.height();
104  GLfloat maxheight = rect ? m_videoDispDim.height() : m_videoDispDim.height() /
105  static_cast<GLfloat>(m_inputTextureSize.height());
106  GLfloat fieldsize = rect ? 0.5F : m_inputTextureSize.height() / 2.0F;
107  QVector4D parameters(lineheight, /* lineheight */
108  static_cast<GLfloat>(m_inputTextureSize.width()), /* 'Y' select */
109  maxheight - lineheight, /* maxheight */
110  fieldsize /* fieldsize */);
111 
112  for (size_t i = Progressive; i < ShaderCount; ++i)
113  {
114  if (m_shaders[i])
115  {
117  m_shaders[i]->setUniformValue("m_frameData", parameters);
118  if (BicubicUpsize == i)
119  {
120  QVector2D size { rect ? 1.0F : static_cast<GLfloat>(m_videoDim.width()),
121  rect ? 1.0F : static_cast<GLfloat>(m_videoDim.height()) };
122  m_shaders[i]->setUniformValue("m_textureSize", size);
123  }
124  }
125  }
126 }
127 
129 {
131  return TypeToProfile(m_inputType);
132  return TypeToProfile(m_outputType);
133 }
134 
136 {
137  // If switching off/from basic deinterlacing, then we need to delete and
138  // recreate the input textures and sometimes the shaders as well - so start
139  // from scratch
141  {
142  // Note. Textures will be created with linear filtering - which matches
143  // no resizing - which should be the case for the basic deinterlacer - and
144  // the call to SetupFrameFormat will reset resizing anyway
145  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Removing single field textures");
146  // revert to YUY2 if preferred
147  if ((m_inputType == FMT_YV12) && (m_profile == "opengl"))
150  emit OutputChanged(m_videoDim, m_videoDim, -1.0F);
151  }
154  m_deinterlacer2x = false;
155 }
156 
158  MythDeintType Filter /* = DEINT_SHADER */,
159  bool CreateReferences /* = true */)
160 {
161  if (!Frame)
162  return false;
163 
164  // do we want an opengl shader?
165  // shaders trump CPU deinterlacers if selected and driver deinterlacers will only
166  // be available under restricted circumstances
167  // N.B. there should in theory be no situation in which shader deinterlacing is not
168  // available for software formats, hence there should be no need to fallback to cpu
169 
170  if (!is_interlaced(Scan) || Frame->m_alreadyDeinterlaced)
171  {
173  return false;
174  }
175 
176  m_deinterlacer2x = true;
177  MythDeintType deinterlacer = Frame->GetDoubleRateOption(Filter);
178  MythDeintType other = Frame->GetDoubleRateOption(DEINT_DRIVER);
179  if (other) // another double rate deinterlacer is enabled
180  {
182  return false;
183  }
184 
185  if (!deinterlacer)
186  {
187  m_deinterlacer2x = false;
188  deinterlacer = Frame->GetSingleRateOption(Filter);
189  other = Frame->GetSingleRateOption(DEINT_DRIVER);
190  if (!deinterlacer || other) // no shader deinterlacer needed
191  {
193  return false;
194  }
195  }
196 
197  // if we get this far, we cannot use driver deinterlacers, shader deints
198  // are preferred over cpu, we have a deinterlacer but don't actually care whether
199  // it is single or double rate
200  if (m_deinterlacer == deinterlacer || (m_fallbackDeinterlacer && (m_fallbackDeinterlacer == deinterlacer)))
201  return true;
202 
203  // Lock
204  OpenGLLocker ctx_lock(m_openglRender);
205 
206  // delete old reference textures
209 
210  // For basic deinterlacing of software frames, we now create 2 sets of field
211  // based textures - which is the same approach taken by the CPU based onefield/bob
212  // deinterlacer and the EGL basic deinterlacer. The advantages of this
213  // approach are:-
214  // - no dependent texturing in the samplers (it is just a basic YUV to RGB conversion
215  // in the shader)
216  // - better quality (the onefield shader line doubles but does not have the
217  // implicit interpolation/smoothing of using separate textures directly,
218  // which leads to 'blockiness').
219  // - as we are not sampling other fields, there is no need to use an intermediate
220  // framebuffer to ensure accurate sampling - so we can skip the resize stage.
221  //
222  // YUYV formats are currently not supported as it does not work correctly - force YV12 instead.
223 
224  if (deinterlacer == DEINT_BASIC && MythVideoFrame::YUVFormat(m_inputType))
225  {
226  if (m_outputType == FMT_YUY2)
227  {
228  LOG(VB_GENERAL, LOG_INFO, LOC + "Forcing OpenGL YV12 for basic deinterlacer");
230  }
232  QSize size(m_videoDim.width(), m_videoDim.height() >> 1);
233  std::vector<QSize> sizes;
234  sizes.emplace_back(size);
235  // N.B. If we are currently resizing, it will be turned off for this
236  // deinterlacer, so the default linear texture filtering is OK.
238  // nextTextures will hold the other field
240  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Created %1 single field textures")
241  .arg(m_inputTextures.size() * 2));
242  // Con MythVideoBounds into display the field only
243  emit OutputChanged(m_videoDim, size, -1.0F);
244  }
245 
246  // sanity check max texture units. Should only be an issue on old hardware (e.g. Pi)
247  int max = m_openglRender->GetMaxTextureUnits();
248  uint refstocreate = ((deinterlacer == DEINT_HIGH) && CreateReferences) ? 2 : 0;
249  int totaltextures = static_cast<int>(MythVideoFrame::GetNumPlanes(m_outputType)) * static_cast<int>(refstocreate + 1);
250  if (totaltextures > max)
251  {
252  m_fallbackDeinterlacer = deinterlacer;
253  LOG(VB_GENERAL, LOG_WARNING, LOC + QString("Insufficent texture units for deinterlacer '%1' (%2 < %3)")
254  .arg(MythVideoFrame::DeinterlacerName(deinterlacer | DEINT_SHADER, m_deinterlacer2x)).arg(max).arg(totaltextures));
255  deinterlacer = DEINT_BASIC;
256  LOG(VB_GENERAL, LOG_WARNING, LOC + QString("Falling back to '%1'")
258  }
259 
260  // create new deinterlacers - the old ones will be deleted
261  if (!(CreateVideoShader(InterlacedBot, deinterlacer) && CreateVideoShader(InterlacedTop, deinterlacer)))
262  return false;
263 
264  // create the correct number of reference textures
265  if (refstocreate)
266  {
267  std::vector<QSize> sizes;
268  sizes.emplace_back(m_videoDim);
271  // ensure we use GL_NEAREST if resizing is already active and needed
272  if ((m_resizing & Sampling) == Sampling)
273  {
276  }
277  }
278 
279  // ensure they work correctly
280  UpdateColourSpace(false);
282  m_deinterlacer = deinterlacer;
283 
284  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Created deinterlacer '%1' (%2->%3)")
288  return true;
289 }
290 
299 {
300  if (!m_openglRender || !(m_features & QOpenGLFunctions::Shaders))
301  return false;
302 
303  // delete the old
304  if (m_shaders[Type])
306  m_shaders[Type] = nullptr;
307 
308  QStringList defines;
309  QString vertex = DefaultVertexShader;
310  QString fragment;
311  int cost = 1;
312 
314  defines << "EXTOES";
315 
316  if ((Default == Type) || (BicubicUpsize == Type) || (!MythVideoFrame::YUVFormat(m_outputType)))
317  {
318  QString glsldefines;
319  for (const QString& define : std::as_const(defines))
320  glsldefines += QString("#define MYTHTV_%1\n").arg(define);
321  fragment = glsldefines + YUVFragmentExtensions + ((BicubicUpsize == Type) ? BicubicShader : RGBFragmentShader);
322 
323 #ifdef USING_MEDIACODEC
325  vertex = MediaCodecVertexShader;
326 #endif
327  }
328  // no interlaced shaders yet (i.e. interlaced chroma upsampling - not deinterlacers)
329  else
330  {
331  fragment = YUVFragmentShader;
332  QString extensions = YUVFragmentExtensions;
333  QString glsldefines;
334 
335  // Any software frames that are not 8bit need to use unsigned integer
336  // samplers with GLES3.x - which need more modern shaders
337  if ((m_gles > 2) && (MythVideoFrame::ColorDepth(m_inputType) > 8))
338  {
339  static const QString glsl300("#version 300 es\n");
340  fragment = GLSL300YUVFragmentShader;
341  extensions = GLSL300YUVFragmentExtensions;
342  vertex = glsl300 + GLSL300VertexShader;
343  glsldefines.append(glsl300);
344  }
345 
346  bool kernel = false;
347  bool topfield = InterlacedTop == Type;
348  bool progressive = (Progressive == Type) || (Deint == DEINT_NONE);
350  {
351  defines << "YV12";
352  cost = 3;
353  }
355  {
356  defines << "NV12";
357  cost = 2;
358  }
359  else if (FMT_YUY2 == m_outputType)
360  {
361  defines << "YUY2";
362  }
363 
364 #ifdef USING_VTB
365  // N.B. Rectangular texture support is only currently used for VideoToolBox
366  // video frames which are NV12. Do not use rectangular textures for the 'default'
367  // shaders as it breaks video resizing and would require changes to our
368  // FramebufferObject code.
369  if ((m_textureTarget == QOpenGLTexture::TargetRectangle) && (Default != Type))
370  defines << "RECTS";
371 #endif
372  if (!progressive)
373  {
374  bool basic = Deint == DEINT_BASIC && MythVideoFrame::YUVFormat(m_inputType);
375  // Chroma upsampling filter
377  m_chromaUpsamplingFilter && !basic)
378  {
379  defines << "CUE";
380  }
381 
382  // field
383  if (topfield && !basic)
384  defines << "TOPFIELD";
385 
386  switch (Deint)
387  {
388  case DEINT_BASIC:
389  if (!basic)
390  {
391  cost *= 2;
392  defines << "ONEFIELD";
393  }
394  break;
395  case DEINT_MEDIUM: cost *= 5; defines << "LINEARBLEND"; break;
396  case DEINT_HIGH: cost *= 15; defines << "KERNEL"; kernel = true; break;
397  default: break;
398  }
399  }
400 
401  // Start building the new fragment shader
402  // We do this in code otherwise the shader string becomes monolithic
403 
404  // 'expand' calls to sampleYUV for multiple planes
405  // do this before we add the samplers
406  int count = static_cast<int>(MythVideoFrame::GetNumPlanes(m_outputType));
407  for (int i = (kernel ? 2 : 0); (i >= 0) && count; i--)
408  {
409  QString find = QString("s_texture%1").arg(i);
410  QStringList replacelist;
411  for (int j = (i * count); j < ((i + 1) * count); ++j)
412  replacelist << QString("s_texture%1").arg(j);
413  fragment.replace(find, replacelist.join(", "));
414  }
415 
416  // 'expand' calls to the kernel function
417  if (kernel && count)
418  {
419  for (int i = 1 ; i >= 0; i--)
420  {
421  QString find1 = QString("sampler2D kernelTex%1").arg(i);
422  QString find2 = QString("kernelTex%1").arg(i);
423  QStringList replacelist1;
424  QStringList replacelist2;
425  for (int j = 0; j < count; ++j)
426  {
427  replacelist1 << QString("sampler2D kernelTexture%1%2").arg(i).arg(j);
428  replacelist2 << QString("kernelTexture%1%2").arg(i).arg(j);
429  }
430  fragment.replace(find1, replacelist1.join(", "));
431  fragment.replace(find2, replacelist2.join(", "));
432  }
433  }
434 
435  // Retrieve colour mappping defines
437 
438  // Add defines
439  for (const QString& define : std::as_const(defines))
440  glsldefines += QString("#define MYTHTV_%1\n").arg(define);
441 
442  // Add the required samplers
443  int start = 0;
444  int end = count;
445  if (kernel)
446  {
447  end *= 3;
448  if (topfield)
449  start += count;
450  else
451  end -= count;
452  }
453  QString glslsamplers;
454  for (int i = start; i < end; ++i)
455  glslsamplers += QString("uniform sampler2D s_texture%1;\n").arg(i);
456 
457  // construct the final shader string
458  fragment = glsldefines + extensions + glslsamplers + fragment;
459  }
460 
461  m_shaderCost[Type] = cost;
462  QOpenGLShaderProgram *program = m_openglRender->CreateShaderProgram(vertex, fragment);
463  if (!program)
464  return false;
465 
466  m_shaders[Type] = program;
467  return true;
468 }
469 
471  QSize Size, GLenum TextureTarget)
472 {
473  QString texnew = (TextureTarget == QOpenGLTexture::TargetRectangle) ? "Rect" :
474  (TextureTarget == GL_TEXTURE_EXTERNAL_OES) ? "OES" : "2D";
475  QString texold = (m_textureTarget == QOpenGLTexture::TargetRectangle) ? "Rect" :
476  (m_textureTarget == GL_TEXTURE_EXTERNAL_OES) ? "OES" : "2D";
477  LOG(VB_GENERAL, LOG_INFO, LOC +
478  QString("New frame format: %1:%2 %3x%4 (Tex: %5) -> %6:%7 %8x%9 (Tex: %10)")
481  QString::number(m_videoDim.width()),
482  QString::number(m_videoDim.height()),
483  texold,
486  QString::number(Size.width()),
487  QString::number(Size.height()))
488  .arg(texnew));
489 
491 
492  m_inputType = InputType;
493  m_outputType = OutputType;
494  m_textureTarget = TextureTarget;
495  m_videoDim = Size;
496 
497  // This is only currently needed for RGBA32 frames from composed DRM_PRIME
498  // textures that may be half height for simple bob deinterlacing
500  emit OutputChanged(m_videoDim, m_videoDim, -1.0F);
501 
502  if (!MythVideoFrame::HardwareFormat(InputType))
503  {
504  std::vector<QSize> sizes;
505  sizes.push_back(Size);
507  if (m_inputTextures.empty())
508  {
509  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create input textures");
510  return false;
511  }
512 
513  m_inputTextureSize = m_inputTextures[0]->m_totalSize;
514  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Created %1 input textures for '%2'")
515  .arg(m_inputTextures.size()).arg(GetProfile()));
516  }
517  else
518  {
519  m_inputTextureSize = Size;
520  }
521 
522  // Create shaders
524  return false;
525 
526  UpdateColourSpace(false);
528  return true;
529 }
530 
532 {
533  for (auto & shader : m_shaders)
534  if (shader)
536  m_shaders.fill(nullptr);
537  m_shaderCost.fill(1);
541  m_textureTarget = QOpenGLTexture::Target2D;
545  m_frameBuffer = nullptr;
546  m_frameBufferTexture = nullptr;
547 
549 }
550 
553 {
554  if (Frame->m_type == FMT_NONE)
555  return;
556 
557  // Hardware frames are retrieved/updated in PrepareFrame but we need to
558  // reset software frames now if necessary
560  {
562  {
563  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Resetting input format");
565  }
566  return;
567  }
568 
569  // Sanitise frame
570  if ((Frame->m_width < 1) || (Frame->m_height < 1) || !Frame->m_buffer)
571  {
572  LOG(VB_GENERAL, LOG_ERR, LOC + "Invalid software frame");
573  return;
574  }
575 
576  // Can we render this frame format
577  if (!MythVideoFrame::YUVFormat(Frame->m_type))
578  {
579  LOG(VB_GENERAL, LOG_ERR, LOC + "Frame format is not supported");
580  return;
581  }
582 
583  // lock
584  OpenGLLocker ctx_lock(m_openglRender);
585 
586  // check for input changes
587  if ((Frame->m_width != m_videoDim.width()) ||
588  (Frame->m_height != m_videoDim.height()) ||
589  (Frame->m_type != m_inputType))
590  {
591  VideoFrameType frametype = Frame->m_type;
592  if ((frametype == FMT_YV12) && (m_profile == "opengl"))
593  frametype = FMT_YUY2;
594  QSize size(Frame->m_width, Frame->m_height);
595  if (!SetupFrameFormat(Frame->m_type, frametype, size, QOpenGLTexture::Target2D))
596  return;
597  }
598 
599  // Setup deinterlacing if required
600  AddDeinterlacer(Frame, Scan);
601 
602  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
603  m_openglRender->logDebugMarker(LOC + "UPDATE_FRAME_START");
604 
606 
607  // Rotate textures if necessary
608  bool current = true;
610  {
611  if (!m_nextTextures.empty() && !m_prevTextures.empty())
612  {
613  if (qAbs(Frame->m_frameCounter - m_discontinuityCounter) > 1)
614  ResetTextures();
615  std::vector<MythVideoTextureOpenGL*> temp = m_prevTextures;
618  m_nextTextures = temp;
619  current = false;
620  }
621  }
622 
623  m_discontinuityCounter = Frame->m_frameCounter;
624 
626  {
627  // first field. Fake the pitches
628  FramePitches pitches = Frame->m_pitches;
629  Frame->m_pitches[0] = Frame->m_pitches[0] << 1;
630  Frame->m_pitches[1] = Frame->m_pitches[1] << 1;
631  Frame->m_pitches[2] = Frame->m_pitches[2] << 1;
633  // second field. Fake the offsets as well.
634  FrameOffsets offsets = Frame->m_offsets;
635  Frame->m_offsets[0] = Frame->m_offsets[0] + pitches[0];
636  Frame->m_offsets[1] = Frame->m_offsets[1] + pitches[1];
637  Frame->m_offsets[2] = Frame->m_offsets[2] + pitches[2];
639  Frame->m_pitches = pitches;
640  Frame->m_offsets = offsets;
641  }
642  else
643  {
645  }
646 
647  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
648  m_openglRender->logDebugMarker(LOC + "UPDATE_FRAME_END");
649 }
650 
652  StereoscopicMode StereoOverride, bool DrawBorder)
653 {
654  if (!m_openglRender)
655  return;
656 
658 
659  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
660  m_openglRender->logDebugMarker(LOC + "RENDER_FRAME_START");
661 
662  // Set required input textures for the last stage
663  // ProcessFrame is always called first, which will create/destroy software
664  // textures as needed
665  bool hwframes = false;
666  bool useframebufferimage = false;
667 
668  // for tiled renderers (e.g. Pi), enable scissoring to try and improve performance
669  // when not full screen and avoid the resize stage unless absolutely necessary
670  bool tiled = m_extraFeatures & kGLTiled;
671 
672  // We lose the pause frame when seeking and using VDPAU/VAAPI/NVDEC direct rendering.
673  // As a workaround, we always use the resize stage so the last displayed frame
674  // should be retained in the Framebuffer used for resizing. If there is
675  // nothing to display, then fallback to this framebuffer.
676  // N.B. this is now strictly necessary with v4l2 and DRM PRIME direct rendering
677  // but ignore now for performance reasons
678  VideoResizing resize = Frame ? (MythVideoFrame::HardwareFramesFormat(Frame->m_type) ? Framebuffer : None) :
680 
681  std::vector<MythVideoTextureOpenGL*> inputtextures = m_inputTextures;
682  if (inputtextures.empty())
683  {
684  // This is experimental support for direct rendering to a framebuffer (e.g. DRM).
685  // It may be removed or refactored (e.g. pass presentation details through to
686  // the interop).
687  if (Frame)
688  {
689  Frame->m_displayed = false;
690  Frame->m_srcRect = m_videoRect;
691  Frame->m_dstRect = m_displayVideoRect;
692  }
693 
694  // Pull in any hardware frames
696 
697  if (Frame && Frame->m_displayed)
698  return;
699 
700  if (!inputtextures.empty())
701  {
702  hwframes = true;
703  QSize newsize = inputtextures[0]->m_size;
704  VideoFrameType newsourcetype = inputtextures[0]->m_frameType;
705  VideoFrameType newtargettype = inputtextures[0]->m_frameFormat;
706  GLenum newtargettexture = inputtextures[0]->m_target;
707  if ((m_outputType != newtargettype) || (m_textureTarget != newtargettexture) ||
708  (m_inputType != newsourcetype) || (newsize != m_inputTextureSize))
709  {
710  SetupFrameFormat(newsourcetype, newtargettype, newsize, newtargettexture);
711  }
712 
713 #ifdef USING_MEDIACODEC
714  // Set the texture transform for mediacodec
716  {
717  if (inputtextures[0]->m_transform && m_shaders[Default])
718  {
720  m_shaders[Default]->setUniformValue("u_transform", *inputtextures[0]->m_transform);
721  }
722  }
723 #endif
724  // Enable deinterlacing for NVDEC, VTB and VAAPI DRM if VPP is not available
725  if (inputtextures[0]->m_allowGLSLDeint)
726  AddDeinterlacer(Frame, Scan, DEINT_SHADER | DEINT_CPU, false); // pickup shader or cpu prefs
727  }
728  else
729  {
730  if ((resize == Framebuffer) && m_frameBuffer && m_frameBufferTexture)
731  {
732  LOG(VB_PLAYBACK, LOG_DEBUG, "Using existing framebuffer");
733  useframebufferimage = true;
734  }
735  else
736  {
737  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + "Nothing to display");
738  // if this is live tv startup and the window rect has changed we
739  // must set the viewport
741  return;
742  }
743  }
744  }
745 
746  // Determine which shader to use. This helps optimise the resize check.
747  bool deinterlacing = false;
748  bool basicdeinterlacing = false;
749  bool yuvoutput = MythVideoFrame::YUVFormat(m_outputType);
750  VideoShaderType program = yuvoutput ? Progressive : Default;
751  if (m_deinterlacer != DEINT_NONE)
752  {
753  if (Scan == kScan_Interlaced)
754  {
755  program = TopFieldFirst ? InterlacedTop : InterlacedBot;
756  deinterlacing = true;
757  }
758  else if (Scan == kScan_Intr2ndField)
759  {
760  program = TopFieldFirst ? InterlacedBot : InterlacedTop;
761  deinterlacing = true;
762  }
763 
764  // select the correct field for the basic deinterlacer
766  {
767  basicdeinterlacing = true;
768  if (program == InterlacedBot)
769  inputtextures = m_nextTextures;
770  }
771  }
772 
773  // Set deinterlacer type for debug OSD
774  if (deinterlacing && Frame)
775  {
776  Frame->m_deinterlaceInuse = m_deinterlacer | DEINT_SHADER;
777  Frame->m_deinterlaceInuse2x = m_deinterlacer2x;
778  }
779 
780  // Tonemapping can only render to a texture
781  if (m_toneMap)
782  resize |= ToneMap;
783 
784  // Decide whether to use render to texture - for performance or quality
785  if (yuvoutput && !resize)
786  {
787  // ensure deinterlacing works correctly when down scaling in height
788  // N.B. not needed for the basic deinterlacer
789  if (deinterlacing && !basicdeinterlacing && (m_videoDispDim.height() > m_displayVideoRect.height()))
790  resize |= Deinterlacer;
791 
792  // NB GL_NEAREST introduces some 'minor' chroma sampling errors
793  // for the following 2 cases. For YUY2 this may be better handled in the
794  // shader. For GLES3.0 10bit textures - Vulkan is probably the better solution.
795 
796  // UYVY packed pixels must be sampled exactly with GL_NEAREST
797  if (FMT_YUY2 == m_outputType)
798  resize |= Sampling;
799  // unsigned integer texture formats need GL_NEAREST sampling
800  if ((m_gles > 2) && (MythVideoFrame::ColorDepth(m_inputType) > 8))
801  resize |= Sampling;
802 
803  // don't enable resizing if the cost of a framebuffer switch may be
804  // prohibitive (e.g. Raspberry Pi/tiled renderers) or for basic deinterlacing,
805  // where we are trying to simplify/optimise rendering (and the framebuffer
806  // sizing gets confused by the change to m_videoDispDim)
807  if (!resize && !tiled && !basicdeinterlacing)
808  {
809  // improve performance. This is an educated guess on the relative cost
810  // of render to texture versus straight rendering.
811  int totexture = m_videoDispDim.width() * m_videoDispDim.height() * m_shaderCost[program];
812  int blitcost = m_displayVideoRect.width() * m_displayVideoRect.height() * m_shaderCost[Default];
813  int noresizecost = m_displayVideoRect.width() * m_displayVideoRect.height() * m_shaderCost[program];
814  if ((totexture + blitcost) < noresizecost)
815  resize |= Performance;
816  }
817  }
818 
819  // Bicubic upsizing - test this after all other resize options have been checked
820  // to ensure it is not the only flag set
821  if (m_bicubicUpsize)
822  SetupBicubic(resize);
823 
824  // We don't need an extra stage prior to bicubic if the frame is already RGB (e.g. VDPAU, MediaCodec)
825  // So bypass if we only set resize for bicubic.
826  bool needresize = resize && (!MythVideoFrame::FormatIsRGB(m_outputType) || (resize != Bicubic));
827 
828  // set software frame filtering if resizing has changed
829  if (!needresize && m_resizing)
830  {
831  // remove framebuffer
833  {
835  m_frameBufferTexture = nullptr;
836  }
837  if (m_frameBuffer)
838  {
840  m_frameBuffer = nullptr;
841  }
842  // set filtering
846  m_resizing = None;
847  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Disabled resizing");
848  }
849  else if (!m_resizing && needresize)
850  {
851  // framebuffer will be created as needed below
852  QOpenGLTexture::Filter filter = ((resize & Sampling) == Sampling) ? QOpenGLTexture::Nearest : QOpenGLTexture::Linear;
856  m_resizing = resize;
857  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Resizing from %1x%2 to %3x%4 for %5")
858  .arg(m_videoDispDim.width()).arg(m_videoDispDim.height())
859  .arg(m_displayVideoRect.width()).arg(m_displayVideoRect.height())
860  .arg(VideoResizeToString(resize)));
861  }
862 
863  // check hardware frames have the correct filtering
864  if (hwframes)
865  {
866  QOpenGLTexture::Filter filter = (resize.testFlag(Sampling)) ? QOpenGLTexture::Nearest : QOpenGLTexture::Linear;
867  if (inputtextures[0]->m_filter != filter)
869  }
870 
871  // texture coordinates
872  QRect trect(m_videoRect);
873 
874  if (needresize)
875  {
876  MythVideoTextureOpenGL* nexttexture = nullptr;
877 
878  // only render to the framebuffer if there is something to update
879  if (useframebufferimage)
880  {
881  if (m_toneMap)
882  {
883  nexttexture = m_toneMap->GetTexture();
884  trect = QRect(QPoint(0, 0), m_displayVideoRect.size());
885  }
886  else
887  {
888  nexttexture = m_frameBufferTexture;
889  }
890  }
891  else if (m_toneMap)
892  {
893  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
894  m_openglRender->logDebugMarker(LOC + "RENDER_TO_TEXTURE");
895  nexttexture = m_toneMap->Map(inputtextures, m_displayVideoRect.size());
896  trect = QRect(QPoint(0, 0), m_displayVideoRect.size());
897  }
898  else
899  {
900  // render to texture stage
901  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
902  m_openglRender->logDebugMarker(LOC + "RENDER_TO_TEXTURE");
903 
904  // we need a framebuffer and associated texture
905  if (!m_frameBuffer)
906  {
908  (fbo != nullptr) && (tex != nullptr))
909  {
910  delete m_frameBuffer;
911  delete m_frameBufferTexture;
912  m_frameBuffer = fbo;
913  m_frameBufferTexture = tex;
914  m_openglRender->SetTextureFilters(m_frameBufferTexture, QOpenGLTexture::Linear);
915  }
916  }
917 
919  return;
920 
921  // coordinates
922  QRect vrect(QPoint(0, 0), m_videoDispDim);
923  QRect trect2 = vrect;
924  if (FMT_YUY2 == m_outputType)
925  trect2.setWidth(m_videoDispDim.width() >> 1);
926 
927  // framebuffer
929  m_openglRender->SetViewPort(vrect);
930 
931  // bind correct textures
932  std::vector<MythGLTexture*> textures {};
933  BindTextures(deinterlacing, inputtextures, textures);
934 
935  // render
936  m_openglRender->DrawBitmap(textures, m_frameBuffer, trect2, vrect,
937  m_shaders[program], 0);
938  nexttexture = m_frameBufferTexture;
939  }
940 
941  // reset for next stage
942  inputtextures.clear();
943  inputtextures.push_back(nexttexture);
944  program = Default;
945  deinterlacing = false;
946  }
947 
948  // Use the bicubic shader if necessary
949  if (resize.testFlag(Bicubic))
950  program = BicubicUpsize;
951 
952  // render to default framebuffer/screen
953  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
954  m_openglRender->logDebugMarker(LOC + "RENDER_TO_SCREEN");
955 
956  // discard stereoscopic fields
957  StereoscopicMode stereo = StereoOverride;
958  m_lastStereo = Frame ? Frame->m_stereo3D : m_lastStereo;
959  // N.B. kStereoscopicModeSideBySideDiscard is a proxy here for discard of all types
960  if ((stereo == kStereoscopicModeAuto) &&
962  (m_lastStereo != AV_STEREO3D_2D))
963  {
964  if (m_lastStereo == AV_STEREO3D_SIDEBYSIDE)
966  else if (m_lastStereo == AV_STEREO3D_TOPBOTTOM)
968  }
969 
971  trect = QRect(trect.left() >> 1, trect.top(), trect.width() >> 1, trect.height());
972  else if (kStereoscopicModeTopAndBottomDiscard == stereo)
973  trect = QRect(trect.left(), trect.top() >> 1, trect.width(), trect.height() >> 1);
974 
975  // bind default framebuffer
978 
979  // PiP border
980  if (DrawBorder)
981  {
982  QRect piprect = m_displayVideoRect.adjusted(-10, -10, +10, +10);
983  static const QPen kNopen(Qt::NoPen);
984  static const QBrush kRedBrush(QBrush(QColor(127, 0, 0, 255)));
985  m_openglRender->DrawRect(nullptr, piprect, kRedBrush, kNopen, 255);
986  }
987 
988  // bind correct textures
989  std::vector<MythGLTexture*> textures;
990  BindTextures(deinterlacing, inputtextures, textures);
991 
992  // rotation
993  if (Frame)
994  m_lastRotation = Frame->m_rotation;
995 
996  // apply scissoring
997  if (tiled)
998  {
999  // N.B. It's not obvious whether this helps
1000  m_openglRender->glEnable(GL_SCISSOR_TEST);
1001  m_openglRender->glScissor(m_displayVideoRect.left() - 1, m_displayVideoRect.top() - 1,
1002  m_displayVideoRect.width() + 2, m_displayVideoRect.height() + 2);
1003  }
1004 
1005  // draw
1006  m_openglRender->DrawBitmap(textures, nullptr, trect, m_displayVideoRect,
1007  m_shaders[program], m_lastRotation);
1008 
1009  // disable scissoring
1010  if (tiled)
1011  m_openglRender->glDisable(GL_SCISSOR_TEST);
1012 
1013  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
1014  m_openglRender->logDebugMarker(LOC + "RENDER_FRAME_END");
1015 }
1016 
1019 {
1020  for (auto & texture : m_inputTextures)
1021  texture->m_valid = false;
1022  for (auto & texture : m_prevTextures)
1023  texture->m_valid = false;
1024  for (auto & texture : m_nextTextures)
1025  texture->m_valid = false;
1026 }
1027 
1028 void MythOpenGLVideo::BindTextures(bool Deinterlacing, std::vector<MythVideoTextureOpenGL*>& Current,
1029  std::vector<MythGLTexture*>& Textures)
1030 {
1031  if (Deinterlacing && !MythVideoFrame::HardwareFormat(m_inputType))
1032  {
1033  if ((m_nextTextures.size() == Current.size()) && (m_prevTextures.size() == Current.size()))
1034  {
1035  // if we are using reference frames, we want the current frame in the middle
1036  // but next will be the first valid, followed by current...
1037  size_t count = Current.size();
1038  std::vector<MythVideoTextureOpenGL*>& current = Current[0]->m_valid ? Current : m_nextTextures;
1039  std::vector<MythVideoTextureOpenGL*>& prev = m_prevTextures[0]->m_valid ? m_prevTextures : current;
1040 
1041  for (uint i = 0; i < count; ++i)
1042  Textures.push_back(reinterpret_cast<MythGLTexture*>(prev[i]));
1043  for (uint i = 0; i < count; ++i)
1044  Textures.push_back(reinterpret_cast<MythGLTexture*>(current[i]));
1045  for (uint i = 0; i < count; ++i)
1046  Textures.push_back(reinterpret_cast<MythGLTexture*>(m_nextTextures[i]));
1047  return;
1048  }
1049  }
1050 
1051  std::transform(Current.cbegin(), Current.cend(), std::back_inserter(Textures),
1052  [](MythVideoTextureOpenGL* Tex) { return reinterpret_cast<MythGLTexture*>(Tex); });
1053 }
1054 
1056 {
1058  return "opengl-hw";
1059 
1060  switch (Type)
1061  {
1062  case FMT_YUY2: return "opengl"; // compatibility with old profiles
1063  case FMT_YV12: return "opengl-yv12";
1064  case FMT_NV12: return "opengl-nv12";
1065  default: break;
1066  }
1067  return "opengl";
1068 }
1069 
1070 void MythOpenGLVideo::SetupBicubic(VideoResizing& Resize)
1071 {
1072  if (((m_videoDispDim.width() < m_displayVideoRect.width()) ||
1073  (m_videoDispDim.height() < m_displayVideoRect.height())))
1074  {
1075  if (!m_shaders[BicubicUpsize])
1076  {
1078  {
1079  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create bicubic shader. Disabling");
1080  m_bicubicUpsize = false;
1081  }
1082  else
1083  {
1085  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Created bicubic sampler");
1086  }
1087  }
1088 
1089  if (m_shaders[BicubicUpsize])
1090  Resize |= Bicubic;
1091  }
1092  else
1093  {
1094  if (m_shaders[BicubicUpsize] != nullptr)
1095  {
1096  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Disabling bicubic sampler");
1097  delete m_shaders[BicubicUpsize];
1098  m_shaders[BicubicUpsize] = nullptr;
1099  }
1100  }
1101 }
FMT_MEDIACODEC
@ FMT_MEDIACODEC
Definition: mythframe.h:61
MythOpenGLVideo::m_toneMap
MythOpenGLTonemap * m_toneMap
Definition: mythopenglvideo.h:83
DEINT_DRIVER
@ DEINT_DRIVER
Definition: mythframe.h:75
tv.h
MythVideoGPU::m_discontinuityCounter
uint64_t m_discontinuityCounter
Definition: mythvideogpu.h:78
MythOpenGLVideo::m_gles
int m_gles
Definition: mythopenglvideo.h:70
MythGLTexture
Definition: mythrenderopengl.h:56
DEINT_MEDIUM
@ DEINT_MEDIUM
Definition: mythframe.h:71
MythVideoGPU::m_lastStereo
uint m_lastStereo
Definition: mythvideogpu.h:95
MythVideoGPU::m_inputTextureSize
QSize m_inputTextureSize
Definition: mythvideogpu.h:88
MythVideoGPU::Sampling
@ Sampling
Definition: mythvideogpu.h:29
MythOpenGLVideo::InterlacedTop
@ InterlacedTop
Definition: mythopenglvideo.h:31
MythRenderOpenGL::DeleteFramebuffer
void DeleteFramebuffer(QOpenGLFramebufferObject *Framebuffer)
Definition: mythrenderopengl.cpp:775
DEINT_SHADER
@ DEINT_SHADER
Definition: mythframe.h:74
MythVideoTextureOpenGL
Definition: mythvideotextureopengl.h:21
MythVideoFrame::HardwareFramesFormat
static bool HardwareFramesFormat(VideoFrameType Type)
Definition: mythframe.h:433
FMT_DRMPRIME
@ FMT_DRMPRIME
Definition: mythframe.h:64
MythOpenGLTonemap::Map
MythVideoTextureOpenGL * Map(std::vector< MythVideoTextureOpenGL * > &Inputs, QSize DisplaySize)
Definition: mythopengltonemap.cpp:73
MythVideoGPU::m_lastRotation
int m_lastRotation
Definition: mythvideogpu.h:90
MythOpenGLVideo::ResetTextures
void ResetTextures() override
Clear reference frames after a seek as they will contain old images.
Definition: mythopenglvideo.cpp:1018
MythOpenGLVideo::m_frameBufferTexture
MythVideoTextureOpenGL * m_frameBufferTexture
Definition: mythopenglvideo.h:78
MythVideoGPU::m_resizing
VideoResizing m_resizing
Definition: mythvideogpu.h:89
MythOpenGLVideo::MythOpenGLVideo
MythOpenGLVideo(MythRenderOpenGL *Render, MythVideoColourSpace *ColourSpace, MythVideoBounds *Bounds, const MythVideoProfilePtr &VideoProfile, const QString &Profile)
Definition: mythopenglvideo.cpp:34
Frame
Definition: zmdefines.h:93
BicubicShader
static const QString BicubicShader
Definition: mythopenglvideoshaders.h:190
MythVideoColourSpace::UpdateColourSpace
bool UpdateColourSpace(const MythVideoFrame *Frame)
Set the current colourspace to use.
Definition: mythvideocolourspace.cpp:321
MythRenderOpenGL::logDebugMarker
void logDebugMarker(const QString &Message)
Definition: mythrenderopengl.cpp:193
MythVideoFrame::FormatIsRGB
static bool FormatIsRGB(VideoFrameType Type)
Definition: mythframe.h:472
VERBOSE_LEVEL_CHECK
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
Definition: mythlogging.h:29
DEINT_NONE
@ DEINT_NONE
Definition: mythframe.h:69
MythVideoGPU::m_videoColourSpace
MythVideoColourSpace * m_videoColourSpace
Definition: mythvideogpu.h:87
MythOpenGLVideo::~MythOpenGLVideo
~MythOpenGLVideo() override
Definition: mythopenglvideo.cpp:59
FrameScanType
FrameScanType
Definition: videoouttypes.h:94
MythVideoGPU::m_bicubicUpsize
bool m_bicubicUpsize
Definition: mythvideogpu.h:97
FramePitches
std::array< int, 3 > FramePitches
Definition: mythframe.h:84
LOC
#define LOC
Definition: mythopenglvideo.cpp:21
MythRenderOpenGL::DrawBitmap
void DrawBitmap(MythGLTexture *Texture, QOpenGLFramebufferObject *Target, QRect Source, QRect Destination, QOpenGLShaderProgram *Program, int Alpha=255, qreal Scale=1.0)
Definition: mythrenderopengl.cpp:833
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythVideoFrame::HardwareFormat
static bool HardwareFormat(VideoFrameType Type)
Definition: mythframe.h:425
MythVideoGPU::ToneMap
@ ToneMap
Definition: mythvideogpu.h:32
MythOpenGLVideo::PrepareFrame
void PrepareFrame(MythVideoFrame *Frame, FrameScanType Scan=kScan_Progressive) override
Update the current input texture using the data from the given video frame.
Definition: mythopenglvideo.cpp:552
MythVideoTextureOpenGL::SetTextureFilters
static void SetTextureFilters(MythRenderOpenGL *Context, const std::vector< MythVideoTextureOpenGL * > &Textures, QOpenGLTexture::Filter Filter, QOpenGLTexture::WrapMode Wrap=QOpenGLTexture::ClampToEdge)
Definition: mythvideotextureopengl.cpp:40
FrameOffsets
std::array< int, 3 > FrameOffsets
Definition: mythframe.h:85
MythVideoFrame::FormatIs422
static bool FormatIs422(VideoFrameType Type)
Definition: mythframe.h:444
MythVideoTextureOpenGL::UpdateTextures
static void UpdateTextures(MythRenderOpenGL *Context, const MythVideoFrame *Frame, const std::vector< MythVideoTextureOpenGL * > &Textures)
Update the contents of the given Textures for data held in Frame.
Definition: mythvideotextureopengl.cpp:281
MythVideoGPU::m_videoDim
QSize m_videoDim
Definition: mythvideogpu.h:83
mythopenglvideoshaders.h
MythOpenGLVideo::SetupFrameFormat
bool SetupFrameFormat(VideoFrameType InputType, VideoFrameType OutputType, QSize Size, GLenum TextureTarget)
Definition: mythopenglvideo.cpp:470
mythopenglvideo.h
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
MythRenderOpenGL::GetFeatures
QOpenGLFunctions::OpenGLFeatures GetFeatures(void) const
Definition: mythrenderopengl.cpp:460
MythOpenGLVideo::m_fallbackDeinterlacer
MythDeintType m_fallbackDeinterlacer
Definition: mythopenglvideo.h:71
MythRenderOpenGL::SetShaderProgramParams
void SetShaderProgramParams(QOpenGLShaderProgram *Program, const QMatrix4x4 &Value, const char *Uniform)
Definition: mythrenderopengl.cpp:1499
MythOpenGLVideo::m_frameBuffer
QOpenGLFramebufferObject * m_frameBuffer
Definition: mythopenglvideo.h:77
FMT_NONE
@ FMT_NONE
Definition: mythframe.h:22
MythVideoGPU
Definition: mythvideogpu.h:20
GL_TEXTURE_EXTERNAL_OES
#define GL_TEXTURE_EXTERNAL_OES
Definition: mythrenderopengldefs.h:13
DEINT_CPU
@ DEINT_CPU
Definition: mythframe.h:73
MythVideoColourSpace::GetColourMappingDefines
QStringList GetColourMappingDefines(void)
Definition: mythvideocolourspace.cpp:442
mythrenderopengl.h
MythVideoFrame::YUVFormat
static bool YUVFormat(VideoFrameType Type)
Definition: mythframe.h:466
MythOpenGLVideo::m_features
QOpenGLFunctions::OpenGLFeatures m_features
Definition: mythopenglvideo.h:79
MythOpenGLVideo::BindTextures
void BindTextures(bool Deinterlacing, std::vector< MythVideoTextureOpenGL * > &Current, std::vector< MythGLTexture * > &Textures)
Definition: mythopenglvideo.cpp:1028
kScan_Intr2ndField
@ kScan_Intr2ndField
Definition: videoouttypes.h:99
MythVideoGPU::m_profile
QString m_profile
Definition: mythvideogpu.h:79
MythVideoGPU::Bicubic
@ Bicubic
Definition: mythvideogpu.h:33
MythOpenGLVideo::ColourSpaceUpdate
void ColourSpaceUpdate(bool PrimariesChanged) override
Definition: mythopenglvideo.cpp:70
MythOpenGLVideo::m_openglRender
MythRenderOpenGL * m_openglRender
Definition: mythopenglvideo.h:69
MythOpenGLVideo::InterlacedBot
@ InterlacedBot
Definition: mythopenglvideo.h:32
MythRenderOpenGL::DrawRect
void DrawRect(QOpenGLFramebufferObject *Target, QRect Area, const QBrush &FillBrush, const QPen &LinePen, int Alpha)
Definition: mythrenderopengl.cpp:979
MythVideoGPU::m_videoDispDim
QSize m_videoDispDim
Definition: mythvideogpu.h:82
mythopengltonemap.h
FMT_YV12
@ FMT_YV12
Definition: mythframe.h:24
MythOpenGLVideo::TypeToProfile
static QString TypeToProfile(VideoFrameType Type)
Definition: mythopenglvideo.cpp:1055
MythOpenGLVideo::RenderFrame
void RenderFrame(MythVideoFrame *Frame, bool TopFieldFirst, FrameScanType Scan, StereoscopicMode StereoOverride, bool DrawBorder=false) override
Definition: mythopenglvideo.cpp:651
MythOpenGLVideo::m_inputTextures
std::vector< MythVideoTextureOpenGL * > m_inputTextures
Definition: mythopenglvideo.h:74
MythOpenGLVideo::m_chromaUpsamplingFilter
bool m_chromaUpsamplingFilter
Definition: mythopenglvideo.h:82
MythOpenGLVideo::SetupBicubic
void SetupBicubic(VideoResizing &Resize)
Definition: mythopenglvideo.cpp:1070
MythOpenGLVideo::m_textureTarget
GLenum m_textureTarget
Definition: mythopenglvideo.h:81
MythOpenGLVideo::AddDeinterlacer
bool AddDeinterlacer(const MythVideoFrame *Frame, FrameScanType Scan, MythDeintType Filter=DEINT_SHADER, bool CreateReferences=true)
Definition: mythopenglvideo.cpp:157
MythVideoColourSpace::GetColourGamma
float GetColourGamma(void) const
Definition: mythvideocolourspace.cpp:465
GLSL300VertexShader
static const QString GLSL300VertexShader
Definition: mythopenglvideoshaders.h:298
MythOpenGLVideo::m_prevTextures
std::vector< MythVideoTextureOpenGL * > m_prevTextures
Definition: mythopenglvideo.h:75
MythOpenGLVideo::Progressive
@ Progressive
Definition: mythopenglvideo.h:30
MythVideoGPU::VideoResizeToString
static QString VideoResizeToString(VideoResizing Resize)
Definition: mythvideogpu.cpp:108
MythRenderOpenGL::makeCurrent
void makeCurrent()
Definition: mythrenderopengl.cpp:566
MythVideoFrame::ColorDepth
static int ColorDepth(int Format)
Definition: mythframe.h:399
MythRenderOpenGL::DeleteTexture
void DeleteTexture(MythGLTexture *Texture)
Definition: mythrenderopengl.cpp:716
GLSL300YUVFragmentExtensions
static const QString GLSL300YUVFragmentExtensions
Definition: mythopenglvideoshaders.h:309
MythVideoGPU::m_deinterlacer
MythDeintType m_deinterlacer
Definition: mythvideogpu.h:91
kStereoscopicModeTopAndBottomDiscard
@ kStereoscopicModeTopAndBottomDiscard
Definition: videoouttypes.h:139
MythOpenGLVideo::UpdateShaderParameters
void UpdateShaderParameters()
Definition: mythopenglvideo.cpp:96
MythRenderOpenGL::GetExtraFeatures
int GetExtraFeatures(void) const
Definition: mythrenderopengl.cpp:455
MythVideoGPU::m_outputType
VideoFrameType m_outputType
Definition: mythvideogpu.h:81
MythVideoColourSpace::GetDisplayGamma
float GetDisplayGamma(void) const
Definition: mythvideocolourspace.cpp:470
MythRenderOpenGL::DeleteShaderProgram
void DeleteShaderProgram(QOpenGLShaderProgram *Program)
Definition: mythrenderopengl.cpp:1465
MythOpenGLVideo::CleanupDeinterlacers
void CleanupDeinterlacers()
Definition: mythopenglvideo.cpp:135
uint
unsigned int uint
Definition: compat.h:81
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
MythVideoGPU::m_videoRect
QRect m_videoRect
Definition: mythvideogpu.h:86
kStereoscopicModeAuto
@ kStereoscopicModeAuto
Definition: videoouttypes.h:136
MythVideoGPU::Deinterlacer
@ Deinterlacer
Definition: mythvideogpu.h:28
MythVideoGPU::OutputChanged
void OutputChanged(QSize VideoDim, QSize VideoDispDim, float)
MythOpenGLVideo::VideoShaderType
VideoShaderType
Definition: mythopenglvideo.h:27
MythVideoGPU::m_stereoMode
StereoscopicMode m_stereoMode
Definition: mythvideogpu.h:96
MythVideoBounds
Definition: mythvideobounds.h:23
MythVideoFrame::FormatIs444
static bool FormatIs444(VideoFrameType Type)
Definition: mythframe.h:450
StereoscopicMode
StereoscopicMode
Definition: videoouttypes.h:134
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:906
MythRenderOpenGL::doneCurrent
void doneCurrent()
Definition: mythrenderopengl.cpp:574
MythVideoGPU::m_displayVideoRect
QRect m_displayVideoRect
Definition: mythvideogpu.h:85
MythRenderOpenGL::GetMaxTextureUnits
int GetMaxTextureUnits(void) const
Definition: mythrenderopengl.cpp:450
MythVideoFrame::FormatIs420
static bool FormatIs420(VideoFrameType Type)
Definition: mythframe.h:438
MythRenderOpenGL
Definition: mythrenderopengl.h:96
MythOpenGLVideo::Default
@ Default
Definition: mythopenglvideo.h:29
MythDeintType
MythDeintType
Definition: mythframe.h:67
MythOpenGLVideo::ShaderCount
@ ShaderCount
Definition: mythopenglvideo.h:34
MythOpenGLVideo::m_shaders
std::array< QOpenGLShaderProgram *, ShaderCount > m_shaders
Definition: mythopenglvideo.h:72
MythRenderOpenGL::BindFramebuffer
void BindFramebuffer(QOpenGLFramebufferObject *Framebuffer)
Definition: mythrenderopengl.cpp:785
MythVideoFrame::FormatDescription
static QString FormatDescription(VideoFrameType Type)
Definition: mythframe.cpp:368
MythOpenGLVideo::CreateVideoShader
bool CreateVideoShader(VideoShaderType Type, MythDeintType Deint=DEINT_NONE)
Create the appropriate shader for the operation Type.
Definition: mythopenglvideo.cpp:298
kScan_Interlaced
@ kScan_Interlaced
Definition: videoouttypes.h:98
FMT_YUY2
@ FMT_YUY2
Definition: mythframe.h:51
YUVFragmentExtensions
static const QString YUVFragmentExtensions
Definition: mythopenglvideoshaders.h:41
MythOpenGLTonemap::GetTexture
MythVideoTextureOpenGL * GetTexture()
Definition: mythopengltonemap.cpp:68
MythVideoFrame::DeinterlacerName
static QString DeinterlacerName(MythDeintType Deint, bool DoubleRate, VideoFrameType Format=FMT_NONE)
Definition: mythframe.cpp:462
MythVideoTextureOpenGL::DeleteTextures
static void DeleteTextures(MythRenderOpenGL *Context, std::vector< MythVideoTextureOpenGL * > &Textures)
Definition: mythvideotextureopengl.cpp:31
DEINT_HIGH
@ DEINT_HIGH
Definition: mythframe.h:72
MythVideoTextureOpenGL::CreateVideoFrameBuffer
static VideoFramebuffer CreateVideoFrameBuffer(MythRenderOpenGL *Context, VideoFrameType OutputType, QSize Size, bool HighPrecision=true)
Definition: mythvideotextureopengl.cpp:583
mythavutil.h
MythRenderOpenGL::SetTextureFilters
void SetTextureFilters(MythGLTexture *Texture, QOpenGLTexture::Filter Filter, QOpenGLTexture::WrapMode Wrap=QOpenGLTexture::ClampToEdge)
Definition: mythrenderopengl.cpp:679
mythcontext.h
MythOpenGLVideo::m_nextTextures
std::vector< MythVideoTextureOpenGL * > m_nextTextures
Definition: mythopenglvideo.h:76
MythVideoFrame::GetNumPlanes
static uint GetNumPlanes(VideoFrameType Type)
Definition: mythframe.h:214
MythVideoColourSpace::GetPrimaryMatrix
QMatrix4x4 GetPrimaryMatrix(void)
Definition: mythvideocolourspace.cpp:460
MythVideoGPU::m_valid
bool m_valid
Definition: mythvideogpu.h:93
DefaultVertexShader
static const QString DefaultVertexShader
Definition: mythopenglvideoshaders.h:6
YUVFragmentShader
static const QString YUVFragmentShader
Definition: mythopenglvideoshaders.h:56
MythOpenGLVideo::BicubicUpsize
@ BicubicUpsize
Definition: mythopenglvideo.h:33
MythVideoGPU::ResetFrameFormat
virtual void ResetFrameFormat()
Definition: mythvideogpu.cpp:98
VideoFrameType
VideoFrameType
Definition: mythframe.h:20
MythVideoGPU::UpdateColourSpace
void UpdateColourSpace(bool PrimariesChanged)
Definition: mythvideogpu.cpp:60
MythRenderOpenGL::SetViewPort
void SetViewPort(QRect Rect, bool ViewportOnly=false) override
Definition: mythrenderopengl.cpp:584
MythVideoProfilePtr
std::shared_ptr< MythVideoProfile > MythVideoProfilePtr
Definition: mythvideogpu.h:18
MythOpenGLVideo::m_extraFeatures
int m_extraFeatures
Definition: mythopenglvideo.h:80
MythVideoGPU::m_deinterlacer2x
bool m_deinterlacer2x
Definition: mythvideogpu.h:92
MythVideoGPU::None
@ None
Definition: mythvideogpu.h:27
MythVideoFrame
Definition: mythframe.h:88
RGBFragmentShader
static const QString RGBFragmentShader
Definition: mythopenglvideoshaders.h:17
FMT_NV12
@ FMT_NV12
Definition: mythframe.h:53
DEINT_BASIC
@ DEINT_BASIC
Definition: mythframe.h:70
MythVideoGPU::m_masterViewportSize
QSize m_masterViewportSize
Definition: mythvideogpu.h:84
is_interlaced
bool is_interlaced(FrameScanType Scan)
Definition: videoouttypes.h:188
MythVideoFrame::FormatIsNV12
static bool FormatIsNV12(VideoFrameType Type)
Definition: mythframe.h:456
MythOpenGLVideo::m_shaderCost
std::array< int, ShaderCount > m_shaderCost
Definition: mythopenglvideo.h:73
kStereoscopicModeSideBySideDiscard
@ kStereoscopicModeSideBySideDiscard
Definition: videoouttypes.h:138
kGLTiled
@ kGLTiled
Definition: mythrenderopengl.h:46
MythVideoColourSpace
MythVideoColourSpace contains a QMatrix4x4 that can convert YCbCr data to RGB.
Definition: mythvideocolourspace.h:18
MythVideoGPU::m_inputType
VideoFrameType m_inputType
Definition: mythvideogpu.h:80
MythVideoTextureOpenGL::CreateTextures
static std::vector< MythVideoTextureOpenGL * > CreateTextures(MythRenderOpenGL *Context, VideoFrameType Type, VideoFrameType Format, std::vector< QSize > Sizes, GLenum Target=QOpenGLTexture::Target2D)
Create a set of textures suitable for the given Type and Format.
Definition: mythvideotextureopengl.cpp:57
GLSL300YUVFragmentShader
static const QString GLSL300YUVFragmentShader
Definition: mythopenglvideoshaders.h:316
find
static pid_list_t::iterator find(const PIDInfoMap &map, pid_list_t &list, pid_list_t::iterator begin, pid_list_t::iterator end, bool find_open)
Definition: dvbstreamhandler.cpp:363
MythOpenGLInterop::Retrieve
static std::vector< MythVideoTextureOpenGL * > Retrieve(MythRenderOpenGL *Context, MythVideoColourSpace *ColourSpace, MythVideoFrame *Frame, FrameScanType Scan)
Definition: mythopenglinterop.cpp:69
MythVideoGPU::Performance
@ Performance
Definition: mythvideogpu.h:30
MythRenderOpenGL::CreateShaderProgram
QOpenGLShaderProgram * CreateShaderProgram(const QString &Vertex, const QString &Fragment)
Definition: mythrenderopengl.cpp:1416
MythRenderOpenGL::EnableShaderProgram
bool EnableShaderProgram(QOpenGLShaderProgram *Program)
Definition: mythrenderopengl.cpp:1475
FMT_RGBA32
@ FMT_RGBA32
Definition: mythframe.h:35
MythOpenGLVideo::GetProfile
QString GetProfile() const override
Definition: mythopenglvideo.cpp:128
MythOpenGLVideo::ResetFrameFormat
void ResetFrameFormat() override
Definition: mythopenglvideo.cpp:531
MythVideoGPU::Framebuffer
@ Framebuffer
Definition: mythvideogpu.h:31
OpenGLLocker
Definition: mythrenderopengl.h:255