[vlc-devel] [RFC 5/8] libvlc: pass the video output callbacks using a structure

Steve Lhomme robux4 at ycbcr.xyz
Tue Nov 20 16:42:39 CET 2018


This way it can be expanded in the future without changing existing code.

The engine is put with the callback. Maybe at some point it should be possible
to set callbacks per engine and have all of them used depending on what the vout
is in use.
---
 doc/libvlc/sdl_opengl_player.cpp  | 16 +++++--
 include/vlc/libvlc_media_player.h | 77 ++++++++++++++++++++++---------
 lib/libvlc.sym                    |  2 +
 lib/media_player.c                | 43 +++++++++--------
 4 files changed, 93 insertions(+), 45 deletions(-)

diff --git a/doc/libvlc/sdl_opengl_player.cpp b/doc/libvlc/sdl_opengl_player.cpp
index dabc430bdd..80d66178ae 100644
--- a/doc/libvlc/sdl_opengl_player.cpp
+++ b/doc/libvlc/sdl_opengl_player.cpp
@@ -78,11 +78,19 @@ public:
             libvlc_media_release(m_media);
             return false;
         }
+
+        libvlc_video_engine_callbacks_t *callbacks =
+                libvlc_video_engine_callbacks_get( libvlc_video_engine_opengl );
+        callbacks->opaque = this;
+        callbacks->setup_cb = setup;
+        callbacks->cleanup_cb = cleanup;
+        callbacks->update_output_cb = resize;
+        callbacks->swap_cb = swap;
+        callbacks->makeCurrent_cb = make_current;
+        callbacks->getProcAddress_cb = get_proc_address;
+
         // 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);
+        libvlc_video_set_output_callbacks(m_mp, callbacks);
 
         // Play the video
         libvlc_media_player_play (m_mp);
diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h
index 45cd47afac..9158fc328b 100644
--- a/include/vlc/libvlc_media_player.h
+++ b/include/vlc/libvlc_media_player.h
@@ -425,7 +425,7 @@ void libvlc_video_set_callbacks( libvlc_media_player_t *mp,
 /**
  * Callback prototype called to initialize user data.
  *
- * \param opaque private pointer passed to the @a libvlc_video_set_output_callbacks() [IN]
+ * \param opaque private pointer passed in the @a libvlc_video_engine_callbacks_t [IN]
  * \return true on success
  * \version LibVLC 4.0.0 or later
  */
@@ -435,7 +435,7 @@ 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]
+ * \param opaque private pointer passed in the @a libvlc_video_engine_callbacks_t [IN]
  * \version LibVLC 4.0.0 or later
  */
 typedef void (*libvlc_video_cleanup_cb)(void* opaque);
@@ -443,7 +443,7 @@ 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 opaque private pointer passed in the @a libvlc_video_engine_callbacks_t [IN]
  * \param width video width in pixel [IN]
  * \param height video height in pixel [IN]
  * \return true on success
@@ -455,7 +455,7 @@ typedef bool (*libvlc_video_update_output_cb)(void* opaque, unsigned width, unsi
 /**
  * Callback prototype called after performing drawing calls.
  *
- * \param opaque private pointer passed to the @a libvlc_video_set_output_callbacks() [IN]
+ * \param opaque private pointer passed in the @a libvlc_video_engine_callbacks_t [IN]
  * \version LibVLC 4.0.0 or later
  */
 typedef void (*libvlc_video_swap_cb)(void* opaque);
@@ -463,7 +463,7 @@ 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 opaque private pointer passed in the @a libvlc_video_engine_callbacks_t [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
@@ -473,7 +473,7 @@ 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 opaque private pointer passed in the @a libvlc_video_engine_callbacks_t [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
@@ -490,34 +490,67 @@ typedef enum libvlc_video_engine_t {
 } libvlc_video_engine_t;
 
 /**
- * Set callbacks and data to render decoded video to a custom texture
+ * The structure should be created by libvlc_video_engine_callbacks_get().
  *
- * \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 opaque private pointer passed to each callbacks
  * \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)
  * \param getProcAddress_cb opengl function loading callback (cannot be NULL)
- * \param opaque private pointer passed to callbacks
+ * \version LibVLC 4.0.0 or later
+ */
+typedef struct libvlc_video_engine_callbacks_t
+{
+    libvlc_video_engine_t           engine;
+
+    void                            *opaque;
+
+    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;
+
+    /* OpenGL/GLES2 specific callbacks */
+    libvlc_video_makeCurrent_cb     makeCurrent_cb;
+    libvlc_video_getProcAddress_cb  getProcAddress_cb;
+} libvlc_video_engine_callbacks_t;
+
+/**
+ * Initialize a libvlc_video_engine_callbacks_t structure.
+ *
+ * \param engine the engine to initialize the callbacks for.
+ * \return a libvlc_video_engine_callbacks_t structure or NULL
+ */
+LIBVLC_API
+libvlc_video_engine_callbacks_t *libvlc_video_engine_callbacks_get(
+        libvlc_video_engine_t engine );
+
+/**
+ * Release (free) libvlc_video_engine_callbacks_t
+ *
+ * \param cb the structure to release
+ */
+LIBVLC_API
+void libvlc_video_engine_callbacks_release( libvlc_video_engine_callbacks_t *cb );
+
+/**
+ * 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 callbacks the callbacks to use for the given engine.
  * \version LibVLC 4.0.0 or later
  */
 LIBVLC_API
 void 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 );
+                                        libvlc_video_engine_callbacks_t *callbacks );
 
 /**
  * Set decoded video chroma and dimensions.
diff --git a/lib/libvlc.sym b/lib/libvlc.sym
index 285cf4f7af..042f79b279 100644
--- a/lib/libvlc.sym
+++ b/lib/libvlc.sym
@@ -246,6 +246,8 @@ libvlc_video_set_crop_geometry
 libvlc_video_set_deinterlace
 libvlc_video_set_format
 libvlc_video_set_format_callbacks
+libvlc_video_engine_callbacks_get
+libvlc_video_engine_callbacks_release
 libvlc_video_set_output_callbacks
 libvlc_video_set_key_input
 libvlc_video_set_logo_int
diff --git a/lib/media_player.c b/lib/media_player.c
index 89ba10d638..ef9bc329fd 100644
--- a/lib/media_player.c
+++ b/lib/media_player.c
@@ -98,10 +98,10 @@ static void libvlc_media_player_destroy( libvlc_media_player_t *p_mi );
 
 /*
  * The input lock protects the input and input resource pointer.
- * It MUST NOT be used from callbacks.
+ * It MUST NOT be used from callbacks->
  *
  * The object lock protects the reset, namely the media and the player state.
- * It can, and usually needs to be taken from callbacks.
+ * It can, and usually needs to be taken from callbacks->
  * The object lock can be acquired under the input lock... and consequently
  * the opposite order is STRICTLY PROHIBITED.
  */
@@ -413,7 +413,7 @@ input_event_changed( vlc_object_t * p_this, char const * psz_cmd,
     else if ( newval.i_int == INPUT_EVENT_ES )
     {
         /* Send ESSelected events from this callback ("intf-event") and not
-         * from "audio-es", "video-es", "spu-es" callbacks. Indeed, these
+         * from "audio-es", "video-es", "spu-es" callbacks-> Indeed, these
          * callbacks are not triggered when the input_thread changes an ES
          * while this callback is. */
         struct {
@@ -1161,14 +1161,7 @@ void libvlc_video_set_format( libvlc_media_player_t *mp, const char *chroma,
 }
 
 void 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 )
+                                        libvlc_video_engine_callbacks_t *callbacks )
 {
 #ifdef __ANDROID__
     //use the default android window
@@ -1177,7 +1170,7 @@ void libvlc_video_set_output_callbacks( libvlc_media_player_t *mp,
     var_SetString( mp, "window", "wdummy");
 #endif
 
-    if( engine == libvlc_video_engine_gles2 )
+    if( callbacks->engine == libvlc_video_engine_gles2 )
     {
         var_SetString ( mp, "vout", "gles2" );
         var_SetString ( mp, "gles2", "vgl" );
@@ -1188,15 +1181,27 @@ void libvlc_video_set_output_callbacks( libvlc_media_player_t *mp,
         var_SetString ( mp, "gl", "vgl");
     }
 
-    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-opaque", callbacks->opaque );
+    var_SetAddress( mp, "vout-cb-setup", callbacks->setup_cb );
+    var_SetAddress( mp, "vout-cb-cleanup", callbacks->cleanup_cb );
+    var_SetAddress( mp, "vout-cb-update-output", callbacks->update_output_cb );
+    var_SetAddress( mp, "vout-cb-swap", callbacks->swap_cb );
+    var_SetAddress( mp, "vout-cb-get-proc-address", callbacks->getProcAddress_cb );
+    var_SetAddress( mp, "vout-cb-make-current", callbacks->makeCurrent_cb );
 }
 
+libvlc_video_engine_callbacks_t *libvlc_video_engine_callbacks_get( libvlc_video_engine_t engine )
+{
+    libvlc_video_engine_callbacks_t *callbacks = calloc(1, sizeof(*callbacks));
+    if (callbacks)
+        callbacks->engine = engine;
+    return callbacks;
+}
+
+void libvlc_video_engine_callbacks_release(libvlc_video_engine_callbacks_t * cb)
+{
+    free(cb);
+}
 
 /**************************************************************************
  * set_nsobject
-- 
2.17.1



More information about the vlc-devel mailing list