WIP: feat: video wallpapers #163
@@ -1,4 +1,3 @@
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
#include "vaapiplayer.hpp"
|
||||
|
||||
#ifdef ZHAVE_FFMPEG
|
||||
@@ -50,6 +49,42 @@ GLEGLImageTargetProc glEGLImageTarget() {
|
||||
return fn;
|
||||
}
|
||||
|
||||
// eglCreateImageKHR/eglDestroyImageKHR are EGL extension entry points. Fetch
|
||||
// them through eglGetProcAddress rather than linking them directly, so the
|
||||
// shared library does not carry a hard undefined reference to symbols libEGL
|
||||
// may not export on every platform.
|
||||
using PfnCreateImageKHR = EGLImageKHR (*)(
|
||||
EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint*);
|
||||
using PfnDestroyImageKHR = EGLBoolean (*)(EGLDisplay, EGLImageKHR);
|
||||
|
||||
PfnCreateImageKHR eglCreateImageProc() {
|
||||
static PfnCreateImageKHR fn = reinterpret_cast<PfnCreateImageKHR>(
|
||||
eglGetProcAddress("eglCreateImageKHR"));
|
||||
return fn;
|
||||
}
|
||||
|
||||
PfnDestroyImageKHR eglDestroyImageProc() {
|
||||
static PfnDestroyImageKHR fn = reinterpret_cast<PfnDestroyImageKHR>(
|
||||
eglGetProcAddress("eglDestroyImageKHR"));
|
||||
return fn;
|
||||
}
|
||||
|
||||
void destroyEglImage(EGLDisplay dpy, EGLImageKHR image) {
|
||||
if (image == EGL_NO_IMAGE_KHR) return;
|
||||
PfnDestroyImageKHR fn = eglDestroyImageProc();
|
||||
if (!fn) {
|
||||
static bool warned = false;
|
||||
if (!warned) {
|
||||
warned = true;
|
||||
qCWarning(
|
||||
vaapiLog,
|
||||
"VideoPlayer: eglDestroyImageKHR unavailable, EGL images leak");
|
||||
}
|
||||
return;
|
||||
}
|
||||
fn(dpy, image);
|
||||
}
|
||||
|
||||
EGLImageKHR createDmaImage(
|
||||
EGLDisplay dpy,
|
||||
int fd,
|
||||
@@ -57,6 +92,9 @@ EGLImageKHR createDmaImage(
|
||||
uint32_t pitch,
|
||||
uint32_t fourcc,
|
||||
uint64_t modifier) {
|
||||
PfnCreateImageKHR fn = eglCreateImageProc();
|
||||
if (!fn) return EGL_NO_IMAGE_KHR;
|
||||
|
||||
EGLint attrs[16];
|
||||
int n = 0;
|
||||
attrs[n++] = EGL_LINUX_DRM_FOURCC_EXT;
|
||||
@@ -75,8 +113,8 @@ EGLImageKHR createDmaImage(
|
||||
}
|
||||
attrs[n] = EGL_NONE;
|
||||
|
||||
EGLImageKHR image = eglCreateImageKHR(
|
||||
dpy, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attrs);
|
||||
EGLImageKHR image =
|
||||
fn(dpy, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attrs);
|
||||
if (image == EGL_NO_IMAGE_KHR) return EGL_NO_IMAGE_KHR;
|
||||
return image;
|
||||
}
|
||||
@@ -105,11 +143,11 @@ VaapiPlayer::~VaapiPlayer() {
|
||||
|
||||
#ifdef ZHAVE_VAAPI
|
||||
if (m_imageY != EGL_NO_IMAGE_KHR) {
|
||||
eglDestroyImageKHR(m_eglDisplay, m_imageY);
|
||||
destroyEglImage(m_eglDisplay, m_imageY);
|
||||
m_imageY = EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
if (m_imageUV != EGL_NO_IMAGE_KHR) {
|
||||
eglDestroyImageKHR(m_eglDisplay, m_imageUV);
|
||||
destroyEglImage(m_eglDisplay, m_imageUV);
|
||||
m_imageUV = EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
#endif
|
||||
@@ -339,11 +377,11 @@ void VaapiPlayer::stop() {
|
||||
void VaapiPlayer::deleteTexture() {
|
||||
#ifdef ZHAVE_VAAPI
|
||||
if (m_imageY != EGL_NO_IMAGE_KHR) {
|
||||
eglDestroyImageKHR(m_eglDisplay, m_imageY);
|
||||
destroyEglImage(m_eglDisplay, m_imageY);
|
||||
m_imageY = EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
if (m_imageUV != EGL_NO_IMAGE_KHR) {
|
||||
eglDestroyImageKHR(m_eglDisplay, m_imageUV);
|
||||
destroyEglImage(m_eglDisplay, m_imageUV);
|
||||
m_imageUV = EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
#endif
|
||||
@@ -569,11 +607,11 @@ bool VaapiPlayer::importEglImages(AVFrame* frame) {
|
||||
const QSize sz = QSize(int(frame->width), int(frame->height));
|
||||
if (m_texSize != sz || m_texY == 0) {
|
||||
if (m_imageY != EGL_NO_IMAGE_KHR) {
|
||||
eglDestroyImageKHR(m_eglDisplay, m_imageY);
|
||||
destroyEglImage(m_eglDisplay, m_imageY);
|
||||
m_imageY = EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
if (m_imageUV != EGL_NO_IMAGE_KHR) {
|
||||
eglDestroyImageKHR(m_eglDisplay, m_imageUV);
|
||||
destroyEglImage(m_eglDisplay, m_imageUV);
|
||||
m_imageUV = EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
if (m_texY == 0) glGenTextures(1, &m_texY);
|
||||
@@ -595,10 +633,8 @@ bool VaapiPlayer::importEglImages(AVFrame* frame) {
|
||||
EGLImageKHR imageUV = bindLayer(1, m_texUV);
|
||||
|
||||
if (imageY == EGL_NO_IMAGE_KHR || imageUV == EGL_NO_IMAGE_KHR) {
|
||||
if (imageY != EGL_NO_IMAGE_KHR)
|
||||
eglDestroyImageKHR(m_eglDisplay, imageY);
|
||||
if (imageUV != EGL_NO_IMAGE_KHR)
|
||||
eglDestroyImageKHR(m_eglDisplay, imageUV);
|
||||
destroyEglImage(m_eglDisplay, imageY);
|
||||
destroyEglImage(m_eglDisplay, imageUV);
|
||||
for (uint32_t i = 0; i < desc.num_objects; ++i)
|
||||
if (desc.objects[i].fd >= 0) close(desc.objects[i].fd);
|
||||
static int logged = 0;
|
||||
@@ -608,10 +644,8 @@ bool VaapiPlayer::importEglImages(AVFrame* frame) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_imageY != EGL_NO_IMAGE_KHR)
|
||||
eglDestroyImageKHR(m_eglDisplay, m_imageY);
|
||||
if (m_imageUV != EGL_NO_IMAGE_KHR)
|
||||
eglDestroyImageKHR(m_eglDisplay, m_imageUV);
|
||||
if (m_imageY != EGL_NO_IMAGE_KHR) destroyEglImage(m_eglDisplay, m_imageY);
|
||||
if (m_imageUV != EGL_NO_IMAGE_KHR) destroyEglImage(m_eglDisplay, m_imageUV);
|
||||
|
||||
m_imageY = imageY;
|
||||
m_imageUV = imageUV;
|
||||
|
||||
Reference in New Issue
Block a user