[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