Go to the documentation of this file.
18 #include "libavutil/stereo3d.h"
21 #define LOC QString("GLVid: ")
36 :
MythVideoGPU(Render, ColourSpace, Bounds, VideoProfile, Profile),
37 m_openglRender(Render)
41 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Fatal error");
55 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Chroma upsampling filter %1")
77 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Primaries conversion changed - recreating shaders");
90 m_shaders[i]->setUniformValue(
"m_colourGamma", colourgamma);
91 m_shaders[i]->setUniformValue(
"m_displayGamma", displaygamma);
107 QVector4D parameters(lineheight,
109 maxheight - lineheight,
117 m_shaders[i]->setUniformValue(
"m_frameData", parameters);
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);
145 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Removing single field textures");
159 bool CreateReferences )
188 deinterlacer =
Frame->GetSingleRateOption(Filter);
190 if (!deinterlacer || other)
228 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Forcing OpenGL YV12 for basic deinterlacer");
233 std::vector<QSize> sizes;
234 sizes.emplace_back(size);
240 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Created %1 single field textures")
248 uint refstocreate = ((deinterlacer ==
DEINT_HIGH) && CreateReferences) ? 2 : 0;
250 if (totaltextures > max)
253 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Insufficent texture units for deinterlacer '%1' (%2 < %3)")
256 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Falling back to '%1'")
267 std::vector<QSize> sizes;
284 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Created deinterlacer '%1' (%2->%3)")
319 for (
const QString& define : qAsConst(defines))
320 glsldefines += QString(
"#define MYTHTV_%1\n").arg(define);
323 #ifdef USING_MEDIACODEC
325 vertex = MediaCodecVertexShader;
339 static const QString glsl300(
"#version 300 es\n");
343 glsldefines.append(glsl300);
383 if (topfield && !basic)
384 defines <<
"TOPFIELD";
392 defines <<
"ONEFIELD";
395 case DEINT_MEDIUM: cost *= 5; defines <<
"LINEARBLEND";
break;
396 case DEINT_HIGH: cost *= 15; defines <<
"KERNEL"; kernel =
true;
break;
407 for (
int i = (kernel ? 2 : 0); (i >= 0) && count; i--)
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(
", "));
419 for (
int i = 1 ; i >= 0; i--)
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)
427 replacelist1 << QString(
"sampler2D kernelTexture%1%2").arg(i).arg(j);
428 replacelist2 << QString(
"kernelTexture%1%2").arg(i).arg(j);
430 fragment.replace(find1, replacelist1.join(
", "));
431 fragment.replace(find2, replacelist2.join(
", "));
439 for (
const QString& define : qAsConst(defines))
440 glsldefines += QString(
"#define MYTHTV_%1\n").arg(define);
453 QString glslsamplers;
454 for (
int i = start; i < end; ++i)
455 glslsamplers += QString(
"uniform sampler2D s_texture%1;\n").arg(i);
458 fragment = glsldefines + extensions + glslsamplers + fragment;
471 QSize Size, GLenum TextureTarget)
473 QString texnew = (TextureTarget == QOpenGLTexture::TargetRectangle) ?
"Rect" :
475 QString texold = (
m_textureTarget == QOpenGLTexture::TargetRectangle) ?
"Rect" :
477 LOG(VB_GENERAL, LOG_INFO,
LOC +
478 QString(
"New frame format: %1:%2 %3x%4 (Tex: %5) -> %6:%7 %8x%9 (Tex: %10)")
486 QString::number(Size.width()),
487 QString::number(Size.height()))
504 std::vector<QSize> sizes;
505 sizes.push_back(Size);
509 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create input textures");
514 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Created %1 input textures for '%2'")
563 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Resetting input format");
572 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid software frame");
579 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Frame format is not supported");
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;
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;
665 bool hwframes =
false;
666 bool useframebufferimage =
false;
682 if (inputtextures.empty())
689 Frame->m_displayed =
false;
700 if (!inputtextures.empty())
703 QSize newsize = inputtextures[0]->m_size;
706 GLenum newtargettexture = inputtextures[0]->m_target;
713 #ifdef USING_MEDIACODEC
720 m_shaders[
Default]->setUniformValue(
"u_transform", *inputtextures[0]->m_transform);
725 if (inputtextures[0]->m_allowGLSLDeint)
732 LOG(VB_PLAYBACK, LOG_DEBUG,
"Using existing framebuffer");
733 useframebufferimage =
true;
737 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC +
"Nothing to display");
747 bool deinterlacing =
false;
748 bool basicdeinterlacing =
false;
756 deinterlacing =
true;
761 deinterlacing =
true;
767 basicdeinterlacing =
true;
774 if (deinterlacing &&
Frame)
785 if (yuvoutput && !resize)
807 if (!resize && !tiled && !basicdeinterlacing)
814 if ((totexture + blitcost) < noresizecost)
847 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Disabled resizing");
852 QOpenGLTexture::Filter filter = ((resize &
Sampling) ==
Sampling) ? QOpenGLTexture::Nearest : QOpenGLTexture::Linear;
857 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Resizing from %1x%2 to %3x%4 for %5")
866 QOpenGLTexture::Filter filter = (resize.testFlag(
Sampling)) ? QOpenGLTexture::Nearest : QOpenGLTexture::Linear;
867 if (inputtextures[0]->m_filter != filter)
879 if (useframebufferimage)
908 (fbo !=
nullptr) && (tex !=
nullptr))
923 QRect trect2 = vrect;
932 std::vector<MythGLTexture*> textures {};
942 inputtextures.clear();
943 inputtextures.push_back(nexttexture);
945 deinterlacing =
false;
971 trect = QRect(trect.left() >> 1, trect.top(), trect.width() >> 1, trect.height());
973 trect = QRect(trect.left(), trect.top() >> 1, trect.width(), trect.height() >> 1);
983 static const QPen kNopen(Qt::NoPen);
984 static const QBrush kRedBrush(QBrush(QColor(127, 0, 0, 255)));
989 std::vector<MythGLTexture*> textures;
1021 texture->m_valid =
false;
1023 texture->m_valid =
false;
1025 texture->m_valid =
false;
1029 std::vector<MythGLTexture*>& Textures)
1037 size_t count = Current.size();
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)
1045 for (
uint i = 0; i < count; ++i)
1051 std::transform(Current.cbegin(), Current.cend(), std::back_inserter(Textures),
1063 case FMT_YV12:
return "opengl-yv12";
1064 case FMT_NV12:
return "opengl-nv12";
1079 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create bicubic shader. Disabling");
1085 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Created bicubic sampler");
1096 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Disabling bicubic sampler");
MythOpenGLTonemap * m_toneMap
uint64_t m_discontinuityCounter
void DeleteFramebuffer(QOpenGLFramebufferObject *Framebuffer)
static bool HardwareFramesFormat(VideoFrameType Type)
MythVideoTextureOpenGL * Map(std::vector< MythVideoTextureOpenGL * > &Inputs, QSize DisplaySize)
void ResetTextures() override
Clear reference frames after a seek as they will contain old images.
MythVideoTextureOpenGL * m_frameBufferTexture
MythOpenGLVideo(MythRenderOpenGL *Render, MythVideoColourSpace *ColourSpace, MythVideoBounds *Bounds, const MythVideoProfilePtr &VideoProfile, const QString &Profile)
static const QString BicubicShader
bool UpdateColourSpace(const MythVideoFrame *Frame)
Set the current colourspace to use.
void logDebugMarker(const QString &Message)
static bool FormatIsRGB(VideoFrameType Type)
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
MythVideoColourSpace * m_videoColourSpace
~MythOpenGLVideo() override
std::array< int, 3 > FramePitches
void DrawBitmap(MythGLTexture *Texture, QOpenGLFramebufferObject *Target, QRect Source, QRect Destination, QOpenGLShaderProgram *Program, int Alpha=255, qreal Scale=1.0)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
static bool HardwareFormat(VideoFrameType Type)
void PrepareFrame(MythVideoFrame *Frame, FrameScanType Scan=kScan_Progressive) override
Update the current input texture using the data from the given video frame.
static void SetTextureFilters(MythRenderOpenGL *Context, const std::vector< MythVideoTextureOpenGL * > &Textures, QOpenGLTexture::Filter Filter, QOpenGLTexture::WrapMode Wrap=QOpenGLTexture::ClampToEdge)
std::array< int, 3 > FrameOffsets
static bool FormatIs422(VideoFrameType Type)
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.
bool SetupFrameFormat(VideoFrameType InputType, VideoFrameType OutputType, QSize Size, GLenum TextureTarget)
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
QOpenGLFunctions::OpenGLFeatures GetFeatures(void) const
MythDeintType m_fallbackDeinterlacer
void SetShaderProgramParams(QOpenGLShaderProgram *Program, const QMatrix4x4 &Value, const char *Uniform)
QOpenGLFramebufferObject * m_frameBuffer
#define GL_TEXTURE_EXTERNAL_OES
QStringList GetColourMappingDefines(void)
static bool YUVFormat(VideoFrameType Type)
QOpenGLFunctions::OpenGLFeatures m_features
void BindTextures(bool Deinterlacing, std::vector< MythVideoTextureOpenGL * > &Current, std::vector< MythGLTexture * > &Textures)
void ColourSpaceUpdate(bool PrimariesChanged) override
MythRenderOpenGL * m_openglRender
void DrawRect(QOpenGLFramebufferObject *Target, QRect Area, const QBrush &FillBrush, const QPen &LinePen, int Alpha)
static QString TypeToProfile(VideoFrameType Type)
void RenderFrame(MythVideoFrame *Frame, bool TopFieldFirst, FrameScanType Scan, StereoscopicMode StereoOverride, bool DrawBorder=false) override
std::vector< MythVideoTextureOpenGL * > m_inputTextures
bool m_chromaUpsamplingFilter
void SetupBicubic(VideoResizing &Resize)
bool AddDeinterlacer(const MythVideoFrame *Frame, FrameScanType Scan, MythDeintType Filter=DEINT_SHADER, bool CreateReferences=true)
float GetColourGamma(void) const
static const QString GLSL300VertexShader
std::vector< MythVideoTextureOpenGL * > m_prevTextures
static QString VideoResizeToString(VideoResizing Resize)
static int ColorDepth(int Format)
void DeleteTexture(MythGLTexture *Texture)
static const QString GLSL300YUVFragmentExtensions
MythDeintType m_deinterlacer
@ kStereoscopicModeTopAndBottomDiscard
void UpdateShaderParameters()
int GetExtraFeatures(void) const
VideoFrameType m_outputType
float GetDisplayGamma(void) const
void DeleteShaderProgram(QOpenGLShaderProgram *Program)
void CleanupDeinterlacers()
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
void OutputChanged(QSize VideoDim, QSize VideoDispDim, float)
StereoscopicMode m_stereoMode
static bool FormatIs444(VideoFrameType Type)
bool GetBoolSetting(const QString &key, bool defaultval=false)
int GetMaxTextureUnits(void) const
static bool FormatIs420(VideoFrameType Type)
std::array< QOpenGLShaderProgram *, ShaderCount > m_shaders
void BindFramebuffer(QOpenGLFramebufferObject *Framebuffer)
static QString FormatDescription(VideoFrameType Type)
bool CreateVideoShader(VideoShaderType Type, MythDeintType Deint=DEINT_NONE)
Create the appropriate shader for the operation Type.
static const QString YUVFragmentExtensions
MythVideoTextureOpenGL * GetTexture()
static QString DeinterlacerName(MythDeintType Deint, bool DoubleRate, VideoFrameType Format=FMT_NONE)
static void DeleteTextures(MythRenderOpenGL *Context, std::vector< MythVideoTextureOpenGL * > &Textures)
static VideoFramebuffer CreateVideoFrameBuffer(MythRenderOpenGL *Context, VideoFrameType OutputType, QSize Size, bool HighPrecision=true)
void SetTextureFilters(MythGLTexture *Texture, QOpenGLTexture::Filter Filter, QOpenGLTexture::WrapMode Wrap=QOpenGLTexture::ClampToEdge)
std::vector< MythVideoTextureOpenGL * > m_nextTextures
static uint GetNumPlanes(VideoFrameType Type)
QMatrix4x4 GetPrimaryMatrix(void)
static const QString DefaultVertexShader
static const QString YUVFragmentShader
virtual void ResetFrameFormat()
void UpdateColourSpace(bool PrimariesChanged)
void SetViewPort(QRect Rect, bool ViewportOnly=false) override
std::shared_ptr< MythVideoProfile > MythVideoProfilePtr
static const QString RGBFragmentShader
QSize m_masterViewportSize
bool is_interlaced(FrameScanType Scan)
static bool FormatIsNV12(VideoFrameType Type)
std::array< int, ShaderCount > m_shaderCost
@ kStereoscopicModeSideBySideDiscard
MythVideoColourSpace contains a QMatrix4x4 that can convert YCbCr data to RGB.
VideoFrameType m_inputType
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.
static const QString GLSL300YUVFragmentShader
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)
static std::vector< MythVideoTextureOpenGL * > Retrieve(MythRenderOpenGL *Context, MythVideoColourSpace *ColourSpace, MythVideoFrame *Frame, FrameScanType Scan)
QOpenGLShaderProgram * CreateShaderProgram(const QString &Vertex, const QString &Fragment)
bool EnableShaderProgram(QOpenGLShaderProgram *Program)
QString GetProfile() const override
void ResetFrameFormat() override