diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h index e19b22023f..2301e90f50 100644 --- a/include/vlc/libvlc_media_player.h +++ b/include/vlc/libvlc_media_player.h @@ -2944,6 +2944,67 @@ libvlc_media_player_time_point_get_next_date(const libvlc_media_player_time_poin /** @} libvlc_media_player_watch_time */ +/** \defgroup libvlc_media_player_concurrency LibVLC media player concurrency API + * @{ + */ + +/** + * Lock the media_player internal lock + + * The lock is recursive, so it's safe to use it multiple times from the same + * thread. You must call libvlc_media_player_unlock() the same number of times + * you called libvlc_media_player_lock(). + * + * Locking is not mandatory before calling a libvlc_media_player_t function + * since they will automatically hold the lock internally. + * + * This lock can be used to synchronise user variables that interact with the + * libvlc_media_player_t or can be used to call several functions together. + * + * \param mp media player object + * \version LibVLC 4.0.0 or later + */ +LIBVLC_API void libvlc_media_player_lock( libvlc_media_player_t *mp ); + +/** + * Unlock the media_player internal lock + * + * \see libvlc_media_player_lock + * + * \param mp media player object locked using /ref libvlc_media_player_lock + * \version LibVLC 4.0.0 or later + */ +LIBVLC_API void libvlc_media_player_unlock( libvlc_media_player_t *mp ); + +/** + * Wait for an event to be signalled + * + * \note this is equivalent to pthread_cond_wait() with the + * libvlc_media_player_t internal mutex and condition variable. This function + * may spuriously wake up even without libvlc_media_player_signal() being + * called. + * + * \warning this function must not be called from any libvlc callbacks and + * events. The lock should be held only one time before waiting. + * + * \param mp media player object locked using /ref libvlc_media_player_lock + * \version LibVLC 4.0.0 or later + */ +LIBVLC_API void libvlc_media_player_wait( libvlc_media_player_t *mp ); + +/** + * Signal all threads waiting for a signalling event + * + * \note this is equivalent to pthread_cond_broadcast() with the + * libvlc_media_player_t internal condition variable. + * + * \param mp media player object locked using /ref libvlc_media_player_lock + * \version LibVLC 4.0.0 or later + */ +LIBVLC_API void libvlc_media_player_signal( libvlc_media_player_t *mp ); + +/** @} libvlc_media_player_concurrency */ + /** @} media_player */ # ifdef __cplusplus diff --git a/lib/libvlc.sym b/lib/libvlc.sym index d05db9c532..ddb32f4a3b 100644 --- a/lib/libvlc.sym +++ b/lib/libvlc.sym @@ -159,6 +159,10 @@ libvlc_media_player_previous_chapter libvlc_media_player_record libvlc_media_player_release libvlc_media_player_retain +libvlc_media_player_lock +libvlc_media_player_unlock +libvlc_media_player_wait +libvlc_media_player_signal libvlc_media_player_set_android_context libvlc_media_player_set_chapter libvlc_media_player_set_equalizer diff --git a/lib/media_player.c b/lib/media_player.c index f080caead4..0503496895 100644 --- a/lib/media_player.c +++ b/lib/media_player.c @@ -777,6 +777,7 @@ libvlc_media_player_new( libvlc_instance_t *instance ) NULL, NULL); if (unlikely(!mp->player)) goto error1; + vlc_cond_init(&mp->wait); vlc_player_Lock(mp->player); @@ -890,6 +891,26 @@ void libvlc_media_player_release( libvlc_media_player_t *p_mi ) libvlc_media_player_destroy( p_mi ); } +void libvlc_media_player_lock( libvlc_media_player_t *mp ) +{ + vlc_player_Lock(mp->player); +} + +void libvlc_media_player_unlock( libvlc_media_player_t *mp ) +{ + vlc_player_Unlock(mp->player); +} + +void libvlc_media_player_wait( libvlc_media_player_t *mp ) +{ + vlc_player_CondWait(mp->player, &mp->wait); +} + +void libvlc_media_player_signal( libvlc_media_player_t *mp ) +{ + vlc_cond_broadcast(&mp->wait); +} + /************************************************************************** * Retain a Media Instance object. * diff --git a/lib/media_player_internal.h b/lib/media_player_internal.h index 2d7e5606fa..fb1b26c0ef 100644 --- a/lib/media_player_internal.h +++ b/lib/media_player_internal.h @@ -41,6 +41,7 @@ struct libvlc_media_player_t vlc_player_t *player; vlc_player_listener_id *listener; vlc_player_aout_listener_id *aout_listener; + vlc_cond_t wait; struct libvlc_instance_t * p_libvlc_instance; /* Parent instance */ libvlc_media_t * p_md; /* current media descriptor */