4#define pointer Xpointer
5#if defined(_X11_XLIB_H_) && !defined(Bool)
20#define LOC QString("VAAPIGLX: ")
34 uint flags = VA_FRAME_PICTURE;
41 flags = VA_FRAME_PICTURE;
46 bool doublerate =
true;
59 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Enabled deinterlacer '%1'")
63 bool top =
Frame->m_interlacedReverse ? !
Frame->m_topFieldFirst :
Frame->m_topFieldFirst;
67 Frame->m_deinterlaceInuse2x = doublerate;
68 flags = top ? VA_TOP_FIELD : VA_BOTTOM_FIELD;
73 Frame->m_deinterlaceInuse2x = doublerate;
74 flags = top ? VA_BOTTOM_FIELD : VA_TOP_FIELD;
80 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Disabled basic VAAPI deinterlacer");
88 switch (
Frame->m_colorspace)
91 case AVCOL_SPC_SMPTE170M:
97 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Using '%1' VAAPI colourspace")
115 QVector<VADisplayAttribute> supported;
117 auto* attribs =
new VADisplayAttribute[
static_cast<unsigned int>(num)];
121 va_status = vaQueryDisplayAttributes(
m_vaDisplay, attribs, &actual);
124 for (
int i = 0; i < actual; i++)
126 int type = attribs[i].type;
127 if ((attribs[i].flags & VA_DISPLAY_ATTRIB_SETTABLE) &&
128 (
type == VADisplayAttribBrightness ||
129 type == VADisplayAttribContrast ||
130 type == VADisplayAttribHue ||
131 type == VADisplayAttribSaturation ||
132 type == VADisplayAttribCSCMatrix))
134 supported.push_back(attribs[i]);
135 if (
type == VADisplayAttribBrightness)
137 if (
type == VADisplayAttribHue)
139 if (
type == VADisplayAttribContrast)
141 if (
type == VADisplayAttribSaturation)
154 if (supported.isEmpty())
178 VADisplayAttribType attrib = VADisplayAttribBrightness;
182 attrib = VADisplayAttribBrightness;
185 attrib = VADisplayAttribContrast;
188 attrib = VADisplayAttribHue;
192 attrib = VADisplayAttribSaturation;
204 int newval = Value + adjustment;
205 if (newval > 100) newval -= 100;
232 Display *display = glXGetCurrentDisplay();
235 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to open GLX display");
242 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create GLX VADisplay");
252 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Deleting GLX surface");
260std::vector<MythVideoTextureOpenGL*>
266 std::vector<MythVideoTextureOpenGL*> result;
304 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create GLX surface.");
309 result.push_back(texture);
331 m_vaDisplay = vaGetDisplay(glXGetCurrentDisplay());
333 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create X11 VADisplay");
339MythVAAPIInteropGLXPixmap::~MythVAAPIInteropGLXPixmap()
342 Display* display = glXGetCurrentDisplay();
343 if (!InitPixmaps() || !display)
346 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Deleting GLX Pixmaps");
349 m_glxReleaseTexImageEXT(display, m_glxPixmap, GLX_FRONT_EXT);
350 XSync(display, False);
351 glXDestroyPixmap(display, m_glxPixmap);
355 XFreePixmap(display, m_pixmap);
358std::vector<MythVideoTextureOpenGL*>
364 std::vector<MythVideoTextureOpenGL*> result;
369 VASurfaceID
id = VerifySurface(Context,
Frame);
370 if (!
id || !m_vaDisplay)
374 if (ColourSpace && m_openglTextures.isEmpty())
375 InitPictureAttributes(ColourSpace);
383 if (m_openglTextures.isEmpty())
386 Display* display = glXGetCurrentDisplay();
391 const std::array<const int,23> fbattribs {
392 GLX_RENDER_TYPE, GLX_RGBA_BIT,
393 GLX_X_RENDERABLE, True,
394 GLX_BIND_TO_TEXTURE_RGBA_EXT, True,
395 GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
396 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
397 GLX_Y_INVERTED_EXT, True,
398 GLX_DOUBLEBUFFER, False,
405 GLXFBConfig *fbs = glXChooseFBConfig(display, DefaultScreen(display), fbattribs.data(), &fbcount);
408 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to retrieve GLX framebuffer config");
412 GLXFBConfig fbconfig = fbs[0];
413 XFree(
reinterpret_cast<void*
>(fbs));
416 uint width =
static_cast<uint>(m_textureSize.width());
417 uint height =
static_cast<uint>(m_textureSize.height());
418 XWindowAttributes xwattribs;
419 XGetWindowAttributes(display, DefaultRootWindow(display), &xwattribs);
420 m_pixmap = XCreatePixmap(display, DefaultRootWindow(display),
421 width, height,
static_cast<uint>(xwattribs.depth));
424 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create Pixmap");
428 const std::array<const int,7> attribs {
429 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
430 GLX_TEXTURE_FORMAT_EXT, xwattribs.depth == 32 ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT,
431 GLX_MIPMAP_TEXTURE_EXT, False, 0};
433 m_glxPixmap = glXCreatePixmap(display, fbconfig, m_pixmap, attribs.data());
436 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create GLXPixmap");
443 std::vector<QSize> size;
444 size.push_back(m_textureSize);
446 if (textures.empty())
448 result.push_back(textures[0]);
452 if (m_openglTextures.isEmpty() || !m_glxPixmap || !m_pixmap)
457 id = Deinterlace(
Frame,
id, Scan);
461 va_status = vaSyncSurface(m_vaDisplay,
id);
463 auto width =
static_cast<unsigned short>(m_textureSize.width());
464 auto height =
static_cast<unsigned short>(m_textureSize.height());
465 va_status = vaPutSurface(m_vaDisplay,
id, m_pixmap,
466 0, 0, width, height, 0, 0, width, height,
467 nullptr, 0, GetFlagsForFrame(
Frame, Scan));
470 Display* glxdisplay = glXGetCurrentDisplay();
473 XSync(glxdisplay, False);
474 m_openglContext->glBindTexture(QOpenGLTexture::Target2D, result[0]->m_textureId);
475 m_glxBindTexImageEXT(glxdisplay, m_glxPixmap, GLX_FRONT_EXT,
nullptr);
476 m_openglContext->glBindTexture(QOpenGLTexture::Target2D, 0);
481bool MythVAAPIInteropGLXPixmap::InitPixmaps()
483 if (m_glxBindTexImageEXT && m_glxReleaseTexImageEXT)
487 m_glxBindTexImageEXT =
reinterpret_cast<MYTH_GLXBINDTEXIMAGEEXT
>(glXGetProcAddressARB(
reinterpret_cast<const GLubyte*
>(
"glXBindTexImageEXT")));
488 m_glxReleaseTexImageEXT =
reinterpret_cast<MYTH_GLXRELEASETEXIMAGEEXT
>(glXGetProcAddressARB(
reinterpret_cast<const GLubyte*
>(
"glXReleaseTexImageEXT")));
489 if (!m_glxBindTexImageEXT || !m_glxReleaseTexImageEXT)
491 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to resolve 'texture_from_pixmap' functions");
503 Display* display = glXGetCurrentDisplay();
506 int screen = DefaultScreen(display);
507 QByteArray extensions(glXQueryExtensionsString(display, screen));
508 return extensions.contains(
"GLX_EXT_texture_from_pixmap");
QOpenGLTexture * m_texture
MythRenderOpenGL * m_openglContext
QHash< unsigned long long, std::vector< MythVideoTextureOpenGL * > > m_openglTextures
std::vector< MythVideoTextureOpenGL * > Acquire(MythRenderOpenGL *Context, MythVideoColourSpace *ColourSpace, MythVideoFrame *Frame, FrameScanType Scan) override
MythVAAPIInteropGLXCopy(MythPlayerUI *Player, MythRenderOpenGL *Context)
~MythVAAPIInteropGLXCopy() override
~MythVAAPIInteropGLX() override
MythVAAPIInteropGLX(MythPlayerUI *Player, MythRenderOpenGL *Context, InteropType Type)
void InitPictureAttributes(MythVideoColourSpace *ColourSpace)
VADisplayAttribute * m_vaapiPictureAttributes
int m_vaapiPictureAttributeCount
MythDeintType m_basicDeinterlacer
uint GetFlagsForFrame(MythVideoFrame *Frame, FrameScanType Scan)
int SetPictureAttribute(PictureAttribute Attribute, int Value)
void InitaliseDisplay(void)
MythDeintType m_deinterlacer
VASurfaceID VerifySurface(MythRenderOpenGL *Context, MythVideoFrame *Frame)
VASurfaceID Deinterlace(MythVideoFrame *Frame, VASurfaceID Current, FrameScanType Scan)
MythVideoColourSpace contains a QMatrix4x4 that can convert YCbCr data to RGB.
void PictureAttributeChanged(PictureAttribute Attribute, int Value)
void SetSupportedAttributes(PictureAttributeSupported Supported)
Enable the given set of picture attributes.
int GetPictureAttribute(PictureAttribute Attribute)
static QString DeinterlacerName(MythDeintType Deint, bool DoubleRate, VideoFrameType Format=FMT_NONE)
VideoFrameType m_frameFormat
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 MythVideoTextureOpenGL * CreateTexture(MythRenderOpenGL *Context, QSize Size, GLenum Target=QOpenGLTexture::Target2D, QOpenGLTexture::PixelType PixelType=QOpenGLTexture::UInt8, QOpenGLTexture::PixelFormat PixelFormat=QOpenGLTexture::RGBA, QOpenGLTexture::TextureFormat Format=QOpenGLTexture::NoFormat, QOpenGLTexture::Filter Filter=QOpenGLTexture::Linear, QOpenGLTexture::WrapMode Wrap=QOpenGLTexture::ClampToEdge)
Create and initialise a MythVideoTexture that is backed by a QOpenGLTexture.
VideoFrameType m_frameType
static void DeleteTexture(MythRenderOpenGL *Context, MythVideoTextureOpenGL *Texture)
static constexpr uint64_t DUMMY_INTEROP_ID
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
static eu8 clamp(eu8 value, eu8 low, eu8 high)
PictureAttributeSupported
@ kPictureAttributeSupported_Colour
@ kPictureAttributeSupported_Brightness
@ kPictureAttributeSupported_Hue
@ kPictureAttributeSupported_Contrast
@ kPictureAttributeSupported_None
@ kPictureAttribute_Contrast
@ kPictureAttribute_Brightness
@ kPictureAttribute_Colour
bool is_interlaced(FrameScanType Scan)