[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