3#include "libmythbase/mythconfig.h"
6#define pointer Xpointer
7#if defined(_X11_XLIB_H_) && !defined(Bool)
22#define LOC QString("VAAPIGLX: ")
36 uint flags = VA_FRAME_PICTURE;
43 flags = VA_FRAME_PICTURE;
48 bool doublerate =
true;
61 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Enabled deinterlacer '%1'")
65 bool top =
Frame->m_interlacedReverse ? !
Frame->m_topFieldFirst :
Frame->m_topFieldFirst;
69 Frame->m_deinterlaceInuse2x = doublerate;
70 flags = top ? VA_TOP_FIELD : VA_BOTTOM_FIELD;
75 Frame->m_deinterlaceInuse2x = doublerate;
76 flags = top ? VA_BOTTOM_FIELD : VA_TOP_FIELD;
82 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Disabled basic VAAPI deinterlacer");
90 switch (
Frame->m_colorspace)
93 case AVCOL_SPC_SMPTE170M:
99 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Using '%1' VAAPI colourspace")
117 QVector<VADisplayAttribute> supported;
119 auto* attribs =
new VADisplayAttribute[
static_cast<unsigned int>(num)];
123 va_status = vaQueryDisplayAttributes(
m_vaDisplay, attribs, &actual);
126 for (
int i = 0; i < actual; i++)
128 int type = attribs[i].type;
129 if ((attribs[i].flags & VA_DISPLAY_ATTRIB_SETTABLE) &&
130 (
type == VADisplayAttribBrightness ||
131 type == VADisplayAttribContrast ||
132 type == VADisplayAttribHue ||
133 type == VADisplayAttribSaturation ||
134 type == VADisplayAttribCSCMatrix))
136 supported.push_back(attribs[i]);
137 if (
type == VADisplayAttribBrightness)
139 if (
type == VADisplayAttribHue)
141 if (
type == VADisplayAttribContrast)
143 if (
type == VADisplayAttribSaturation)
156 if (supported.isEmpty())
180 VADisplayAttribType attrib = VADisplayAttribBrightness;
184 attrib = VADisplayAttribBrightness;
187 attrib = VADisplayAttribContrast;
190 attrib = VADisplayAttribHue;
194 attrib = VADisplayAttribSaturation;
206 int newval = Value + adjustment;
207 if (newval > 100) newval -= 100;
234 Display *display = glXGetCurrentDisplay();
237 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to open GLX display");
244 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create GLX VADisplay");
254 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Deleting GLX surface");
262std::vector<MythVideoTextureOpenGL*>
268 std::vector<MythVideoTextureOpenGL*> result;
306 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create GLX surface.");
311 result.push_back(texture);
333 m_vaDisplay = vaGetDisplay(glXGetCurrentDisplay());
335 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create X11 VADisplay");
341MythVAAPIInteropGLXPixmap::~MythVAAPIInteropGLXPixmap()
344 Display* display = glXGetCurrentDisplay();
345 if (!InitPixmaps() || !display)
348 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Deleting GLX Pixmaps");
351 m_glxReleaseTexImageEXT(display, m_glxPixmap, GLX_FRONT_EXT);
352 XSync(display, False);
353 glXDestroyPixmap(display, m_glxPixmap);
357 XFreePixmap(display, m_pixmap);
360std::vector<MythVideoTextureOpenGL*>
366 std::vector<MythVideoTextureOpenGL*> result;
371 VASurfaceID
id = VerifySurface(Context,
Frame);
372 if (!
id || !m_vaDisplay)
376 if (ColourSpace && m_openglTextures.isEmpty())
377 InitPictureAttributes(ColourSpace);
385 if (m_openglTextures.isEmpty())
388 Display* display = glXGetCurrentDisplay();
393 const std::array<const int,23> fbattribs {
394 GLX_RENDER_TYPE, GLX_RGBA_BIT,
395 GLX_X_RENDERABLE, True,
396 GLX_BIND_TO_TEXTURE_RGBA_EXT, True,
397 GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
398 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
399 GLX_Y_INVERTED_EXT, True,
400 GLX_DOUBLEBUFFER, False,
407 GLXFBConfig *fbs = glXChooseFBConfig(display, DefaultScreen(display), fbattribs.data(), &fbcount);
410 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to retrieve GLX framebuffer config");
414 GLXFBConfig fbconfig = fbs[0];
415 XFree(
reinterpret_cast<void*
>(fbs));
418 uint width =
static_cast<uint>(m_textureSize.width());
419 uint height =
static_cast<uint>(m_textureSize.height());
420 XWindowAttributes xwattribs;
421 XGetWindowAttributes(display, DefaultRootWindow(display), &xwattribs);
422 m_pixmap = XCreatePixmap(display, DefaultRootWindow(display),
423 width, height,
static_cast<uint>(xwattribs.depth));
426 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create Pixmap");
430 const std::array<const int,7> attribs {
431 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
432 GLX_TEXTURE_FORMAT_EXT, xwattribs.depth == 32 ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT,
433 GLX_MIPMAP_TEXTURE_EXT, False, 0};
435 m_glxPixmap = glXCreatePixmap(display, fbconfig, m_pixmap, attribs.data());
438 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create GLXPixmap");
445 std::vector<QSize> size;
446 size.push_back(m_textureSize);
448 if (textures.empty())
450 result.push_back(textures[0]);
454 if (m_openglTextures.isEmpty() || !m_glxPixmap || !m_pixmap)
459 id = Deinterlace(
Frame,
id, Scan);
463 va_status = vaSyncSurface(m_vaDisplay,
id);
465 auto width =
static_cast<unsigned short>(m_textureSize.width());
466 auto height =
static_cast<unsigned short>(m_textureSize.height());
467 va_status = vaPutSurface(m_vaDisplay,
id, m_pixmap,
468 0, 0, width, height, 0, 0, width, height,
469 nullptr, 0, GetFlagsForFrame(
Frame, Scan));
472 Display* glxdisplay = glXGetCurrentDisplay();
475 XSync(glxdisplay, False);
476 m_openglContext->glBindTexture(QOpenGLTexture::Target2D, result[0]->m_textureId);
477 m_glxBindTexImageEXT(glxdisplay, m_glxPixmap, GLX_FRONT_EXT,
nullptr);
478 m_openglContext->glBindTexture(QOpenGLTexture::Target2D, 0);
483bool MythVAAPIInteropGLXPixmap::InitPixmaps()
485 if (m_glxBindTexImageEXT && m_glxReleaseTexImageEXT)
489 m_glxBindTexImageEXT =
reinterpret_cast<MYTH_GLXBINDTEXIMAGEEXT
>(glXGetProcAddressARB(
reinterpret_cast<const GLubyte*
>(
"glXBindTexImageEXT")));
490 m_glxReleaseTexImageEXT =
reinterpret_cast<MYTH_GLXRELEASETEXIMAGEEXT
>(glXGetProcAddressARB(
reinterpret_cast<const GLubyte*
>(
"glXReleaseTexImageEXT")));
491 if (!m_glxBindTexImageEXT || !m_glxReleaseTexImageEXT)
493 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to resolve 'texture_from_pixmap' functions");
505 Display* display = glXGetCurrentDisplay();
508 int screen = DefaultScreen(display);
509 QByteArray extensions(glXQueryExtensionsString(display, screen));
510 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)