[vlc-devel] [PATCH v4 17/18] video_output: Add PPAPI plugin

Julian Scheel julian at jusst.de
Wed Mar 22 09:59:05 CET 2017


---
 configure.ac                        |   2 +
 include/vlc_vout_window.h           |   2 +
 modules/video_output/Makefile.am    |  15 +++
 modules/video_output/ppapi/gl.c     | 188 ++++++++++++++++++++++++++++++++++++
 modules/video_output/ppapi/window.c | 153 +++++++++++++++++++++++++++++
 5 files changed, 360 insertions(+)
 create mode 100644 modules/video_output/ppapi/gl.c
 create mode 100644 modules/video_output/ppapi/window.c

diff --git a/configure.ac b/configure.ac
index cd992f09ee..58bc678859 100644
--- a/configure.ac
+++ b/configure.ac
@@ -303,6 +303,8 @@ case "${host_os}" in
     AC_LIBOBJ([sigwait])
     AC_LIBOBJ([recvmsg])
     AC_LIBOBJ([sendmsg])
+    VLC_ADD_PLUGIN([gles2])
+    VLC_ADD_LIBS([nacl],[-lppapi -lppapi_gles2])
     ;;
   *)
     SYS="${host_os}"
diff --git a/include/vlc_vout_window.h b/include/vlc_vout_window.h
index 69a719bd2a..2ac4f84452 100644
--- a/include/vlc_vout_window.h
+++ b/include/vlc_vout_window.h
@@ -53,6 +53,7 @@ enum {
     VOUT_WINDOW_TYPE_NSOBJECT,
     VOUT_WINDOW_TYPE_ANDROID_NATIVE,
     VOUT_WINDOW_TYPE_WAYLAND,
+    VOUT_WINDOW_TYPE_PPAPI,
 };
 
 /**
@@ -133,6 +134,7 @@ struct vout_window_t {
         void     *nsobject;      /* Mac OSX view object */
         void     *anativewindow; /* Android native window. */
         struct wl_surface *wl;   /* Wayland surface */
+        int32_t  pp_context;     /* PPAPI context ID */
     } handle;
 
     /* display server (mandatory) */
diff --git a/modules/video_output/Makefile.am b/modules/video_output/Makefile.am
index 483a197053..2fdd000ef3 100644
--- a/modules/video_output/Makefile.am
+++ b/modules/video_output/Makefile.am
@@ -337,6 +337,21 @@ endif
 endif
 
 
+## NaCl/PPAPI ###
+
+libppapi_gl_plugin_la_SOURCES = video_output/ppapi/gl.c
+libppapi_gl_plugin_la_CFLAGS = $(AM_CFLAGS) -DUSE_OPENGL_ES2
+libppapi_gl_plugin_la_LIBADD = $(LIBS_nacl)
+
+libppapi_window_plugin_la_SOURCES = video_output/ppapi/window.c
+libppapi_window_plugin_la_CFLAGS = $(AM_CFLAGS)
+libppapi_window_plugin_la_LIBADD = $(LIBS_nacl)
+
+if HAVE_NACL
+vout_LTLIBRARIES += libppapi_gl_plugin.la libppapi_window_plugin.la
+endif
+
+
 ### FrameBuffer ###
 
 libdirectfb_plugin_la_SOURCES = video_output/directfb.c
diff --git a/modules/video_output/ppapi/gl.c b/modules/video_output/ppapi/gl.c
new file mode 100644
index 0000000000..b5655525c6
--- /dev/null
+++ b/modules/video_output/ppapi/gl.c
@@ -0,0 +1,188 @@
+/*****************************************************************************
+ * gl.c: GL extension for PPAPI/NaCl
+ *****************************************************************************
+ * Copyright © 2017 VLC authors and VideoLAN
+ *
+ * Authors: Julian Scheel <julian at jusst.de>
+ *
+ * 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_vout_display.h>
+#include <vlc_opengl.h>
+
+#include "../opengl/vout_helper.h"
+
+#include <ppapi/gles2/gl2ext_ppapi.h>
+#include <ppapi/c/ppb_graphics_3d.h>
+#include <ppapi/c/ppb_view.h>
+#include <ppapi/c/pp_completion_callback.h>
+#include <ppapi/c/pp_errors.h>
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+static int Open(vlc_object_t *);
+static void Close(vlc_object_t *);
+
+vlc_module_begin()
+    set_shortname("PPAPI GL")
+    set_description(N_("PPAPI extension for OpenGL"))
+    set_category(CAT_VIDEO)
+    set_subcategory(SUBCAT_VIDEO_VOUT)
+
+    set_capability("opengl es2", 50)
+    set_callbacks(Open, Close)
+    add_shortcut("ppapi-gl", "gles2")
+vlc_module_end()
+
+/*****************************************************************************
+ * Local prototypes.
+ *****************************************************************************/
+
+struct vout_display_sys_t
+{
+    unsigned width;
+    unsigned height;
+
+    PP_Resource context;
+    PP_Resource viewport;
+    PPB_Graphics3D *graphics3d;
+    PPB_View *view;
+};
+
+static int GetViewSize(vlc_gl_t *gl, int32_t *width, int32_t *height)
+{
+    vout_display_sys_t *sys = gl->sys;
+
+    struct PP_Rect rect;
+    if (sys->viewport &&
+            sys->view->IsView(sys->viewport) &&
+            sys->view->GetRect(sys->viewport, &rect)) {
+        *width = rect.size.width;
+        *height = rect.size.height;
+        return VLC_SUCCESS;
+    }
+
+    return VLC_EGENERIC;
+}
+
+static void Resize(vlc_gl_t *gl, unsigned w, unsigned h)
+{
+    vout_display_sys_t *sys = gl->sys;
+
+    if (sys->graphics3d->ResizeBuffers(sys->context, w, h) != PP_OK)
+        msg_Err(gl, "Resizing buffers failed");
+}
+
+static void Swap(vlc_gl_t *gl)
+{
+    vout_display_sys_t *sys = gl->sys;
+
+    sys->viewport = var_InheritInteger(gl, "ppapi-view");
+
+    int32_t width, height;
+    if (GetViewSize(gl, &width, &height) != VLC_SUCCESS)
+        return;
+
+    if (((unsigned)width != sys->width) ||
+            ((unsigned)height != sys->height)) {
+        vout_window_ReportSize(gl->surface, width, height);
+
+        sys->width = width;
+        sys->height = height;
+    }
+
+    sys->graphics3d->SwapBuffers(sys->context, PP_BlockUntilComplete());
+}
+
+static void *GetProcAddress(vlc_gl_t *gl, const char *name)
+{
+    VLC_UNUSED(gl);
+    VLC_UNUSED(name);
+    return NULL;
+}
+
+static int MakeCurrent(vlc_gl_t *gl)
+{
+    vout_display_sys_t *sys = gl->sys;
+
+    glSetCurrentContextPPAPI(sys->context);
+    return VLC_SUCCESS;
+}
+
+static void ReleaseCurrent(vlc_gl_t *gl)
+{
+    VLC_UNUSED(gl);
+    glSetCurrentContextPPAPI(0);
+}
+
+static int Open(vlc_object_t *obj)
+{
+    vlc_gl_t *gl = (vlc_gl_t *)obj;
+    vout_display_sys_t *sys;
+
+    /* Allocate structure */
+    gl->sys = sys = calloc(1, sizeof(*sys));
+    if (!sys)
+        return VLC_ENOMEM;
+
+    vout_window_t *wnd = gl->surface;
+    if (wnd->type != VOUT_WINDOW_TYPE_PPAPI)
+        goto error;
+
+    sys->context = wnd->handle.pp_context;
+
+    PPB_GetInterface ppb_get_interface = var_InheritAddress(obj, "ppapi-ppb-get-interface");
+    if (ppb_get_interface == NULL) {
+        msg_Err(gl, "Variable ppapi-ppb-get-interface is not set");
+        goto error;
+    }
+
+    sys->view = (PPB_View*)ppb_get_interface(PPB_VIEW_INTERFACE);
+    if (sys->view == NULL) {
+        msg_Err(gl, "Failed to get PPB_VIEW_INTERFACE");
+        goto error;
+    }
+
+    sys->graphics3d = (PPB_View*)ppb_get_interface(PPB_GRAPHICS_3D_INTERFACE);
+    if (sys->view == NULL) {
+        msg_Err(gl, "Failed to get PPB_GRAPHICS_3D_INTERFACE");
+        goto error;
+    }
+
+    gl->makeCurrent = MakeCurrent;
+    gl->releaseCurrent = ReleaseCurrent;
+    gl->resize = Resize;
+    gl->swap = Swap;
+    gl->getProcAddress = GetProcAddress;
+
+    return VLC_SUCCESS;
+
+error:
+    Close(obj);
+    return VLC_EGENERIC;
+}
+
+static void Close(vlc_object_t *obj)
+{
+    vlc_gl_t *gl = (vlc_gl_t *)obj;
+    free(gl->sys);
+}
diff --git a/modules/video_output/ppapi/window.c b/modules/video_output/ppapi/window.c
new file mode 100644
index 0000000000..fa683e3736
--- /dev/null
+++ b/modules/video_output/ppapi/window.c
@@ -0,0 +1,153 @@
+/**
+ * @file window.c
+ * @brief PPAPI native window provider module for VLC media player
+ */
+/*****************************************************************************
+ * Copyright © 2017 VLC authors and VideoLAN
+ *
+ * Author: Julian Scheel <julian at jusst.de>
+ *
+ * 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 <stdarg.h>
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_vout_window.h>
+
+#include <ppapi/c/ppb.h>
+#include <ppapi/c/ppb_core.h>
+#include <ppapi/c/ppb_graphics_3d.h>
+#include <ppapi/c/ppb_instance.h>
+#include <ppapi/c/pp_instance.h>
+
+static int Open(vout_window_t*, const vout_window_cfg_t*);
+static void Close(vout_window_t*);
+static int Control(vout_window_t*, int, va_list ap);
+
+/*
+ * Module descriptor
+ */
+vlc_module_begin()
+    set_shortname(N_("PPAPI Window"))
+    set_description(N_("PPAPI drawing area"))
+    set_category(CAT_VIDEO)
+    set_subcategory(SUBCAT_VIDEO_VOUT)
+    set_capability("vout window", 10)
+    set_callbacks(Open, Close)
+vlc_module_end()
+
+struct vout_window_sys_t {
+    PP_Resource context;
+    PPB_Graphics3D *graphics3d;
+    PPB_Core *core;
+};
+
+static int Open(vout_window_t *wnd, const vout_window_cfg_t *cfg)
+{
+    if (cfg->type != VOUT_WINDOW_TYPE_INVALID &&
+            cfg->type != VOUT_WINDOW_TYPE_PPAPI)
+        return VLC_EGENERIC;
+
+    vout_window_sys_t *sys = calloc(1, sizeof (*sys));
+    if (sys == NULL)
+        return VLC_ENOMEM;
+
+    wnd->sys = sys;
+
+    PP_Instance pp_instance = (int)var_InheritInteger(wnd, "ppapi-instance");
+    if (pp_instance == 0)
+        goto error;
+
+    PPB_GetInterface ppb_get_interface = var_InheritAddress(wnd, "ppapi-ppb-get-interface");
+    if (ppb_get_interface == NULL) {
+        msg_Err(wnd, "Variable ppapi-ppb-get-interface is not set");
+        goto error;
+    }
+
+    sys->core = (PPB_Core*)ppb_get_interface(PPB_CORE_INTERFACE);
+    if (sys->core == NULL) {
+        msg_Err(wnd, "Failed to get PPB_CORE_INTERFACE");
+        goto error;
+    }
+
+    sys->graphics3d = (PPB_Graphics3D*)ppb_get_interface(PPB_GRAPHICS_3D_INTERFACE);
+    if (sys->graphics3d == NULL) {
+        msg_Err(wnd, "Failed to get PPB_GRAPHICS_3D_INTERFACE");
+        goto error;
+    }
+
+    int32_t attr[] = {
+        PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 0,
+        PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8,
+        PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8,
+        PP_GRAPHICS3DATTRIB_RED_SIZE, 8,
+        PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0,
+        PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0,
+        PP_GRAPHICS3DATTRIB_WIDTH, (int32_t)cfg->width,
+        PP_GRAPHICS3DATTRIB_HEIGHT, (int32_t)cfg->height,
+        PP_GRAPHICS3DATTRIB_GPU_PREFERENCE, PP_GRAPHICS3DATTRIB_GPU_PREFERENCE_LOW_POWER,
+        PP_GRAPHICS3DATTRIB_NONE
+    };
+    sys->context = sys->graphics3d->Create(pp_instance, 0, attr);
+    if(!sys->graphics3d->IsGraphics3D(sys->context)) {
+        msg_Err(wnd, "Failed to create context");
+        goto error;
+    }
+
+    PPB_Instance *ppb_instance = (PPB_Instance*)ppb_get_interface(PPB_INSTANCE_INTERFACE);
+    if (ppb_instance == NULL) {
+        msg_Err(wnd, "Failed to get PPB_INSTANCE_INTERFACE");
+        goto error;
+    }
+
+    if (ppb_instance->BindGraphics(pp_instance, sys->context) != PP_TRUE) {
+        msg_Err(wnd, "Binding PPAPI graphics context to instance failed");
+        goto error;
+    }
+
+    wnd->type = VOUT_WINDOW_TYPE_PPAPI;
+    wnd->handle.pp_context = sys->context;
+    wnd->control = Control;
+
+    return VLC_SUCCESS;
+
+error:
+    Close(wnd);
+    return VLC_EGENERIC;
+}
+
+static void Close(vout_window_t *wnd)
+{
+    vout_window_sys_t *sys = wnd->sys;
+    if (sys->graphics3d &&
+            sys->graphics3d->IsGraphics3D(sys->context) &&
+            sys->core)
+        sys->core->ReleaseResource(sys->context);
+    free(sys);
+}
+
+static int Control(vout_window_t *wnd, int cmd, va_list ap)
+{
+    VLC_UNUSED(cmd);
+    VLC_UNUSED(ap);
+    msg_Err(wnd, "control requests not supported");
+    return VLC_EGENERIC;
+}
-- 
2.12.0



More information about the vlc-devel mailing list