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

Jean-Baptiste Kempf jb at videolan.org
Tue Nov 20 17:19:40 CET 2018


I am not sure if that is wise, wrt ABI/API.

Thomas, RĂ©mi?

On Tue, 20 Nov 2018, at 16:42, Steve Lhomme wrote:
> 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
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


-- 
Jean-Baptiste Kempf -  President
+33 672 704 734


More information about the vlc-devel mailing list