[vlc-devel] [PATCH 3/6] video_filter: add egl_pbuffer filter plugin
Rémi Denis-Courmont
remi at remlab.net
Tue Feb 23 17:28:44 UTC 2021
Le tiistaina 23. helmikuuta 2021, 18.06.11 EET Romain Vimont a écrit :
> From: Alexandre Janniaux <ajanni at videolabs.io>
>
> egl_pbuffer allows running OpenGL filters inside an EGL pixel buffer
> context, using multiple framebuffers.
>
> Co-authored-by: Romain Vimont <rom1v at videolabs.io>
> ---
> modules/video_filter/egl_pbuffer.c | 470 ++++++++++++++++++++++++
> modules/video_output/opengl/Makefile.am | 15 +
> modules/video_output/opengl/gl_api.c | 3 +
> modules/video_output/opengl/gl_common.h | 17 +
> 4 files changed, 505 insertions(+)
> create mode 100644 modules/video_filter/egl_pbuffer.c
>
> diff --git a/modules/video_filter/egl_pbuffer.c
> b/modules/video_filter/egl_pbuffer.c new file mode 100644
> index 0000000000..4a9c2da8c1
> --- /dev/null
> +++ b/modules/video_filter/egl_pbuffer.c
> @@ -0,0 +1,470 @@
> +/**************************************************************************
> *** + * egl_pbuffer.c: OpenGL filter in EGL offscreen framebuffer
> +
> ***************************************************************************
> ** + * Copyright (C) 2020 Videolabs
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License as published by
> + * the Free Software Foundation; either version 2.1 of the License, or + *
> (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. +
> ***************************************************************************
> **/ +#ifdef HAVE_CONFIG_H
> +# include <config.h>
> +#endif
> +
> +#include <vlc_common.h>
> +#include <vlc_plugin.h>
> +#include <vlc_modules.h>
> +#include <vlc_picture.h>
> +#include <vlc_filter.h>
> +#include <vlc_opengl.h>
> +#include <vlc_vout_display.h>
> +#include <vlc_atomic.h>
> +#include "../video_output/opengl/vout_helper.h"
> +#include "../video_output/opengl/filters.h"
> +#include "../video_output/opengl/gl_api.h"
> +#include "../video_output/opengl/gl_common.h"
> +#include "../video_output/opengl/interop.h"
> +#include <EGL/egl.h>
> +#include <EGL/eglext.h>
> +
> +#define BUFFER_COUNT 4
> +
> +struct pbo_picture_context
> +{
> + struct picture_context_t context;
> + void *buffer_mapping;
> + int rc;
> + vlc_mutex_t *lock;
> + vlc_cond_t *cond;
> +};
> +
> +struct vlc_gl_pbuffer
> +{
> + vlc_gl_t *gl;
> + vlc_mutex_t lock;
> + vlc_cond_t cond;
> +
> + video_format_t fmt_out;
> +
> + struct vlc_gl_api api;
> +
> + size_t current_flip;
> + GLuint pixelbuffers[BUFFER_COUNT];
> + GLuint framebuffers[BUFFER_COUNT];
> + GLuint textures[BUFFER_COUNT];
> + struct pbo_picture_context picture_contexts[BUFFER_COUNT];
> +
> + EGLDisplay display;
> + EGLSurface surface;
> + EGLContext context;
> +
> + PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
> + PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
> +
> + bool current;
> +};
> +
> +static int MakeCurrent (vlc_gl_t *gl)
> +{
> + struct vlc_gl_pbuffer *sys = gl->sys;
> +
> + assert(!sys->current);
> + if (eglMakeCurrent (sys->display, sys->surface, sys->surface,
> + sys->context) != EGL_TRUE)
> + return VLC_EGENERIC;
> +
> + sys->current = true;
> + return VLC_SUCCESS;
> +}
> +
> +static void ReleaseCurrent (vlc_gl_t *gl)
> +{
> + struct vlc_gl_pbuffer *sys = gl->sys;
> +
> + assert(sys->current);
> + eglMakeCurrent (sys->display, EGL_NO_SURFACE, EGL_NO_SURFACE,
> + EGL_NO_CONTEXT);
> +
> + sys->current = false;
> +}
> +
> +static void *GetSymbol(vlc_gl_t *gl, const char *procname)
> +{
> + (void) gl;
> + return (void *)eglGetProcAddress (procname);
> +}
> +
> +static const char *QueryString(vlc_gl_t *gl, int32_t name)
> +{
> + struct vlc_gl_pbuffer *sys = gl->sys;
> +
> + return eglQueryString(sys->display, name);
> +}
> +
> +static void *CreateImageKHR(vlc_gl_t *gl, unsigned target, void *buffer,
> + const int32_t *attrib_list)
> +{
> + struct vlc_gl_pbuffer *sys = gl->sys;
> +
> + return sys->eglCreateImageKHR(sys->display, NULL, target, buffer,
> + attrib_list);
> +}
> +
> +static bool DestroyImageKHR(vlc_gl_t *gl, void *image)
> +{
> + struct vlc_gl_pbuffer *sys = gl->sys;
> +
> + return sys->eglDestroyImageKHR(sys->display, image);
> +}
> +
> +static int InitEGL(vlc_gl_t *gl, unsigned width, unsigned height)
> +{
> + struct vlc_gl_pbuffer *sys = gl->sys;
> +
> + sys->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
> + if (sys->display == EGL_NO_DISPLAY)
> + return VLC_EGENERIC;
This looks rather suspicious, as it seems like it depends on a real display.
As such it would presumably fail in a headless cases, or if the display type
is mismatched (e.g. Wayland when X11 is expected).
--
Rémi Denis-Courmont
http://www.remlab.net/
More information about the vlc-devel
mailing list