MythTV  master
mythopenglvideo.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QPen>
3 
4 // MythTV
5 #include "mythcontext.h"
6 #include "tv.h"
8 #include "mythavutil.h"
11 #include "opengl/mythopenglvideo.h"
12 
13 // std
14 #include <utility>
15 
16 // FFmpeg
17 extern "C" {
18 #include "libavutil/stereo3d.h"
19 }
20 
21 #define LOC QString("GLVid: ")
22 #define 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  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  vector<QSize> sizes;
268  sizes.emplace_back(QSize(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 : qAsConst(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 : qAsConst(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  .arg(m_videoDim.width()).arg(m_videoDim.height()).arg(texold)
482  .arg(MythVideoFrame::FormatDescription(InputType))
483  .arg(MythVideoFrame::FormatDescription(OutputType))
484  .arg(Size.width()).arg(Size.height()).arg(texnew));
485 
487 
488  m_inputType = InputType;
489  m_outputType = OutputType;
490  m_textureTarget = TextureTarget;
491  m_videoDim = Size;
492 
493  // This is only currently needed for RGBA32 frames from composed DRM_PRIME
494  // textures that may be half height for simple bob deinterlacing
496  emit OutputChanged(m_videoDim, m_videoDim, -1.0F);
497 
498  if (!MythVideoFrame::HardwareFormat(InputType))
499  {
500  vector<QSize> sizes;
501  sizes.push_back(Size);
503  if (m_inputTextures.empty())
504  {
505  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create input textures");
506  return false;
507  }
508 
509  m_inputTextureSize = m_inputTextures[0]->m_totalSize;
510  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Created %1 input textures for '%2'")
511  .arg(m_inputTextures.size()).arg(GetProfile()));
512  }
513  else
514  {
515  m_inputTextureSize = Size;
516  }
517 
518  // Create shaders
520  return false;
521 
522  UpdateColourSpace(false);
524  return true;
525 }
526 
528 {
529  for (auto & shader : m_shaders)
530  if (shader)
532  m_shaders.fill(nullptr);
533  m_shaderCost.fill(1);
537  m_textureTarget = QOpenGLTexture::Target2D;
541  m_frameBuffer = nullptr;
542  m_frameBufferTexture = nullptr;
543 
545 }
546 
549 {
550  if (Frame->m_type == FMT_NONE)
551  return;
552 
553  // Hardware frames are retrieved/updated in PrepareFrame but we need to
554  // reset software frames now if necessary
556  {
558  {
559  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Resetting input format");
561  }
562  return;
563  }
564 
565  // Sanitise frame
566  if ((Frame->m_width < 1) || (Frame->m_height < 1) || !Frame->m_buffer)
567  {
568  LOG(VB_GENERAL, LOG_ERR, LOC + "Invalid software frame");
569  return;
570  }
571 
572  // Can we render this frame format
573  if (!MythVideoFrame::YUVFormat(Frame->m_type))
574  {
575  LOG(VB_GENERAL, LOG_ERR, LOC + "Frame format is not supported");
576  return;
577  }
578 
579  // lock
580  OpenGLLocker ctx_lock(m_openglRender);
581 
582  // check for input changes
583  if ((Frame->m_width != m_videoDim.width()) ||
584  (Frame->m_height != m_videoDim.height()) ||
585  (Frame->m_type != m_inputType))
586  {
587  VideoFrameType frametype = Frame->m_type;
588  if ((frametype == FMT_YV12) && (m_profile == "opengl"))
589  frametype = FMT_YUY2;
590  QSize size(Frame->m_width, Frame->m_height);
591  if (!SetupFrameFormat(Frame->m_type, frametype, size, QOpenGLTexture::Target2D))
592  return;
593  }
594 
595  // Setup deinterlacing if required
596  AddDeinterlacer(Frame, Scan);
597 
598  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
599  m_openglRender->logDebugMarker(LOC + "UPDATE_FRAME_START");
600 
602 
603  // Rotate textures if necessary
604  bool current = true;
606  {
607  if (!m_nextTextures.empty() && !m_prevTextures.empty())
608  {
609  if (qAbs(Frame->m_frameCounter - m_discontinuityCounter) > 1)
610  ResetTextures();
611  vector<MythVideoTextureOpenGL*> temp = m_prevTextures;
614  m_nextTextures = temp;
615  current = false;
616  }
617  }
618 
619  m_discontinuityCounter = Frame->m_frameCounter;
620 
622  {
623  // first field. Fake the pitches
624  FramePitches pitches = Frame->m_pitches;
625  Frame->m_pitches[0] = Frame->m_pitches[0] << 1;
626  Frame->m_pitches[1] = Frame->m_pitches[1] << 1;
627  Frame->m_pitches[2] = Frame->m_pitches[2] << 1;
629  // second field. Fake the offsets as well.
630  FrameOffsets offsets = Frame->m_offsets;
631  Frame->m_offsets[0] = Frame->m_offsets[0] + pitches[0];
632  Frame->m_offsets[1] = Frame->m_offsets[1] + pitches[1];
633  Frame->m_offsets[2] = Frame->m_offsets[2] + pitches[2];
635  Frame->m_pitches = pitches;
636  Frame->m_offsets = offsets;
637  }
638  else
639  {
641  }
642 
643  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
644  m_openglRender->logDebugMarker(LOC + "UPDATE_FRAME_END");
645 }
646 
648  StereoscopicMode StereoOverride, bool DrawBorder)
649 {
650  if (!m_openglRender)
651  return;
652 
654 
655  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
656  m_openglRender->logDebugMarker(LOC + "RENDER_FRAME_START");
657 
658  // Set required input textures for the last stage
659  // ProcessFrame is always called first, which will create/destroy software
660  // textures as needed
661  bool hwframes = false;
662  bool useframebufferimage = false;
663 
664  // for tiled renderers (e.g. Pi), enable scissoring to try and improve performance
665  // when not full screen and avoid the resize stage unless absolutely necessary
666  bool tiled = m_extraFeatures & kGLTiled;
667 
668  // We lose the pause frame when seeking and using VDPAU/VAAPI/NVDEC direct rendering.
669  // As a workaround, we always use the resize stage so the last displayed frame
670  // should be retained in the Framebuffer used for resizing. If there is
671  // nothing to display, then fallback to this framebuffer.
672  // N.B. this is now strictly necessary with v4l2 and DRM PRIME direct rendering
673  // but ignore now for performance reasons
674  VideoResizing resize = Frame ? (MythVideoFrame::HardwareFramesFormat(Frame->m_type) ? Framebuffer : None) :
676 
677  vector<MythVideoTextureOpenGL*> inputtextures = m_inputTextures;
678  if (inputtextures.empty())
679  {
680  // This is experimental support for direct rendering to a framebuffer (e.g. DRM).
681  // It may be removed or refactored (e.g. pass presentation details through to
682  // the interop).
683  if (Frame)
684  {
685  Frame->m_displayed = false;
686  Frame->m_srcRect = m_videoRect;
687  Frame->m_dstRect = m_displayVideoRect;
688  }
689 
690  // Pull in any hardware frames
692 
693  if (Frame && Frame->m_displayed)
694  return;
695 
696  if (!inputtextures.empty())
697  {
698  hwframes = true;
699  QSize newsize = inputtextures[0]->m_size;
700  VideoFrameType newsourcetype = inputtextures[0]->m_frameType;
701  VideoFrameType newtargettype = inputtextures[0]->m_frameFormat;
702  GLenum newtargettexture = inputtextures[0]->m_target;
703  if ((m_outputType != newtargettype) || (m_textureTarget != newtargettexture) ||
704  (m_inputType != newsourcetype) || (newsize != m_inputTextureSize))
705  {
706  SetupFrameFormat(newsourcetype, newtargettype, newsize, newtargettexture);
707  }
708 
709 #ifdef USING_MEDIACODEC
710  // Set the texture transform for mediacodec
712  {
713  if (inputtextures[0]->m_transform && m_shaders[Default])
714  {
716  m_shaders[Default]->setUniformValue("u_transform", *inputtextures[0]->m_transform);
717  }
718  }
719 #endif
720  // Enable deinterlacing for NVDEC, VTB and VAAPI DRM if VPP is not available
721  if (inputtextures[0]->m_allowGLSLDeint)
722  AddDeinterlacer(Frame, Scan, DEINT_SHADER | DEINT_CPU, false); // pickup shader or cpu prefs
723  }
724  else
725  {
726  if ((resize == Framebuffer) && m_frameBuffer && m_frameBufferTexture)
727  {
728  LOG(VB_PLAYBACK, LOG_DEBUG, "Using existing framebuffer");
729  useframebufferimage = true;
730  }
731  else
732  {
733  LOG(VB_PLAYBACK, LOG_DEBUG, LOC + "Nothing to display");
734  // if this is live tv startup and the window rect has changed we
735  // must set the viewport
737  return;
738  }
739  }
740  }
741 
742  // Determine which shader to use. This helps optimise the resize check.
743  bool deinterlacing = false;
744  bool basicdeinterlacing = false;
745  bool yuvoutput = MythVideoFrame::YUVFormat(m_outputType);
746  VideoShaderType program = yuvoutput ? Progressive : Default;
747  if (m_deinterlacer != DEINT_NONE)
748  {
749  if (Scan == kScan_Interlaced)
750  {
751  program = TopFieldFirst ? InterlacedTop : InterlacedBot;
752  deinterlacing = true;
753  }
754  else if (Scan == kScan_Intr2ndField)
755  {
756  program = TopFieldFirst ? InterlacedBot : InterlacedTop;
757  deinterlacing = true;
758  }
759 
760  // select the correct field for the basic deinterlacer
762  {
763  basicdeinterlacing = true;
764  if (program == InterlacedBot)
765  inputtextures = m_nextTextures;
766  }
767  }
768 
769  // Set deinterlacer type for debug OSD
770  if (deinterlacing && Frame)
771  {
772  Frame->m_deinterlaceInuse = m_deinterlacer | DEINT_SHADER;
773  Frame->m_deinterlaceInuse2x = m_deinterlacer2x;
774  }
775 
776  // Tonemapping can only render to a texture
777  if (m_toneMap)
778  resize |= ToneMap;
779 
780  // Decide whether to use render to texture - for performance or quality
781  if (yuvoutput && !resize)
782  {
783  // ensure deinterlacing works correctly when down scaling in height
784  // N.B. not needed for the basic deinterlacer
785  if (deinterlacing && !basicdeinterlacing && (m_videoDispDim.height() > m_displayVideoRect.height()))
786  resize |= Deinterlacer;
787 
788  // NB GL_NEAREST introduces some 'minor' chroma sampling errors
789  // for the following 2 cases. For YUY2 this may be better handled in the
790  // shader. For GLES3.0 10bit textures - Vulkan is probably the better solution.
791 
792  // UYVY packed pixels must be sampled exactly with GL_NEAREST
793  if (FMT_YUY2 == m_outputType)
794  resize |= Sampling;
795  // unsigned integer texture formats need GL_NEAREST sampling
796  if ((m_gles > 2) && (MythVideoFrame::ColorDepth(m_inputType) > 8))
797  resize |= Sampling;
798 
799  // don't enable resizing if the cost of a framebuffer switch may be
800  // prohibitive (e.g. Raspberry Pi/tiled renderers) or for basic deinterlacing,
801  // where we are trying to simplify/optimise rendering (and the framebuffer
802  // sizing gets confused by the change to m_videoDispDim)
803  if (!resize && !tiled && !basicdeinterlacing)
804  {
805  // improve performance. This is an educated guess on the relative cost
806  // of render to texture versus straight rendering.
807  int totexture = m_videoDispDim.width() * m_videoDispDim.height() * m_shaderCost[program];
808  int blitcost = m_displayVideoRect.width() * m_displayVideoRect.height() * m_shaderCost[Default];
809  int noresizecost = m_displayVideoRect.width() * m_displayVideoRect.height() * m_shaderCost[program];
810  if ((totexture + blitcost) < noresizecost)
811  resize |= Performance;
812  }
813  }
814 
815  // Bicubic upsizing - test this after all other resize options have been checked
816  // to ensure it is not the only flag set
817  if (m_bicubicUpsize)
818  SetupBicubic(resize);
819 
820  // We don't need an extra stage prior to bicubic if the frame is already RGB (e.g. VDPAU, MediaCodec)
821  // So bypass if we only set resize for bicubic.
822  bool needresize = resize && !(MythVideoFrame::FormatIsRGB(m_outputType) && (resize == Bicubic));
823 
824  // set software frame filtering if resizing has changed
825  if (!needresize && m_resizing)
826  {
827  // remove framebuffer
829  {
831  m_frameBufferTexture = nullptr;
832  }
833  if (m_frameBuffer)
834  {
836  m_frameBuffer = nullptr;
837  }
838  // set filtering
842  m_resizing = None;
843  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Disabled resizing");
844  }
845  else if (!m_resizing && needresize)
846  {
847  // framebuffer will be created as needed below
848  QOpenGLTexture::Filter filter = ((resize & Sampling) == Sampling) ? QOpenGLTexture::Nearest : QOpenGLTexture::Linear;
852  m_resizing = resize;
853  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Resizing from %1x%2 to %3x%4 for %5")
854  .arg(m_videoDispDim.width()).arg(m_videoDispDim.height())
855  .arg(m_displayVideoRect.width()).arg(m_displayVideoRect.height())
856  .arg(VideoResizeToString(resize)));
857  }
858 
859  // check hardware frames have the correct filtering
860  if (hwframes)
861  {
862  QOpenGLTexture::Filter filter = (resize.testFlag(Sampling)) ? QOpenGLTexture::Nearest : QOpenGLTexture::Linear;
863  if (inputtextures[0]->m_filter != filter)
865  }
866 
867  // texture coordinates
868  QRect trect(m_videoRect);
869 
870  if (needresize)
871  {
872  MythVideoTextureOpenGL* nexttexture = nullptr;
873 
874  // only render to the framebuffer if there is something to update
875  if (useframebufferimage)
876  {
877  if (m_toneMap)
878  {
879  nexttexture = m_toneMap->GetTexture();
880  trect = QRect(QPoint(0, 0), m_displayVideoRect.size());
881  }
882  else
883  {
884  nexttexture = m_frameBufferTexture;
885  }
886  }
887  else if (m_toneMap)
888  {
889  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
890  m_openglRender->logDebugMarker(LOC + "RENDER_TO_TEXTURE");
891  nexttexture = m_toneMap->Map(inputtextures, m_displayVideoRect.size());
892  trect = QRect(QPoint(0, 0), m_displayVideoRect.size());
893  }
894  else
895  {
896  // render to texture stage
897  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
898  m_openglRender->logDebugMarker(LOC + "RENDER_TO_TEXTURE");
899 
900  // we need a framebuffer and associated texture
901  if (!m_frameBuffer)
902  {
904  (fbo != nullptr) && (tex != nullptr))
905  {
906  delete m_frameBuffer;
907  delete m_frameBufferTexture;
908  m_frameBuffer = fbo;
909  m_frameBufferTexture = tex;
910  m_openglRender->SetTextureFilters(m_frameBufferTexture, QOpenGLTexture::Linear);
911  }
912  }
913 
915  return;
916 
917  // coordinates
918  QRect vrect(QPoint(0, 0), m_videoDispDim);
919  QRect trect2 = vrect;
920  if (FMT_YUY2 == m_outputType)
921  trect2.setWidth(m_videoDispDim.width() >> 1);
922 
923  // framebuffer
925  m_openglRender->SetViewPort(vrect);
926 
927  // bind correct textures
928  vector<MythGLTexture*> textures {};
929  BindTextures(deinterlacing, inputtextures, textures);
930 
931  // render
932  m_openglRender->DrawBitmap(textures, m_frameBuffer, trect2, vrect,
933  m_shaders[program], 0);
934  nexttexture = m_frameBufferTexture;
935  }
936 
937  // reset for next stage
938  inputtextures.clear();
939  inputtextures.push_back(nexttexture);
940  program = Default;
941  deinterlacing = false;
942  }
943 
944  // Use the bicubic shader if necessary
945  if (resize.testFlag(Bicubic))
946  program = BicubicUpsize;
947 
948  // render to default framebuffer/screen
949  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
950  m_openglRender->logDebugMarker(LOC + "RENDER_TO_SCREEN");
951 
952  // discard stereoscopic fields
953  StereoscopicMode stereo = StereoOverride;
954  m_lastStereo = Frame ? Frame->m_stereo3D : m_lastStereo;
955  // N.B. kStereoscopicModeSideBySideDiscard is a proxy here for discard of all types
956  if ((stereo == kStereoscopicModeAuto) &&
958  (m_lastStereo != AV_STEREO3D_2D))
959  {
960  if (m_lastStereo == AV_STEREO3D_SIDEBYSIDE)
962  else if (m_lastStereo == AV_STEREO3D_TOPBOTTOM)
964  }
965 
967  trect = QRect(trect.left() >> 1, trect.top(), trect.width() >> 1, trect.height());
968  else if (kStereoscopicModeTopAndBottomDiscard == stereo)
969  trect = QRect(trect.left(), trect.top() >> 1, trect.width(), trect.height() >> 1);
970 
971  // bind default framebuffer
974 
975  // PiP border
976  if (DrawBorder)
977  {
978  QRect piprect = m_displayVideoRect.adjusted(-10, -10, +10, +10);
979  static const QPen kNopen(Qt::NoPen);
980  static const QBrush kRedBrush(QBrush(QColor(127, 0, 0, 255)));
981  m_openglRender->DrawRect(nullptr, piprect, kRedBrush, kNopen, 255);
982  }
983 
984  // bind correct textures
985  vector<MythGLTexture*> textures;
986  BindTextures(deinterlacing, inputtextures, textures);
987 
988  // rotation
989  if (Frame)
990  m_lastRotation = Frame->m_rotation;
991 
992  // apply scissoring
993  if (tiled)
994  {
995  // N.B. It's not obvious whether this helps
996  m_openglRender->glEnable(GL_SCISSOR_TEST);
997  m_openglRender->glScissor(m_displayVideoRect.left() - 1, m_displayVideoRect.top() - 1,
998  m_displayVideoRect.width() + 2, m_displayVideoRect.height() + 2);
999  }
1000 
1001  // draw
1002  m_openglRender->DrawBitmap(textures, nullptr, trect, m_displayVideoRect,
1003  m_shaders[program], m_lastRotation);
1004 
1005  // disable scissoring
1006  if (tiled)
1007  m_openglRender->glDisable(GL_SCISSOR_TEST);
1008 
1009  if (VERBOSE_LEVEL_CHECK(VB_GPU, LOG_INFO))
1010  m_openglRender->logDebugMarker(LOC + "RENDER_FRAME_END");
1011 }
1012 
1015 {
1016  for (auto & texture : m_inputTextures)
1017  texture->m_valid = false;
1018  for (auto & texture : m_prevTextures)
1019  texture->m_valid = false;
1020  for (auto & texture : m_nextTextures)
1021  texture->m_valid = false;
1022 }
1023 
1024 void MythOpenGLVideo::BindTextures(bool Deinterlacing, vector<MythVideoTextureOpenGL*>& Current,
1025  vector<MythGLTexture*>& Textures)
1026 {
1027  if (Deinterlacing && !MythVideoFrame::HardwareFormat(m_inputType))
1028  {
1029  if ((m_nextTextures.size() == Current.size()) && (m_prevTextures.size() == Current.size()))
1030  {
1031  // if we are using reference frames, we want the current frame in the middle
1032  // but next will be the first valid, followed by current...
1033  size_t count = Current.size();
1034  vector<MythVideoTextureOpenGL*>& current = Current[0]->m_valid ? Current : m_nextTextures;
1035  vector<MythVideoTextureOpenGL*>& prev = m_prevTextures[0]->m_valid ? m_prevTextures : current;
1036 
1037  for (uint i = 0; i < count; ++i)
1038  Textures.push_back(reinterpret_cast<MythGLTexture*>(prev[i]));
1039  for (uint i = 0; i < count; ++i)
1040  Textures.push_back(reinterpret_cast<MythGLTexture*>(current[i]));
1041  for (uint i = 0; i < count; ++i)
1042  Textures.push_back(reinterpret_cast<MythGLTexture*>(m_nextTextures[i]));
1043  return;
1044  }
1045  }
1046 
1047  std::transform(Current.cbegin(), Current.cend(), std::back_inserter(Textures),
1048  [](MythVideoTextureOpenGL* Tex) { return reinterpret_cast<MythGLTexture*>(Tex); });
1049 }
1050 
1052 {
1054  return "opengl-hw";
1055 
1056  switch (Type)
1057  {
1058  case FMT_YUY2: return "opengl"; // compatibility with old profiles
1059  case FMT_YV12: return "opengl-yv12";
1060  case FMT_NV12: return "opengl-nv12";
1061  default: break;
1062  }
1063  return "opengl";
1064 }
1065 
1066 void MythOpenGLVideo::SetupBicubic(VideoResizing& Resize)
1067 {
1068  if (((m_videoDispDim.width() < m_displayVideoRect.width()) ||
1069  (m_videoDispDim.height() < m_displayVideoRect.height())))
1070  {
1071  if (!m_shaders[BicubicUpsize])
1072  {
1074  {
1075  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create bicubic shader. Disabling");
1076  m_bicubicUpsize = false;
1077  }
1078  else
1079  {
1081  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Created bicubic sampler");
1082  }
1083  }
1084 
1085  if (m_shaders[BicubicUpsize])
1086  Resize |= Bicubic;
1087  }
1088  else
1089  {
1090  if (m_shaders[BicubicUpsize] != nullptr)
1091  {
1092  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Disabling bicubic sampler");
1093  delete m_shaders[BicubicUpsize];
1094  m_shaders[BicubicUpsize] = nullptr;
1095  }
1096  }
1097 }
FMT_MEDIACODEC
@ FMT_MEDIACODEC
Definition: mythframe.h:61
MythOpenGLVideo::m_toneMap
MythOpenGLTonemap * m_toneMap
Definition: mythopenglvideo.h:85
DEINT_DRIVER
@ DEINT_DRIVER
Definition: mythframe.h:75
MythOpenGLVideo::m_inputTextures
vector< MythVideoTextureOpenGL * > m_inputTextures
Definition: mythopenglvideo.h:76
tv.h
MythVideoGPU::m_discontinuityCounter
uint64_t m_discontinuityCounter
Definition: mythvideogpu.h:72
MythOpenGLVideo::m_gles
int m_gles
Definition: mythopenglvideo.h:72
MythGLTexture
Definition: mythrenderopengl.h:55
DEINT_MEDIUM
@ DEINT_MEDIUM
Definition: mythframe.h:71
MythVideoGPU::m_lastStereo
uint m_lastStereo
Definition: mythvideogpu.h:89
MythVideoGPU::m_inputTextureSize
QSize m_inputTextureSize
Definition: mythvideogpu.h:82
MythVideoGPU::Sampling
@ Sampling
Definition: mythvideogpu.h:29
MythOpenGLVideo::m_prevTextures
vector< MythVideoTextureOpenGL * > m_prevTextures
Definition: mythopenglvideo.h:77
MythOpenGLVideo::InterlacedTop
@ InterlacedTop
Definition: mythopenglvideo.h:33
MythRenderOpenGL::DeleteFramebuffer
void DeleteFramebuffer(QOpenGLFramebufferObject *Framebuffer)
Definition: mythrenderopengl.cpp:772
DEINT_SHADER
@ DEINT_SHADER
Definition: mythframe.h:74
MythVideoTextureOpenGL
Definition: mythvideotextureopengl.h:21
MythOpenGLVideo::BindTextures
void BindTextures(bool Deinterlacing, vector< MythVideoTextureOpenGL * > &Current, vector< MythGLTexture * > &Textures)
Definition: mythopenglvideo.cpp:1024
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:74
MythVideoGPU::m_lastRotation
int m_lastRotation
Definition: mythvideogpu.h:84
MythOpenGLVideo::ResetTextures
void ResetTextures() override
Clear reference frames after a seek as they will contain old images.
Definition: mythopenglvideo.cpp:1014
MythOpenGLVideo::m_frameBufferTexture
MythVideoTextureOpenGL * m_frameBufferTexture
Definition: mythopenglvideo.h:80
MythVideoGPU::m_resizing
VideoResizing m_resizing
Definition: mythvideogpu.h:83
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
DEINT_NONE
@ DEINT_NONE
Definition: mythframe.h:69
MythVideoGPU::m_videoColourSpace
MythVideoColourSpace * m_videoColourSpace
Definition: mythvideogpu.h:81
MythOpenGLVideo::~MythOpenGLVideo
~MythOpenGLVideo() override
Definition: mythopenglvideo.cpp:59
arg
arg(title).arg(filename).arg(doDelete))
FrameScanType
FrameScanType
Definition: videoouttypes.h:94
MythVideoGPU::m_bicubicUpsize
bool m_bicubicUpsize
Definition: mythvideogpu.h:91
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:809
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
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:548
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:77
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:10
MythRenderOpenGL::GetFeatures
QOpenGLFunctions::OpenGLFeatures GetFeatures(void) const
Definition: mythrenderopengl.cpp:457
MythOpenGLVideo::m_fallbackDeinterlacer
MythDeintType m_fallbackDeinterlacer
Definition: mythopenglvideo.h:73
MythRenderOpenGL::SetShaderProgramParams
void SetShaderProgramParams(QOpenGLShaderProgram *Program, const QMatrix4x4 &Value, const char *Uniform)
Definition: mythrenderopengl.cpp:1475
MythOpenGLVideo::m_frameBuffer
QOpenGLFramebufferObject * m_frameBuffer
Definition: mythopenglvideo.h:79
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:441
mythrenderopengl.h
MythVideoFrame::YUVFormat
static bool YUVFormat(VideoFrameType Type)
Definition: mythframe.h:466
MythOpenGLVideo::m_features
QOpenGLFunctions::OpenGLFeatures m_features
Definition: mythopenglvideo.h:81
kScan_Intr2ndField
@ kScan_Intr2ndField
Definition: videoouttypes.h:99
MythVideoGPU::m_profile
QString m_profile
Definition: mythvideogpu.h:73
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:71
MythOpenGLVideo::InterlacedBot
@ InterlacedBot
Definition: mythopenglvideo.h:34
MythRenderOpenGL::DrawRect
void DrawRect(QOpenGLFramebufferObject *Target, QRect Area, const QBrush &FillBrush, const QPen &LinePen, int Alpha)
Definition: mythrenderopengl.cpp:955
MythVideoGPU::m_videoDispDim
QSize m_videoDispDim
Definition: mythvideogpu.h:76
mythopengltonemap.h
FMT_YV12
@ FMT_YV12
Definition: mythframe.h:24
MythOpenGLVideo::TypeToProfile
static QString TypeToProfile(VideoFrameType Type)
Definition: mythopenglvideo.cpp:1051
MythOpenGLVideo::RenderFrame
void RenderFrame(MythVideoFrame *Frame, bool TopFieldFirst, FrameScanType Scan, StereoscopicMode StereoOverride, bool DrawBorder=false) override
Definition: mythopenglvideo.cpp:647
MythOpenGLVideo::m_chromaUpsamplingFilter
bool m_chromaUpsamplingFilter
Definition: mythopenglvideo.h:84
MythOpenGLVideo::SetupBicubic
void SetupBicubic(VideoResizing &Resize)
Definition: mythopenglvideo.cpp:1066
MythOpenGLVideo::m_textureTarget
GLenum m_textureTarget
Definition: mythopenglvideo.h:83
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:464
GLSL300VertexShader
static const QString GLSL300VertexShader
Definition: mythopenglvideoshaders.h:298
MythOpenGLVideo::Progressive
@ Progressive
Definition: mythopenglvideo.h:32
MythVideoGPU::VideoResizeToString
static QString VideoResizeToString(VideoResizing Resize)
Definition: mythvideogpu.cpp:106
MythRenderOpenGL::makeCurrent
void makeCurrent()
Definition: mythrenderopengl.cpp:563
MythVideoFrame::ColorDepth
static int ColorDepth(int Format)
Definition: mythframe.h:399
MythRenderOpenGL::DeleteTexture
void DeleteTexture(MythGLTexture *Texture)
Definition: mythrenderopengl.cpp:713
GLSL300YUVFragmentExtensions
static const QString GLSL300YUVFragmentExtensions
Definition: mythopenglvideoshaders.h:309
MythVideoGPU::m_deinterlacer
MythDeintType m_deinterlacer
Definition: mythvideogpu.h:85
kStereoscopicModeTopAndBottomDiscard
@ kStereoscopicModeTopAndBottomDiscard
Definition: videoouttypes.h:139
MythOpenGLVideo::UpdateShaderParameters
void UpdateShaderParameters()
Definition: mythopenglvideo.cpp:96
MythRenderOpenGL::GetExtraFeatures
int GetExtraFeatures(void) const
Definition: mythrenderopengl.cpp:452
MythVideoGPU::m_outputType
VideoFrameType m_outputType
Definition: mythvideogpu.h:75
MythVideoColourSpace::GetDisplayGamma
float GetDisplayGamma(void) const
Definition: mythvideocolourspace.cpp:469
MythRenderOpenGL::DeleteShaderProgram
void DeleteShaderProgram(QOpenGLShaderProgram *Program)
Definition: mythrenderopengl.cpp:1441
MythOpenGLVideo::CleanupDeinterlacers
void CleanupDeinterlacers()
Definition: mythopenglvideo.cpp:135
uint
unsigned int uint
Definition: compat.h:140
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:60
MythVideoGPU::m_videoRect
QRect m_videoRect
Definition: mythvideogpu.h:80
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:29
MythOpenGLInterop::Retrieve
static vector< MythVideoTextureOpenGL * > Retrieve(MythRenderOpenGL *Context, MythVideoColourSpace *ColourSpace, MythVideoFrame *Frame, FrameScanType Scan)
Definition: mythopenglinterop.cpp:67
MythVideoGPU::m_stereoMode
StereoscopicMode m_stereoMode
Definition: mythvideogpu.h:90
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:926
MythRenderOpenGL::doneCurrent
void doneCurrent()
Definition: mythrenderopengl.cpp:571
MythVideoGPU::m_displayVideoRect
QRect m_displayVideoRect
Definition: mythvideogpu.h:79
MythRenderOpenGL::GetMaxTextureUnits
int GetMaxTextureUnits(void) const
Definition: mythrenderopengl.cpp:447
MythVideoFrame::FormatIs420
static bool FormatIs420(VideoFrameType Type)
Definition: mythframe.h:438
MythRenderOpenGL
Definition: mythrenderopengl.h:95
MythOpenGLVideo::Default
@ Default
Definition: mythopenglvideo.h:31
MythDeintType
MythDeintType
Definition: mythframe.h:67
MythOpenGLVideo::ShaderCount
@ ShaderCount
Definition: mythopenglvideo.h:36
VERBOSE_LEVEL_CHECK
#define VERBOSE_LEVEL_CHECK(_MASK_, _LEVEL_)
Definition: mythlogging.h:14
MythOpenGLVideo::m_shaders
std::array< QOpenGLShaderProgram *, ShaderCount > m_shaders
Definition: mythopenglvideo.h:74
MythRenderOpenGL::BindFramebuffer
void BindFramebuffer(QOpenGLFramebufferObject *Framebuffer)
Definition: mythrenderopengl.cpp:782
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:69
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:580
mythavutil.h
MythRenderOpenGL::SetTextureFilters
void SetTextureFilters(MythGLTexture *Texture, QOpenGLTexture::Filter Filter, QOpenGLTexture::WrapMode Wrap=QOpenGLTexture::ClampToEdge)
Definition: mythrenderopengl.cpp:676
mythcontext.h
MythVideoFrame::GetNumPlanes
static uint GetNumPlanes(VideoFrameType Type)
Definition: mythframe.h:214
MythVideoColourSpace::GetPrimaryMatrix
QMatrix4x4 GetPrimaryMatrix(void)
Definition: mythvideocolourspace.cpp:459
MythVideoGPU::m_valid
bool m_valid
Definition: mythvideogpu.h:87
DefaultVertexShader
static const QString DefaultVertexShader
Definition: mythopenglvideoshaders.h:6
YUVFragmentShader
static const QString YUVFragmentShader
Definition: mythopenglvideoshaders.h:56
MythOpenGLVideo::BicubicUpsize
@ BicubicUpsize
Definition: mythopenglvideo.h:35
MythVideoGPU::ResetFrameFormat
virtual void ResetFrameFormat()
Definition: mythvideogpu.cpp:96
VideoFrameType
VideoFrameType
Definition: mythframe.h:20
MythVideoGPU::UpdateColourSpace
void UpdateColourSpace(bool PrimariesChanged)
Definition: mythvideogpu.cpp:58
MythRenderOpenGL::SetViewPort
void SetViewPort(QRect Rect, bool ViewportOnly=false) override
Definition: mythrenderopengl.cpp:581
MythVideoProfilePtr
std::shared_ptr< MythVideoProfile > MythVideoProfilePtr
Definition: mythvideogpu.h:18
MythOpenGLVideo::m_extraFeatures
int m_extraFeatures
Definition: mythopenglvideo.h:82
MythVideoGPU::m_deinterlacer2x
bool m_deinterlacer2x
Definition: mythvideogpu.h:86
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:78
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:75
MythOpenGLVideo::m_nextTextures
vector< MythVideoTextureOpenGL * > m_nextTextures
Definition: mythopenglvideo.h:78
kStereoscopicModeSideBySideDiscard
@ kStereoscopicModeSideBySideDiscard
Definition: videoouttypes.h:138
kGLTiled
@ kGLTiled
Definition: mythrenderopengl.h:45
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:74
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:356
MythVideoGPU::Performance
@ Performance
Definition: mythvideogpu.h:30
MythRenderOpenGL::CreateShaderProgram
QOpenGLShaderProgram * CreateShaderProgram(const QString &Vertex, const QString &Fragment)
Definition: mythrenderopengl.cpp:1392
MythRenderOpenGL::EnableShaderProgram
bool EnableShaderProgram(QOpenGLShaderProgram *Program)
Definition: mythrenderopengl.cpp:1451
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:527
MythVideoGPU::Framebuffer
@ Framebuffer
Definition: mythvideogpu.h:31
OpenGLLocker
Definition: mythrenderopengl.h:253