[vlc-devel] [PATCH 1/8] display: use a control callback for external rendering

Steve Lhomme robux4 at ycbcr.xyz
Mon Jan 21 17:38:44 CET 2019


Rather than a list of callbacks. This will make the API more stable over time.
---
 doc/libvlc/sdl_opengl_player.cpp  | 103 ++++++++-------
 include/vlc/libvlc_media_player.h | 200 +++++++++++++++---------------
 include/vlc_vout_display.h        |  58 +++++++++
 lib/libvlc.sym                    |   2 +-
 lib/media_player.c                |  36 +++---
 modules/video_output/vgl.c        |  55 ++++----
 6 files changed, 260 insertions(+), 194 deletions(-)

diff --git a/doc/libvlc/sdl_opengl_player.cpp b/doc/libvlc/sdl_opengl_player.cpp
index d34b99b268..bf06f61429 100644
--- a/doc/libvlc/sdl_opengl_player.cpp
+++ b/doc/libvlc/sdl_opengl_player.cpp
@@ -80,9 +80,7 @@ public:
         }
         // Define the opengl rendering callbacks
         libvlc_video_set_output_callbacks(m_mp, libvlc_video_engine_opengl,
-            setup, cleanup, resize, swap,
-            make_current, get_proc_address,
-            this);
+                                          control, this);
 
         // Play the video
         libvlc_media_player_play (m_mp);
@@ -115,26 +113,59 @@ public:
         return m_tex[m_idx_display];
     }
 
-    /// this callback will create the surfaces and FBO used by VLC to perform its rendering
-    static void resize(void* data, unsigned width, unsigned height)
+    static int control(void* data, libvlc_video_callback_control_t control,
+                       const void *input, void **output)
     {
         VLCVideo* that = static_cast<VLCVideo*>(data);
-        if (width != that->m_width || height != that->m_height)
-            cleanup(data);
+        switch ( control )
+        {
+        case LIBVLC_VIDEO_SETUP:
+            that->setup();
+            *output = that; // non NULL to signal it worked
+            break;
+        case LIBVLC_VIDEO_CLEANUP:
+            that->cleanup();
+            break;
+        case LIBVLC_VIDEO_UPDATE_OUTPUT:
+        {
+            const libvlc_video_callback_cfg_t *cfg = static_cast<const libvlc_video_callback_cfg_t *>(input);
+            that->resize(cfg->width, cfg->height);
+            break;
+        }
+        case LIBVLC_VIDEO_SWAP:
+            that->swap();
+            break;
+        case LIBVLC_VIDEO_MAKE_CURRENT:
+            if (!that->make_current( input != NULL ))
+                return -1;
+            break;
+        case LIBVLC_VIDEO_GET_PROCADDRESS:
+            // This control is called by VLC to get OpenGL functions.
+            *output = SDL_GL_GetProcAddress(static_cast<const char*>(intput));
+            break;
+        }
+        return 0;
+    }
 
-        glGenTextures(3, that->m_tex);
-        glGenFramebuffers(3, that->m_fbo);
+    /// this callback will create the surfaces and FBO used by VLC to perform its rendering
+    void resize(unsigned width, unsigned height)
+    {
+        if (width != m_width || height != m_height)
+            cleanup();
+
+        glGenTextures(3, m_tex);
+        glGenFramebuffers(3, m_fbo);
 
         for (int i = 0; i < 3; i++) {
-            glBindTexture(GL_TEXTURE_2D, that->m_tex[i]);
+            glBindTexture(GL_TEXTURE_2D, m_tex[i]);
             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
-            glBindFramebuffer(GL_FRAMEBUFFER, that->m_fbo[i]);
-            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, that->m_tex[i], 0);
+            glBindFramebuffer(GL_FRAMEBUFFER, m_fbo[i]);
+            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_tex[i], 0);
         }
         glBindTexture(GL_TEXTURE_2D, 0);
 
@@ -144,57 +175,45 @@ public:
             return;
         }
 
-        that->m_width = width;
-        that->m_height = height;
+        m_width = width;
+        m_height = height;
 
-        glBindFramebuffer(GL_FRAMEBUFFER, that->m_fbo[that->m_idx_render]);
+        glBindFramebuffer(GL_FRAMEBUFFER, m_fbo[m_idx_render]);
     }
 
     // This callback is called during initialisation.
-    static bool setup(void* data)
+    void setup()
     {
-        VLCVideo* that = static_cast<VLCVideo*>(data);
-        that->m_width = 0;
-        that->m_height = 0;
-        return true;
+        m_width = 0;
+        m_height = 0;
     }
 
-
     // This callback is called to release the texture and FBO created in resize
-    static void cleanup(void* data)
+    void cleanup()
     {
-        VLCVideo* that = static_cast<VLCVideo*>(data);
-        if (that->m_width == 0 && that->m_height == 0)
+        if (m_width == 0 && m_height == 0)
             return;
 
-        glDeleteTextures(3, that->m_tex);
-        glDeleteFramebuffers(3, that->m_fbo);
+        glDeleteTextures(3, m_tex);
+        glDeleteFramebuffers(3, m_fbo);
     }
 
     //This callback is called after VLC performs drawing calls
-    static void swap(void* data)
+    void swap()
     {
-        VLCVideo* that = static_cast<VLCVideo*>(data);
-        std::lock_guard<std::mutex> lock(that->m_text_lock);
-        that->m_updated = true;
-        std::swap(that->m_idx_swap, that->m_idx_render);
-        glBindFramebuffer(GL_FRAMEBUFFER, that->m_fbo[that->m_idx_render]);
+        std::lock_guard<std::mutex> lock(m_text_lock);
+        m_updated = true;
+        std::swap(m_idx_swap, m_idx_render);
+        glBindFramebuffer(GL_FRAMEBUFFER, m_fbo[m_idx_render]);
     }
 
     // This callback is called to set the OpenGL context
-    static bool make_current(void* data, bool current)
+    bool make_current(bool current)
     {
-        VLCVideo* that = static_cast<VLCVideo*>(data);
         if (current)
-            return SDL_GL_MakeCurrent(that->m_win, that->m_ctx) == 0;
+            return SDL_GL_MakeCurrent(m_win, m_ctx) == 0;
         else
-            return SDL_GL_MakeCurrent(that->m_win, 0) == 0;
-    }
-
-    // This callback is called by VLC to get OpenGL functions.
-    static void* get_proc_address(void* /*data*/, const char* current)
-    {
-        return SDL_GL_GetProcAddress(current);
+            return SDL_GL_MakeCurrent(m_win, 0) == 0;
     }
 
 private:
diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h
index d3b014937c..858b0a061d 100644
--- a/include/vlc/libvlc_media_player.h
+++ b/include/vlc/libvlc_media_player.h
@@ -420,104 +420,6 @@ void libvlc_video_set_callbacks( libvlc_media_player_t *mp,
                                  libvlc_video_display_cb display,
                                  void *opaque );
 
-
-/**
- * Callback prototype called to initialize user data.
- *
- * \param opaque private pointer passed to the @a libvlc_video_set_output_callbacks() [IN]
- * \return true on success
- * \version LibVLC 4.0.0 or later
- */
-typedef bool (*libvlc_video_setup_cb)(void* opaque);
-
-
-/**
- * Callback prototype called to release user data
- *
- * \param opaque private pointer passed to the @a libvlc_video_set_output_callbacks() [IN]
- * \version LibVLC 4.0.0 or later
- */
-typedef void (*libvlc_video_cleanup_cb)(void* opaque);
-
-/**
- * Callback prototype called on video size changes
- *
- * \param opaque private pointer passed to the @a libvlc_video_set_output_callbacks() [IN]
- * \param width video width in pixel [IN]
- * \param height video height in pixel [IN]
- * \version LibVLC 4.0.0 or later
- */
-typedef void (*libvlc_video_update_output_cb)(void* opaque, unsigned width, unsigned height);
-
-
-/**
- * Callback prototype called after performing drawing calls.
- *
- * \param opaque private pointer passed to the @a libvlc_video_set_output_callbacks() [IN]
- * \version LibVLC 4.0.0 or later
- */
-typedef void (*libvlc_video_swap_cb)(void* opaque);
-
-/**
- * Callback prototype to set up the OpenGL context for rendering
- *
- * \param opaque private pointer passed to the @a libvlc_video_set_output_callbacks() [IN]
- * \param enter true to set the context as current, false to unset it [IN]
- * \return true on success
- * \version LibVLC 4.0.0 or later
- */
-typedef bool (*libvlc_video_makeCurrent_cb)(void* opaque, bool enter);
-
-/**
- * Callback prototype to load opengl functions
- *
- * \param opaque private pointer passed to the @a libvlc_video_set_output_callbacks() [IN]
- * \param fct_name name of the opengl function to load
- * \return a pointer to the named OpenGL function the NULL otherwise
- * \version LibVLC 4.0.0 or later
- */
-typedef void* (*libvlc_video_getProcAddress_cb)(void* opaque, const char* fct_name);
-
-/**
- * Enumeration of the Video engine to be used on output.
- * can be passed to @a libvlc_video_set_output_callbacks
- */
-typedef enum libvlc_video_engine_t {
-    libvlc_video_engine_opengl,
-    libvlc_video_engine_gles2,
-} libvlc_video_engine_t;
-
-/**
- * Set callbacks and data to render decoded video to a custom texture
- *
- * \warning VLC will perform video rendering in its own thread and at its own rate,
- * You need to provide your own synchronisation mechanism.
- *
- * OpenGL context need to be created before playing a media.
- *
- * \param mp the media player
- * \param engine the GPU engine to use
- * \param setup_cb callback called to initialize user data
- * \param cleanup_cb callback called to clean up user data
- * \param update_output_cb callback called to get the size of the video
- * \param swap_cb callback called after rendering a video frame (cannot be NULL)
- * \param makeCurrent_cb callback called to enter/leave the opengl context (cannot be NULL for \ref libvlc_video_engine_opengl and for \ref libvlc_video_engine_gles2)
- * \param getProcAddress_cb opengl function loading callback (cannot be NULL for \ref libvlc_video_engine_opengl and for \ref libvlc_video_engine_gles2)
- * \param opaque private pointer passed to callbacks
- * \libvlc_return_bool
- * \version LibVLC 4.0.0 or later
- */
-LIBVLC_API
-int libvlc_video_set_output_callbacks( libvlc_media_player_t *mp,
-                                        libvlc_video_engine_t engine,
-                                        libvlc_video_setup_cb setup_cb,
-                                        libvlc_video_cleanup_cb cleanup_cb,
-                                        libvlc_video_update_output_cb update_output_cb,
-                                        libvlc_video_swap_cb swap_cb,
-                                        libvlc_video_makeCurrent_cb makeCurrent_cb,
-                                        libvlc_video_getProcAddress_cb getProcAddress_cb,
-                                        void* opaque );
-
 /**
  * Set decoded video chroma and dimensions.
  * This only works in combination with libvlc_video_set_callbacks(),
@@ -553,6 +455,108 @@ void libvlc_video_set_format_callbacks( libvlc_media_player_t *mp,
                                         libvlc_video_format_cb setup,
                                         libvlc_video_cleanup_cb cleanup );
 
+
+/**
+ * Enumeration of the Video engine to be used on output.
+ * can be passed to @a libvlc_video_set_output_callbacks
+ */
+typedef enum libvlc_video_engine_t {
+    /** OpenGL rendering engine */
+    libvlc_video_engine_opengl,
+    /** OpenGL ES2 rendering engine */
+    libvlc_video_engine_gles2,
+} libvlc_video_engine_t;
+
+typedef struct
+{
+    unsigned width;  /** rendering video width in pixel */
+    unsigned height; /** rendering video height in pixel */
+} libvlc_video_callback_cfg_t;
+
+/**
+ * List of control passed to the @a libvlc_video_control_cb callback
+ */
+typedef enum libvlc_video_callback_control_t {
+    /** Setup the rendering environment.
+     *
+     * \ref input ignored
+     * \ref output pointer depending on the type of the engine
+     */
+    LIBVLC_VIDEO_SETUP,
+
+    /** Cleanup the rendering environment initialized during \ref LIBVLC_VIDEO_SETUP.
+     *
+     * \ref input ignored
+     * \ref output ignored
+     */
+    LIBVLC_VIDEO_CLEANUP,
+
+    /** Update the rendering output setup.
+     *
+     * \ref input const libvlc_video_callback_cfg_t* with the new setup
+     * \ref output ignored
+     */
+    LIBVLC_VIDEO_UPDATE_OUTPUT,
+
+    /** Callback prototype called after performing drawing calls.
+     *
+     * \ref input ignored
+     * \ref output ignored
+     */
+    LIBVLC_VIDEO_SWAP,
+
+    /** Set up the OpenGL context for rendering.
+     *
+     * \ref input non-NULL to set the OpenGL context as current, NULL to unset it.
+     * \ref output ignored
+     *
+     * \note Only used for \ref libvlc_video_engine_opengl and \ref libvlc_video_engine_gles2 engines.
+     */
+    LIBVLC_VIDEO_MAKE_CURRENT,
+
+    /** Load OpenGL functions.
+     *
+     * \ref input const char * with name of the opengl function to load
+     * \ref output a pointer to the named OpenGL function the NULL otherwise
+     *
+     * \note Only used for \ref libvlc_video_engine_opengl and \ref libvlc_video_engine_gles2 engines.
+     */
+    LIBVLC_VIDEO_GET_PROCADDRESS,
+
+} libvlc_video_callback_control_t;
+
+/**
+ * Callback prototype for the @a libvlc_video_set_surface_callbacks callback.
+ *
+ * \param opaque private pointer passed to the @a libvlc_video_set_surface_callbacks() [IN]
+ * \version LibVLC 4.0.0 or later
+ */
+typedef int (*libvlc_video_control_cb)(void* opaque,
+                                       libvlc_video_callback_control_t control,
+                                       const void *input,
+                                       void **output);
+
+
+/**
+ * Set callbacks and data to render decoded video to a custom texture
+ *
+ * \warning VLC will perform video rendering in its own thread and at its own rate,
+ * You need to provide your own synchronisation mechanism.
+ *
+ * \param mp the media player
+ * \param engine the GPU engine to use
+ * \param control_cb callback that receives all the \ref libvlc_video_callback_control_t
+ * \param opaque private pointer passed to the control callback
+ * \libvlc_return_bool
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API
+int libvlc_video_set_surface_callbacks( libvlc_media_player_t *mp,
+                                        libvlc_video_engine_t engine,
+                                        libvlc_video_control_cb control_cb,
+                                        void* opaque );
+
+
 /**
  * Set the NSView handler where the media player should render its video output.
  *
diff --git a/include/vlc_vout_display.h b/include/vlc_vout_display.h
index e7877f4ad0..bb2d60d7cc 100644
--- a/include/vlc_vout_display.h
+++ b/include/vlc_vout_display.h
@@ -461,5 +461,63 @@ void vout_display_TranslateMouseState(vout_display_t *vd, vlc_mouse_t *video,
  */
 VLC_API void vout_display_SendMouseMovedDisplayCoordinates(vout_display_t *vd, int m_x, int m_y);
 
+/*** rendering to external surfaces ***/
+typedef struct
+{
+    unsigned width, height;
+} vlc_video_surface_cfg_t; /* must match libvlc_video_callback_cfg_t */
+
+typedef enum
+{
+    VLC_VIDEO_SURFACE_SETUP,
+    VLC_VIDEO_SURFACE_CLEANUP,
+    VLC_VIDEO_SURFACE_UPDATE_OUTPUT,
+    VLC_VIDEO_SURFACE_SWAP,
+    VLC_VIDEO_SURFACE_MAKE_CURRENT,
+    VLC_VIDEO_SURFACE_GET_PROCADDRESS,
+} vlc_video_surface_control_t; /* must match libvlc_video_callback_control_t */
+
+typedef int (*vlc_video_surface_control)(void* opaque,
+                                         vlc_video_surface_control_t control,
+                                         const void *input,
+                                         void **output);
+
+static inline void *vlc_video_surface_setup(void *opaque, vlc_video_surface_control ctrl)
+{
+    void *result = (void*)(intptr_t)1; /* so we don't return NULL on success */
+    if (ctrl(opaque, VLC_VIDEO_SURFACE_SETUP, 0, &result) != 0)
+        return NULL;
+    return result;
+}
+
+static inline void vlc_video_surface_cleanup(void *opaque, vlc_video_surface_control ctrl)
+{
+    ctrl(opaque, VLC_VIDEO_SURFACE_CLEANUP, 0, NULL);
+}
+
+static inline bool vlc_video_surface_update_output(void *opaque, vlc_video_surface_control ctrl, const vlc_video_surface_cfg_t *cfg)
+{
+    return ctrl(opaque, VLC_VIDEO_SURFACE_UPDATE_OUTPUT, cfg, NULL) == 0;
+}
+
+static inline void vlc_video_surface_swap(void *opaque, vlc_video_surface_control ctrl)
+{
+    ctrl(opaque, VLC_VIDEO_SURFACE_SWAP, 0, NULL);
+}
+
+static inline bool vlc_video_surface_make_current(void *opaque, vlc_video_surface_control ctrl, bool set)
+{
+    void *p_set = set ? (void*)(intptr_t)1 : NULL;
+    return ctrl(opaque, VLC_VIDEO_SURFACE_MAKE_CURRENT, p_set, NULL) == 0;
+}
+
+static inline void *vlc_video_surface_get_proc(void *opaque, vlc_video_surface_control ctrl, const char* name)
+{
+    void *result;
+    if (ctrl(opaque, VLC_VIDEO_SURFACE_GET_PROCADDRESS, name, &result) != 0)
+        return NULL;
+    return result;
+}
+
 /** @} */
 #endif /* VLC_VOUT_DISPLAY_H */
diff --git a/lib/libvlc.sym b/lib/libvlc.sym
index 285cf4f7af..e948b57120 100644
--- a/lib/libvlc.sym
+++ b/lib/libvlc.sym
@@ -246,7 +246,7 @@ libvlc_video_set_crop_geometry
 libvlc_video_set_deinterlace
 libvlc_video_set_format
 libvlc_video_set_format_callbacks
-libvlc_video_set_output_callbacks
+libvlc_video_set_surface_callbacks
 libvlc_video_set_key_input
 libvlc_video_set_logo_int
 libvlc_video_set_logo_string
diff --git a/lib/media_player.c b/lib/media_player.c
index 4079efd4b0..11dae47448 100644
--- a/lib/media_player.c
+++ b/lib/media_player.c
@@ -640,12 +640,7 @@ libvlc_media_player_new( libvlc_instance_t *instance )
     var_Create (mp, "vmem-pitch", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
 
     var_Create( mp, "vout-cb-opaque", VLC_VAR_ADDRESS );
-    var_Create( mp, "vout-cb-setup", VLC_VAR_ADDRESS );
-    var_Create( mp, "vout-cb-cleanup", VLC_VAR_ADDRESS );
-    var_Create( mp, "vout-cb-update-output", VLC_VAR_ADDRESS );
-    var_Create( mp, "vout-cb-swap", VLC_VAR_ADDRESS );
-    var_Create( mp, "vout-cb-get-proc-address", VLC_VAR_ADDRESS );
-    var_Create( mp, "vout-cb-make-current", VLC_VAR_ADDRESS );
+    var_Create( mp, "vout-cb-control", VLC_VAR_ADDRESS );
 
     var_Create (mp, "avcodec-hw", VLC_VAR_STRING);
     var_Create (mp, "drawable-xid", VLC_VAR_INTEGER);
@@ -1160,14 +1155,9 @@ void libvlc_video_set_format( libvlc_media_player_t *mp, const char *chroma,
     var_SetInteger( mp, "vmem-pitch", pitch );
 }
 
-int libvlc_video_set_output_callbacks( libvlc_media_player_t *mp,
+int libvlc_video_set_surface_callbacks( libvlc_media_player_t *mp,
                                         libvlc_video_engine_t engine,
-                                        libvlc_video_setup_cb setup_cb,
-                                        libvlc_video_cleanup_cb cleanup_cb,
-                                        libvlc_video_update_output_cb update_output_cb,
-                                        libvlc_video_swap_cb swap_cb,
-                                        libvlc_video_makeCurrent_cb makeCurrent_cb,
-                                        libvlc_video_getProcAddress_cb getProcAddress_cb,
+                                        libvlc_video_control_cb control_cb,
                                         void* opaque )
 {
 #ifdef __ANDROID__
@@ -1191,12 +1181,7 @@ int libvlc_video_set_output_callbacks( libvlc_media_player_t *mp,
         return 0;
 
     var_SetAddress( mp, "vout-cb-opaque", opaque );
-    var_SetAddress( mp, "vout-cb-setup", setup_cb );
-    var_SetAddress( mp, "vout-cb-cleanup", cleanup_cb );
-    var_SetAddress( mp, "vout-cb-update-output", update_output_cb );
-    var_SetAddress( mp, "vout-cb-swap", swap_cb );
-    var_SetAddress( mp, "vout-cb-get-proc-address", getProcAddress_cb );
-    var_SetAddress( mp, "vout-cb-make-current", makeCurrent_cb );
+    var_SetAddress( mp, "vout-cb-control", control_cb );
     return 1;
 }
 
@@ -2048,3 +2033,16 @@ int libvlc_media_player_get_role(libvlc_media_player_t *mp)
     free(str);
     return ret;
 }
+
+#include <vlc_vout_display.h>
+
+static_assert(VLC_VIDEO_SURFACE_SETUP              == LIBVLC_VIDEO_SETUP &&
+              VLC_VIDEO_SURFACE_CLEANUP            == LIBVLC_VIDEO_CLEANUP &&
+              VLC_VIDEO_SURFACE_UPDATE_OUTPUT      == LIBVLC_VIDEO_UPDATE_OUTPUT &&
+              VLC_VIDEO_SURFACE_SWAP               == LIBVLC_VIDEO_SWAP &&
+              VLC_VIDEO_SURFACE_MAKE_CURRENT       == LIBVLC_VIDEO_MAKE_CURRENT &&
+              VLC_VIDEO_SURFACE_GET_PROCADDRESS    == LIBVLC_VIDEO_GET_PROCADDRESS &&
+              sizeof(vlc_video_surface_cfg_t)           == sizeof(libvlc_video_callback_cfg_t) &&
+              offsetof(vlc_video_surface_cfg_t, width)  == offsetof(libvlc_video_callback_cfg_t, width) &&
+              offsetof(vlc_video_surface_cfg_t, height) == offsetof(libvlc_video_callback_cfg_t, height)
+              , "video surface mismatch");
diff --git a/modules/video_output/vgl.c b/modules/video_output/vgl.c
index 3617a096a0..7cacae451b 100644
--- a/modules/video_output/vgl.c
+++ b/modules/video_output/vgl.c
@@ -31,66 +31,59 @@
 
 struct vout_display_sys_t
 {
-    void (*cleanupCb)(void* opaque);
-    bool (*setupCb)(void* opaque);
-    void (*resizeCb)(void* opaque, unsigned, unsigned);
-    void (*swapCb)(void* opaque);
-    bool (*makeCurrentCb)(void* opaque, bool);
-    void* (*getProcAddressCb)(void* opaque, const char *name);
-
     void* opaque;
-    unsigned width;
-    unsigned height;
+    vlc_video_surface_control controlCb;
+    vlc_video_surface_cfg_t   current;
 };
 
 
 static void *OurGetProcAddress(vlc_gl_t *gl, const char *name)
 {
     vout_display_sys_t *sys = gl->sys;
-    return sys->getProcAddressCb(sys->opaque, name);
+    return vlc_video_surface_get_proc( sys->opaque, sys->controlCb, name );
 }
 
 static int MakeCurrent(vlc_gl_t *gl)
 {
     vout_display_sys_t *sys = gl->sys;
-    bool success = sys->makeCurrentCb(sys->opaque, true);
-    return success ? VLC_SUCCESS : VLC_EGENERIC;
+    bool ok = vlc_video_surface_make_current( sys->opaque, sys->controlCb, true );
+    return ok ? VLC_SUCCESS : VLC_EGENERIC;
 }
 
 static void ReleaseCurrent(vlc_gl_t *gl)
 {
     vout_display_sys_t *sys = gl->sys;
-    sys->makeCurrentCb(sys->opaque, false);
+    vlc_video_surface_make_current( sys->opaque, sys->controlCb, false );
 }
 
 static void VglSwapBuffers(vlc_gl_t *gl)
 {
     vout_display_sys_t *sys = gl->sys;
-    sys->swapCb(sys->opaque);
+    vlc_video_surface_swap( sys->opaque, sys->controlCb );
 }
 
 static void Resize(vlc_gl_t * gl, unsigned w, unsigned h)
 {
     vout_display_sys_t *sys = gl->sys;
-    if( sys->width == w && sys->height == h )
-        return;
+    vlc_video_surface_cfg_t cfg;
+    cfg.width = w;
+    cfg.height = h;
 
-    if( !sys->resizeCb )
+    if( memcpy( &sys->current, &cfg, sizeof(cfg) ) == 0 )
         return;
 
     MakeCurrent(gl);
-    sys->resizeCb(sys->opaque, w, h);
+    bool ok = vlc_video_surface_update_output(sys->opaque, sys->controlCb, &cfg);
     ReleaseCurrent(gl);
-    sys->width = w;
-    sys->height = h;
+    if (ok)
+        sys->current = cfg;
 }
 
 static void Close(vlc_object_t *object)
 {
     vlc_gl_t *gl = (vlc_gl_t *)object;
     vout_display_sys_t *sys = gl->sys;
-    if( sys->cleanupCb )
-        sys->cleanupCb(sys->opaque);
+    vlc_video_surface_cleanup( sys->opaque, sys->controlCb );
 }
 
 
@@ -114,12 +107,7 @@ static int Open(vlc_object_t *object)
         return VLC_ENOMEM;
 
     sys->opaque = var_InheritAddress(gl, "vout-cb-opaque");
-    sys->setupCb = var_InheritAddress(gl, "vout-cb-setup");
-    sys->cleanupCb = var_InheritAddress(gl, "vout-cb-cleanup");
-    sys->resizeCb = var_InheritAddress(gl, "vout-cb-update-output");
-    SET_CALLBACK_ADDR(sys->swapCb, "vout-cb-swap");
-    SET_CALLBACK_ADDR(sys->makeCurrentCb, "vout-cb-make-current");
-    SET_CALLBACK_ADDR(sys->getProcAddressCb, "vout-cb-get-proc-address");
+    SET_CALLBACK_ADDR(sys->controlCb, "vout-cb-control");
 
     gl->makeCurrent = MakeCurrent;
     gl->releaseCurrent = ReleaseCurrent;
@@ -127,12 +115,11 @@ static int Open(vlc_object_t *object)
     gl->swap = VglSwapBuffers;
     gl->getProcAddress = OurGetProcAddress;
 
-    if( sys->setupCb )
-        if( !sys->setupCb(sys->opaque) )
-        {
-            msg_Err( gl, "user setup failed" );
-            return VLC_EGENERIC;
-        }
+    if ( vlc_video_surface_setup(sys->opaque, sys->controlCb) != NULL )
+    {
+        msg_Err( gl, "user setup failed" );
+        return VLC_EGENERIC;
+    }
 
     return VLC_SUCCESS;
 }
-- 
2.17.1



More information about the vlc-devel mailing list