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 supported.reserve(actual);
127 for (
int i = 0; i < actual; i++)
129 int type = attribs[i].type;
130 if ((attribs[i].flags & VA_DISPLAY_ATTRIB_SETTABLE) &&
131 (
type == VADisplayAttribBrightness ||
132 type == VADisplayAttribContrast ||
133 type == VADisplayAttribHue ||
134 type == VADisplayAttribSaturation ||
135 type == VADisplayAttribCSCMatrix))
137 supported.push_back(attribs[i]);
138 if (
type == VADisplayAttribBrightness)
140 if (
type == VADisplayAttribHue)
142 if (
type == VADisplayAttribContrast)
144 if (
type == VADisplayAttribSaturation)
157 if (supported.isEmpty())
181 VADisplayAttribType attrib = VADisplayAttribBrightness;
185 attrib = VADisplayAttribBrightness;
188 attrib = VADisplayAttribContrast;
191 attrib = VADisplayAttribHue;
195 attrib = VADisplayAttribSaturation;
207 int newval = Value + adjustment;
208 if (newval > 100) newval -= 100;
235 Display *display = glXGetCurrentDisplay();
238 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to open GLX display");
245 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create GLX VADisplay");
255 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Deleting GLX surface");
263std::vector<MythVideoTextureOpenGL*>
269 std::vector<MythVideoTextureOpenGL*> result;
307 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create GLX surface.");
312 result.push_back(texture);
334 m_vaDisplay = vaGetDisplay(glXGetCurrentDisplay());
336 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create X11 VADisplay");
342MythVAAPIInteropGLXPixmap::~MythVAAPIInteropGLXPixmap()
345 Display* display = glXGetCurrentDisplay();
346 if (!InitPixmaps() || !display)
349 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Deleting GLX Pixmaps");
352 m_glxReleaseTexImageEXT(display, m_glxPixmap, GLX_FRONT_EXT);
353 XSync(display, False);
354 glXDestroyPixmap(display, m_glxPixmap);
358 XFreePixmap(display, m_pixmap);
361std::vector<MythVideoTextureOpenGL*>
367 std::vector<MythVideoTextureOpenGL*> result;
372 VASurfaceID
id = VerifySurface(Context,
Frame);
373 if (!
id || !m_vaDisplay)
377 if (ColourSpace && m_openglTextures.isEmpty())
378 InitPictureAttributes(ColourSpace);
386 if (m_openglTextures.isEmpty())
389 Display* display = glXGetCurrentDisplay();
394 const std::array<const int,23> fbattribs {
395 GLX_RENDER_TYPE, GLX_RGBA_BIT,
396 GLX_X_RENDERABLE, True,
397 GLX_BIND_TO_TEXTURE_RGBA_EXT, True,
398 GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
399 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
400 GLX_Y_INVERTED_EXT, True,
401 GLX_DOUBLEBUFFER, False,
408 GLXFBConfig *fbs = glXChooseFBConfig(display, DefaultScreen(display), fbattribs.data(), &fbcount);
411 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to retrieve GLX framebuffer config");
415 GLXFBConfig fbconfig = fbs[0];
416 XFree(
reinterpret_cast<void*
>(fbs));
419 uint width =
static_cast<uint>(m_textureSize.width());
420 uint height =
static_cast<uint>(m_textureSize.height());
421 XWindowAttributes xwattribs;
422 XGetWindowAttributes(display, DefaultRootWindow(display), &xwattribs);
423 m_pixmap = XCreatePixmap(display, DefaultRootWindow(display),
424 width, height,
static_cast<uint>(xwattribs.depth));
427 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create Pixmap");
431 const std::array<const int,7> attribs {
432 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
433 GLX_TEXTURE_FORMAT_EXT, xwattribs.depth == 32 ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT,
434 GLX_MIPMAP_TEXTURE_EXT, False, 0};
436 m_glxPixmap = glXCreatePixmap(display, fbconfig, m_pixmap, attribs.data());
439 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create GLXPixmap");
446 std::vector<QSize> size;
447 size.push_back(m_textureSize);
449 if (textures.empty())
451 result.push_back(textures[0]);
455 if (m_openglTextures.isEmpty() || !m_glxPixmap || !m_pixmap)
460 id = Deinterlace(
Frame,
id, Scan);
464 va_status = vaSyncSurface(m_vaDisplay,
id);
466 auto width =
static_cast<unsigned short>(m_textureSize.width());
467 auto height =
static_cast<unsigned short>(m_textureSize.height());
468 va_status = vaPutSurface(m_vaDisplay,
id, m_pixmap,
469 0, 0, width, height, 0, 0, width, height,
470 nullptr, 0, GetFlagsForFrame(
Frame, Scan));
473 Display* glxdisplay = glXGetCurrentDisplay();
476 XSync(glxdisplay, False);
477 m_openglContext->glBindTexture(QOpenGLTexture::Target2D, result[0]->m_textureId);
478 m_glxBindTexImageEXT(glxdisplay, m_glxPixmap, GLX_FRONT_EXT,
nullptr);
479 m_openglContext->glBindTexture(QOpenGLTexture::Target2D, 0);
484bool MythVAAPIInteropGLXPixmap::InitPixmaps()
486 if (m_glxBindTexImageEXT && m_glxReleaseTexImageEXT)
490 m_glxBindTexImageEXT =
reinterpret_cast<MYTH_GLXBINDTEXIMAGEEXT
>(glXGetProcAddressARB(
reinterpret_cast<const GLubyte*
>(
"glXBindTexImageEXT")));
491 m_glxReleaseTexImageEXT =
reinterpret_cast<MYTH_GLXRELEASETEXIMAGEEXT
>(glXGetProcAddressARB(
reinterpret_cast<const GLubyte*
>(
"glXReleaseTexImageEXT")));
492 if (!m_glxBindTexImageEXT || !m_glxReleaseTexImageEXT)
494 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to resolve 'texture_from_pixmap' functions");
506 Display* display = glXGetCurrentDisplay();
509 int screen = DefaultScreen(display);
510 QByteArray extensions(glXQueryExtensionsString(display, screen));
511 return extensions.contains(
"GLX_EXT_texture_from_pixmap");
515#include "moc_mythvaapiglxinterop.cpp"
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)