WIP: feat: video wallpapers #163

Draft
zach wants to merge 10 commits from feat/video-wallpaper into main
Showing only changes of commit a56afd7fac - Show all commits
+51 -17
View File
@@ -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;