[vlc-devel] [PATCH] player: reorganize header

Thomas Guillem thomas at gllm.fr
Tue Aug 6 16:13:52 CEST 2019


From: Alexandre Janniaux <ajanni at videolabs.io>

Group every struct/enum/functions by group instead of having all structs, all
enums then all functions.

Split the header by the following doxygen groups:
 - Player instance
 - Playback control
 - Title and chapter control
 - Program control
 - Tracks control
 - Tracks synchronisation (delay)
 - Teletext control
 - External renderer control
 - Audio output control
 - Video output control
 - Player events

No functional changes.
---
 include/vlc_player.h | 3602 +++++++++++++++++++++---------------------
 1 file changed, 1840 insertions(+), 1762 deletions(-)

diff --git a/include/vlc_player.h b/include/vlc_player.h
index e1010decd6..3d0c040d3f 100644
--- a/include/vlc_player.h
+++ b/include/vlc_player.h
@@ -25,7 +25,7 @@
 #include <vlc_aout.h>
 
 /**
- * @defgroup player Player
+ * @defgroup vlc_player Player
  * @ingroup input
  * VLC Player API
  * @brief
@@ -54,154 +54,177 @@ digraph player_states {
  * VLC Player API
  */
 
+/**
+ * @defgroup vlc_player__instance Player instance
+ * @{
+ */
+
 /**
  * Player opaque structure.
  */
 typedef struct vlc_player_t vlc_player_t;
 
 /**
- * Player listener opaque structure.
- *
- * This opaque structure is returned by vlc_player_AddListener() and can be
- * used to remove the listener via vlc_player_RemoveListener().
+ * Player lock type (normal or reentrant)
  */
-typedef struct vlc_player_listener_id vlc_player_listener_id;
+enum vlc_player_lock_type
+{
+    /**
+     * Normal lock
+     *
+     * If the player is already locked, subsequent calls to vlc_player_Lock()
+     * will deadlock.
+     */
+    VLC_PLAYER_LOCK_NORMAL,
+
+    /**
+     * Reentrant lock
+     *
+     * If the player is already locked, subsequent calls to vlc_player_Lock()
+     * will still succeed. To unlock the player, one call to
+     * vlc_player_Unlock() per vlc_player_Lock() is necessary.
+     */
+    VLC_PLAYER_LOCK_REENTRANT,
+};
 
 /**
- * Player vout listener opaque structure.
+ * Action when the player is stopped
  *
- * This opaque structure is returned by vlc_player_vout_AddListener() and can
- * be used to remove the listener via vlc_player_vout_RemoveListener().
+ * @see vlc_player_SetMediaStoppedAction()
  */
-typedef struct vlc_player_vout_listener_id vlc_player_vout_listener_id;
+enum vlc_player_media_stopped_action {
+    /** Continue (or stop if there is no next media), default behavior */
+    VLC_PLAYER_MEDIA_STOPPED_CONTINUE,
+    /** Pause when reaching the end of file */
+    VLC_PLAYER_MEDIA_STOPPED_PAUSE,
+    /** Stop, even if there is a next media to play */
+    VLC_PLAYER_MEDIA_STOPPED_STOP,
+    /** Exit VLC */
+    VLC_PLAYER_MEDIA_STOPPED_EXIT,
+};
 
 /**
- * Player aout listener opaque structure.
+ * Callbacks for the owner of the player.
  *
- * This opaque structure is returned by vlc_player_aout_AddListener() and can
- * be used to remove the listener via vlc_player_aout_RemoveListener().
+ * These callbacks are needed to control the player flow (via the
+ * vlc_playlist_t as a owner for example). It can only be set when creating the
+ * player via vlc_player_New().
+ *
+ * All callbacks are called with the player locked (cf. vlc_player_Lock()), and
+ * from any thread (even the current one).
  */
-typedef struct vlc_player_aout_listener_id vlc_player_aout_listener_id;
+struct vlc_player_media_provider
+{
+    /**
+     * Called when the player requires a new media
+     *
+     * @note The returned media must be already held with input_item_Hold()
+     *
+     * @param player locked player instance
+     * @param data opaque pointer set from vlc_player_New()
+     * @return the next media to play, held by the callee with input_item_Hold()
+     */
+    input_item_t *(*get_next)(vlc_player_t *player, void *data);
+};
 
 /**
- * Player program structure.
+ * Create a new player instance
+ *
+ * @param parent parent VLC object
+ * @param media_provider pointer to a media_provider structure or NULL, the
+ * structure must be valid during the lifetime of the player
+ * @param media_provider_data opaque data used by provider callbacks
+ * @return a pointer to a valid player instance or NULL in case of error
  */
-struct vlc_player_program
-{
-    /** Id used for vlc_player_SelectProgram() */
-    int group_id;
-    /** Program name, always valid */
-    const char *name;
-    /** True if the program is selected */
-    bool selected;
-    /** True if the program is scrambled */
-    bool scrambled;
-};
+VLC_API vlc_player_t *
+vlc_player_New(vlc_object_t *parent, enum vlc_player_lock_type lock_type,
+               const struct vlc_player_media_provider *media_provider,
+               void *media_provider_data);
 
 /**
- * Player track structure.
+ * Delete a player instance
  *
- * A track is a representation of an ES identifier at a given time. Once the
- * player is unlocked, all content except the es_id pointer can be updated.
+ * This function stop any playback previously started and wait for their
+ * termination.
  *
- * @see vlc_player_cbs.on_track_list_changed
- * @see vlc_player_GetTrack
+ * @warning Blocking function if the player state is not STOPPED, don't call it
+ * from an UI thread in that case.
+ *
+ * @param player unlocked player instance created by vlc_player_New()
  */
-struct vlc_player_track
-{
-    /** Id used for any player actions, like vlc_player_SelectEsId() */
-    vlc_es_id_t *es_id;
-    /** Track name, always valid */
-    const char *name;
-    /** Es format */
-    es_format_t fmt;
-    /** True if the track is selected */
-    bool selected;
-};
+VLC_API void
+vlc_player_Delete(vlc_player_t *player);
 
 /**
- * Player chapter structure
+ * Lock the player.
+ *
+ * All player functions (except vlc_player_Delete()) need to be called while
+ * the player lock is held.
+ *
+ * @param player unlocked player instance
  */
-struct vlc_player_chapter
-{
-    /** Chapter name, always valid */
-    const char *name;
-    /** Position of this chapter */
-    vlc_tick_t time;
-};
+VLC_API void
+vlc_player_Lock(vlc_player_t *player);
 
-/** vlc_player_title.flags: The title is a menu. */
-#define VLC_PLAYER_TITLE_MENU         0x01
-/** vlc_player_title.flags: The title is interactive. */
-#define VLC_PLAYER_TITLE_INTERACTIVE  0x02
+/**
+ * Unlock the player
+ *
+ * @param player locked player instance
+ */
+VLC_API void
+vlc_player_Unlock(vlc_player_t *player);
 
-/** Player title structure */
-struct vlc_player_title
-{
-    /** Title name, always valid */
-    const char *name;
-    /** Length of the title */
-    vlc_tick_t length;
-    /** Bit flag of @ref VLC_PLAYER_TITLE_MENU and @ref
-     * VLC_PLAYER_TITLE_INTERACTIVE */
-    unsigned flags;
-    /** Number of chapters, can be 0 */
-    size_t chapter_count;
-    /** Array of chapters, can be NULL */
-    const struct vlc_player_chapter *chapters;
-};
+/**
+ * Wait on a condition variable
+ *
+ * This call allow users to use their own condition with the player mutex.
+ *
+ * @param player locked player instance
+ * @param cond external condition
+ */
+VLC_API void
+vlc_player_CondWait(vlc_player_t *player, vlc_cond_t *cond);
 
 /**
- * Opaque structure representing a list of @ref vlc_player_title.
+ * Setup an action when a media is stopped
  *
- * @see vlc_player_GetTitleList()
- * @see vlc_player_title_list_GetCount()
- * @see vlc_player_title_list_GetAt()
+ * @param player locked player instance
+ * @param action action to do when a media is stopped
  */
-typedef struct vlc_player_title_list vlc_player_title_list;
+VLC_API void
+vlc_player_SetMediaStoppedAction(vlc_player_t *player,
+                                 enum vlc_player_media_stopped_action action);
 
 /**
- * Menu (VCD/DVD/BD) and viewpoint navigations
+ * Ask to start in a paused state
  *
- * @see vlc_player_Navigate()
+ * This function can be used before vlc_player_Start()
+ *
+ * @param player locked player instance
+ * @param start_paused true to start in a paused state, false to cancel it
  */
-enum vlc_player_nav
-{
-    /** Activate the navigation item selected */
-    VLC_PLAYER_NAV_ACTIVATE,
-    /** Select a navigation item above or move the viewpoint up */
-    VLC_PLAYER_NAV_UP,
-    /** Select a navigation item under or move the viewpoint down */
-    VLC_PLAYER_NAV_DOWN,
-    /** Select a navigation item on the left or move the viewpoint left */
-    VLC_PLAYER_NAV_LEFT,
-    /** Select a navigation item on the right or move the viewpoint right */
-    VLC_PLAYER_NAV_RIGHT,
-    /** Activate the popup Menu (for BD) */
-    VLC_PLAYER_NAV_POPUP,
-    /** Activate disc Root Menu */
-    VLC_PLAYER_NAV_MENU,
-};
+VLC_API void
+vlc_player_SetStartPaused(vlc_player_t *player, bool start_paused);
 
 /**
- * Action of vlc_player_cbs.on_track_list_changed,
- * vlc_player_cbs.on_program_list_changed callbacks
+ * Enable or disable pause on cork event
+ *
+ * If enabled, the player will automatically pause and resume on cork events.
+ * In that case, cork events won't be propagated via callbacks.
+ * @see vlc_player_cbs.on_cork_changed
+ *
+ * @param player locked player instance
+ * @param enabled true to enable
  */
-enum vlc_player_list_action
-{
-    VLC_PLAYER_LIST_ADDED,
-    VLC_PLAYER_LIST_REMOVED,
-    VLC_PLAYER_LIST_UPDATED,
-};
+VLC_API void
+vlc_player_SetPauseOnCork(vlc_player_t *player, bool enabled);
+
+/** @} vlc_player__instance */
 
 /**
- * action of vlc_player_cbs.on_vout_changed callback
+ * @defgroup vlc_player__playback Playback control
+ * @{
  */
-enum vlc_player_vout_action
-{
-    VLC_PLAYER_VOUT_STARTED,
-    VLC_PLAYER_VOUT_STOPPED,
-};
 
 /**
  * State of the player
@@ -298,41 +321,26 @@ enum vlc_player_whence
 };
 
 /**
- * Player selection policy
+ * Menu (VCD/DVD/BD) and viewpoint navigations
  *
- * @see vlc_player_SelectEsId()
+ * @see vlc_player_Navigate()
  */
-enum vlc_player_select_policy
+enum vlc_player_nav
 {
-    /**
-     * Only one track per category is selected. Selecting a track with this
-     * policy will disable all other tracks for the same category.
-     */
-    VLC_PLAYER_SELECT_EXCLUSIVE,
-    /**
-     * Select multiple tracks for one category.
-     *
-     * Only one audio track can be selected at a time.
-     * Two subtitle tracks can be selected simultaneously.
-     * Multiple video tracks can be selected simultaneously.
-     */
-    VLC_PLAYER_SELECT_SIMULTANEOUS,
-};
-
-/**
- * Action when the player is stopped
- *
- * @see vlc_player_SetMediaStoppedAction()
- */
-enum vlc_player_media_stopped_action {
-    /** Continue (or stop if there is no next media), default behavior */
-    VLC_PLAYER_MEDIA_STOPPED_CONTINUE,
-    /** Pause when reaching the end of file */
-    VLC_PLAYER_MEDIA_STOPPED_PAUSE,
-    /** Stop, even if there is a next media to play */
-    VLC_PLAYER_MEDIA_STOPPED_STOP,
-    /** Exit VLC */
-    VLC_PLAYER_MEDIA_STOPPED_EXIT,
+    /** Activate the navigation item selected */
+    VLC_PLAYER_NAV_ACTIVATE,
+    /** Select a navigation item above or move the viewpoint up */
+    VLC_PLAYER_NAV_UP,
+    /** Select a navigation item under or move the viewpoint down */
+    VLC_PLAYER_NAV_DOWN,
+    /** Select a navigation item on the left or move the viewpoint left */
+    VLC_PLAYER_NAV_LEFT,
+    /** Select a navigation item on the right or move the viewpoint right */
+    VLC_PLAYER_NAV_RIGHT,
+    /** Activate the popup Menu (for BD) */
+    VLC_PLAYER_NAV_POPUP,
+    /** Activate disc Root Menu */
+    VLC_PLAYER_NAV_MENU,
 };
 
 /**
@@ -345,29 +353,6 @@ enum vlc_player_abloop
     VLC_PLAYER_ABLOOP_B,
 };
 
-/**
- * Player lock type (normal or reentrant)
- */
-enum vlc_player_lock_type
-{
-    /**
-     * Normal lock
-     *
-     * If the player is already locked, subsequent calls to vlc_player_Lock()
-     * will deadlock.
-     */
-    VLC_PLAYER_LOCK_NORMAL,
-
-    /**
-     * Reentrant lock
-     *
-     * If the player is already locked, subsequent calls to vlc_player_Lock()
-     * will still succeed. To unlock the player, one call to
-     * vlc_player_Unlock() per vlc_player_Lock() is necessary.
-     */
-    VLC_PLAYER_LOCK_REENTRANT,
-};
-
 /** Player capability: can seek */
 #define VLC_PLAYER_CAP_SEEK (1<<0)
 /** Player capability: can pause */
@@ -389,1208 +374,973 @@ enum vlc_player_lock_type
 #define VLC_PLAYER_TELETEXT_KEY_INDEX ('i' << 16)
 
 /**
- * Callbacks for the owner of the player.
+ * Set the current media
  *
- * These callbacks are needed to control the player flow (via the
- * vlc_playlist_t as a owner for example). It can only be set when creating the
- * player via vlc_player_New().
+ * This function replaces the current and next medias.
  *
- * All callbacks are called with the player locked (cf. vlc_player_Lock()), and
- * from any thread (even the current one).
+ * @note A successful call will always result of
+ * vlc_player_cbs.on_current_media_changed being called. This function is not
+ * blocking. If a media is currently being played, this media will be stopped
+ * and the requested media will be set after.
+ *
+ * @warning This function is either synchronous (if the player state is
+ * STOPPED) or asynchronous. In the later case, vlc_player_GetCurrentMedia()
+ * will return the old media, even after this call, and until the
+ * vlc_player_cbs.on_current_media_changed is called.
+ *
+ * @param player locked player instance
+ * @param media new media to play (will be held by the player)
+ * @return VLC_SUCCESS or a VLC error code
  */
-struct vlc_player_media_provider
-{
-    /**
-     * Called when the player requires a new media
-     *
-     * @note The returned media must be already held with input_item_Hold()
-     *
-     * @param player locked player instance
-     * @param data opaque pointer set from vlc_player_New()
-     * @return the next media to play, held by the callee with input_item_Hold()
-     */
-    input_item_t *(*get_next)(vlc_player_t *player, void *data);
-};
+VLC_API int
+vlc_player_SetCurrentMedia(vlc_player_t *player, input_item_t *media);
 
 /**
- * Player callbacks
- *
- * Can be registered with vlc_player_AddListener().
+ * Get the current played media.
  *
- * All callbacks are called with the player locked (cf. vlc_player_Lock()) and
- * from any threads (and even synchronously from a vlc_player function in some
- * cases). It is safe to call any vlc_player functions from these callbacks
- * except vlc_player_Delete().
+ * @see vlc_player_cbs.on_current_media_changed
  *
- * @warning To avoid deadlocks, users should never call vlc_player functions
- * with an external mutex locked and lock this same mutex from a player
- * callback.
+ * @param player locked player instance
+ * @return a valid media or NULL (if no media is set)
  */
-struct vlc_player_cbs
+VLC_API input_item_t *
+vlc_player_GetCurrentMedia(vlc_player_t *player);
+
+/**
+ * Helper that hold the current media
+ */
+static inline input_item_t *
+vlc_player_HoldCurrentMedia(vlc_player_t *player)
 {
-    /**
-     * Called when the current media has changed
-     *
-     * @note This can be called from the PLAYING state (when the player plays
-     * the next media internally) or from the STOPPED state (from
-     * vlc_player_SetCurrentMedia() or from an internal transition).
-     *
-     * @see vlc_player_SetCurrentMedia()
-     * @see vlc_player_InvalidateNextMedia()
-     *
-     * @param player locked player instance
-     * @param new_media new media currently played or NULL (when there is no
-     * more media to play)
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_current_media_changed)(vlc_player_t *player,
-        input_item_t *new_media, void *data);
+    input_item_t *item = vlc_player_GetCurrentMedia(player);
+    return item ? input_item_Hold(item) : NULL;
+}
 
-    /**
-     * Called when the player state has changed
-     *
-     * @see vlc_player_state
-     *
-     * @param player locked player instance
-     * @param new_state new player state
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_state_changed)(vlc_player_t *player,
-        enum vlc_player_state new_state, void *data);
+/**
+ * Invalidate the next media.
+ *
+ * This function can be used to invalidate the media returned by the
+ * vlc_player_media_provider.get_next callback. This can be used when the next
+ * item from a playlist was changed by the user.
+ *
+ * Calling this function will trigger the
+ * vlc_player_media_provider.get_next callback to be called again.
+ *
+ * @param player locked player instance
+ */
+VLC_API void
+vlc_player_InvalidateNextMedia(vlc_player_t *player);
 
-    /**
-     * Called when a media triggered an error
-     *
-     * Can be called from any states. When it happens the player will stop
-     * itself. It is safe to play an other media or event restart the player
-     * (This will reset the error state).
-     *
-     * @param player locked player instance
-     * @param error player error
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_error_changed)(vlc_player_t *player,
-        enum vlc_player_error error, void *data);
+/**
+ * Start the playback of the current media.
+ *
+ * @param player locked player instance
+ * @return VLC_SUCCESS or a VLC error code
+ */
+VLC_API int
+vlc_player_Start(vlc_player_t *player);
 
-    /**
-     * Called when the player buffering (or cache) has changed
-     *
-     * This event is always called with the 0 and 1 values before a playback
-     * (in case of success).  Values in between depends on the media type.
-     *
-     * @param player locked player instance
-     * @param new_buffering buffering in the range [0:1]
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_buffering_changed)(vlc_player_t *player,
-        float new_buffering, void *data);
+/**
+ * Stop the playback of the current media
+ *
+ * @note This function is asynchronous. Users should wait on
+ * STOPPED state event to know when the stop is finished.
+ *
+ * @param player locked player instance
+ */
+VLC_API void
+vlc_player_Stop(vlc_player_t *player);
 
-    /**
-     * Called when the player rate has changed
-     *
-     * Triggered by vlc_player_ChangeRate(), not sent when the media starts
-     * with the default rate (1.f)
-     *
-     * @param player locked player instance
-     * @param new_rate player
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_rate_changed)(vlc_player_t *player,
-        float new_rate, void *data);
+/**
+ * Pause the playback
+ *
+ * @param player locked player instance
+ */
+VLC_API void
+vlc_player_Pause(vlc_player_t *player);
 
-    /**
-     * Called when the media capabilities has changed
-     *
-     * Always called when the media is opening. Can be called during playback.
-     *
-     * @param player locked player instance
-     * @param old_caps old player capabilities
-     * @param new_caps new player capabilities
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_capabilities_changed)(vlc_player_t *player,
-        int old_caps, int new_caps, void *data);
+/**
+ * Resume the playback from a pause
+ *
+ * @param player locked player instance
+ */
+VLC_API void
+vlc_player_Resume(vlc_player_t *player);
 
-    /**
-     * Called when the player position has changed
-     *
-     * @note A started and playing media doesn't have necessarily a valid time.
-     *
-     * @param player locked player instance
-     * @param new_time a valid time or VLC_TICK_INVALID
-     * @param new_pos a valid position
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_position_changed)(vlc_player_t *player,
-        vlc_tick_t new_time, float new_pos, void *data);
-
-    /**
-     * Called when the media length has changed
-     *
-     * May be called when the media is opening or during playback.
-     *
-     * @note A started and playing media doesn't have necessarily a valid length.
-     *
-     * @param player locked player instance
-     * @param new_length a valid time or VLC_TICK_INVALID
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_length_changed)(vlc_player_t *player,
-        vlc_tick_t new_length, void *data);
-
-    /**
-     * Called when a track is added, removed, or updated
-     *
-     * @note The track is only valid from this callback context. Users should
-     * duplicate this track via vlc_player_track_Dup() if they want to use it
-     * from an other context.
-     *
-     * @param player locked player instance
-     * @param action added, removed or updated
-     * @param track valid track
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_track_list_changed)(vlc_player_t *player,
-        enum vlc_player_list_action action,
-        const struct vlc_player_track *track, void *data);
-
-    /**
-     * Called when a new track is selected and/or unselected
-     *
-     * @note This event can be called with both unselected_id and selected_id
-     * valid. This mean that a new track is replacing the old one.
-     *
-     * @param player locked player instance
-     * @param unselected_id valid track id or NULL (when nothing is unselected)
-     * @param selected_id valid track id or NULL (when nothing is selected)
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_track_selection_changed)(vlc_player_t *player,
-        vlc_es_id_t *unselected_id, vlc_es_id_t *selected_id, void *data);
-
-    /**
-     * Called when a track delay has changed
-     *
-     * @param player locked player instance
-     * @param es_id valid track id
-     * @param delay a valid delay or INT64_MAX if the delay of this track is
-     * canceled
-     */
-    void (*on_track_delay_changed)(vlc_player_t *player,
-        vlc_es_id_t *es_id, vlc_tick_t delay, void *data);
-
-    /**
-     * Called when a new program is added, removed or updated
-     *
-     * @note The program is only valid from this callback context. Users should
-     * duplicate this program via vlc_player_program_Dup() if they want to use
-     * it from an other context.
-     *
-     * @param player locked player instance
-     * @param action added, removed or updated
-     * @param prgm valid program
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_program_list_changed)(vlc_player_t *player,
-        enum vlc_player_list_action action,
-        const struct vlc_player_program *prgm, void *data);
-
-    /**
-     * Called when a new program is selected and/or unselected
-     *
-     * @note This event can be called with both unselected_id and selected_id
-     * valid. This mean that a new program is replacing the old one.
-     *
-     * @param player locked player instance
-     * @param unselected_id valid program id or -1 (when nothing is unselected)
-     * @param selected_id valid program id or -1 (when nothing is selected)
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_program_selection_changed)(vlc_player_t *player,
-        int unselected_id, int selected_id, void *data);
-
-    /**
-     * Called when the media titles has changed
-     *
-     * This event is not called when the opening media doesn't have any titles.
-     * This title list and all its elements are constant. If an element is to
-     * be updated, a new list will be sent from this callback.
-     *
-     * @note Users should hold this list with vlc_player_title_list_Hold() if
-     * they want to use it from an other context.
-     *
-     * @param player locked player instance
-     * @param titles valid title list or NULL
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_titles_changed)(vlc_player_t *player,
-        vlc_player_title_list *titles, void *data);
-
-    /**
-     * Called when a new title is selected
-     *
-     * There are no events when a title is unselected. Titles are automatically
-     * unselected when the title list changes. Titles and indexes are always
-     * valid inside the vlc_player_title_list sent by
-     * vlc_player_cbs.on_titles_changed.
-     *
-     * @param player locked player instance
-     * @param new_title new selected title
-     * @param new_idx index of this title
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_title_selection_changed)(vlc_player_t *player,
-        const struct vlc_player_title *new_title, size_t new_idx, void *data);
-
-    /**
-     * Called when a new chapter is selected
-     *
-     * There are no events when a chapter is unselected. Chapters are
-     * automatically unselected when the title list changes. Titles, chapters
-     * and indexes are always valid inside the vlc_player_title_list sent by
-     * vlc_player_cbs.on_titles_changed.
-     *
-     * @param player locked player instance
-     * @param title selected title
-     * @param title_idx selected title index
-     * @param chapter new selected chapter
-     * @param chapter_idx new selected chapter index
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_chapter_selection_changed)(vlc_player_t *player,
-        const struct vlc_player_title *title, size_t title_idx,
-        const struct vlc_player_chapter *new_chapter, size_t new_chapter_idx,
-        void *data);
-
-    /**
-     * Called when the media has a teletext menu
-     *
-     * @param player locked player instance
-     * @param has_teletext_menu true if the media has a teletext menu
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_teletext_menu_changed)(vlc_player_t *player,
-        bool has_teletext_menu, void *data);
-
-    /**
-     * Called when teletext is enabled or disabled
-     *
-     * @see vlc_player_SetTeletextEnabled()
-     *
-     * @param player locked player instance
-     * @param enabled true if teletext is enabled
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_teletext_enabled_changed)(vlc_player_t *player,
-        bool enabled, void *data);
-
-    /**
-     * Called when the teletext page has changed
-     *
-     * @see vlc_player_SelectTeletextPage()
-     *
-     * @param player locked player instance
-     * @param new_page page in the range ]0;888]
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_teletext_page_changed)(vlc_player_t *player,
-        unsigned new_page, void *data);
-
-    /**
-     * Called when the teletext transparency has changed
-     *
-     * @see vlc_player_SetTeletextTransparency()
-     *
-     * @param player locked player instance
-     * @param enabled true is the teletext overlay is transparent
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_teletext_transparency_changed)(vlc_player_t *player,
-        bool enabled, void *data);
-
-    /**
-     * Called when the player category delay has changed for the current media
-     *
-     * @see vlc_player_SetCategoryDelay()
-     *
-     * @param player locked player instance
-     * @param cat AUDIO_ES or SPU_ES
-     * @param new_delay audio delay
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_category_delay_changed)(vlc_player_t *player,
-         enum es_format_category_e cat, vlc_tick_t new_delay, void *data);
-
-    /**
-     * Called when associated subtitle has changed
-     *
-     * @see vlc_player_SetAssociatedSubsFPS()
-     *
-     * @param player locked player instance
-     * @param sub_fps subtitle fps
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_associated_subs_fps_changed)(vlc_player_t *player,
-        float subs_fps, void *data);
-
-    /**
-     * Called when a new renderer item is set
-     *
-     * @see vlc_player_SetRenderer()
-     *
-     * @param player locked player instance
-     * @param new_item a valid renderer item or NULL (if unset)
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_renderer_changed)(vlc_player_t *player,
-        vlc_renderer_item_t *new_item, void *data);
-
-    /**
-     * Called when the player recording state has changed
-     *
-     * @see vlc_player_SetRecordingEnabled()
-     *
-     * @param player locked player instance
-     * @param recording true if recording is enabled
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_recording_changed)(vlc_player_t *player,
-        bool recording, void *data);
-
-    /**
-     * Called when the media signal has changed
-     *
-     * @param player locked player instance
-     * @param new_quality signal quality
-     * @param new_strength signal strength,
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_signal_changed)(vlc_player_t *player,
-        float quality, float strength, void *data);
-
-    /**
-     * Called when the player has new statisics
-     *
-     * @note The stats structure is only valid from this callback context. It
-     * can be copied in order to use it from an other context.
-     *
-     * @param player locked player instance
-     * @param stats valid stats, only valid from this context
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_statistics_changed)(vlc_player_t *player,
-        const struct input_stats_t *stats, void *data);
-
-    /**
-     * Called when the A to B loop has changed
-     *
-     * @see vlc_player_SetAtoBLoop()
-     *
-     * @param player locked player instance
-     * @param state A, when only A is set, B when both A and B are set, None by
-     * default
-     * @param time valid time or VLC_TICK_INVALID of the current state
-     * @param pos valid pos of the current state
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_atobloop_changed)(vlc_player_t *player,
-        enum vlc_player_abloop new_state, vlc_tick_t time, float pos,
-        void *data);
-
-    /**
-     * Called when media stopped action has changed
-     *
-     * @see vlc_player_SetMediaStoppedAction()
-     *
-     * @param player locked player instance
-     * @param new_action action to execute when a media is stopped
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_media_stopped_action_changed)(vlc_player_t *player,
-        enum vlc_player_media_stopped_action new_action, void *data);
-
-    /**
-     * Called when the media meta has changed
-     *
-     * @param player locked player instance
-     * @param media current media
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_media_meta_changed)(vlc_player_t *player,
-        input_item_t *media, void *data);
-
-    /**
-     * Called when media epg has changed
-     *
-     * @param player locked player instance
-     * @param media current media
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_media_epg_changed)(vlc_player_t *player,
-        input_item_t *media, void *data);
-
-    /**
-     * Called when the media has new subitems
-     *
-     * @param player locked player instance
-     * @param media current media
-     * @param new_subitems node representing all media subitems
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_media_subitems_changed)(vlc_player_t *player,
-        input_item_t *media, input_item_node_t *new_subitems, void *data);
-
-    /**
-     * Called when a vout is started or stopped
-     *
-     * @note In case, several media with only one video track are played
-     * successively, the same vout instance will be started and stopped several
-     * time.
-     *
-     * @param player locked player instance
-     * @param action started or stopped
-     * @param vout vout (can't be NULL)
-     * @param order vout order
-     * @param es_id the ES id associated with this vout
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_vout_changed)(vlc_player_t *player,
-        enum vlc_player_vout_action action, vout_thread_t *vout,
-        enum vlc_vout_order order, vlc_es_id_t *es_id, void *data);
-
-    /**
-     * Called when the player is corked
-     *
-     * The player can be corked when the audio output loose focus or when a
-     * renderer was paused from the outside.
-     *
-     * @note called only if pause on cork was not set to true (by
-     * vlc_player_SetPauseOnCork())
-     * @note a cork_count higher than 0 means the player is corked. In that
-     * case, the user should pause the player and release all external resource
-     * needed by the player. A value higher than 1 mean that the player was
-     * corked more than one time (for different reasons). A value of 0 means
-     * the player is no longer corked. In that case, the user could resume the
-     * player.
-     *
-     * @param player locked player instance
-     * @param cork_count 0 for uncorked, > 0 for corked
-     * @param data opaque pointer set by vlc_player_AddListener()
-     */
-    void (*on_cork_changed)(vlc_player_t *player, unsigned cork_count,
-                            void *data);
-};
+/**
+ * Pause and display the next video frame
+ *
+ * @param player locked player instance
+ */
+VLC_API void
+vlc_player_NextVideoFrame(vlc_player_t *player);
 
 /**
- * Player vout callbacks
- *
- * Can be registered with vlc_player_vout_AddListener().
+ * Get the state of the player
  *
- * These callbacks are *not* called with the player locked. It is safe to lock
- * the player and call any vlc_player functions from these callbacks.
+ * @note Since all players actions are asynchronous, this function won't
+ * reflect the new state immediately. Wait for the
+ * vlc_players_cbs.on_state_changed event to be notified.
  *
- * @note The state changed from the callbacks can be either applied on the
- * player (and all future video outputs), or on a specified video output. The
- * state is applied on the player when the vout argument is NULL.
+ * @see vlc_player_state
+ * @see vlc_player_cbs.on_state_changed
  *
- * @warning To avoid deadlocks, users should never call vout_thread_t functions
- * from these callbacks.
+ * @param player locked player instance
+ * @return the current player state
  */
-struct vlc_player_vout_cbs
-{
-    /**
-     * Called when the player and/or vout fullscreen state has changed
-     *
-     * @see vlc_player_vout_SetFullscreen()
-     *
-     * @param player unlocked player instance
-     * @param vout cf. vlc_player_vout_cbs note
-     * @param enabled true when fullscreen is enabled
-     * @param data opaque pointer set by vlc_player_vout_AddListener()
-     */
-    void (*on_fullscreen_changed)(vlc_player_t *player,
-        vout_thread_t *vout, bool enabled, void *data);
-
-    /**
-     * Called when the player and/or vout wallpaper mode has changed
-     *
-     * @see vlc_player_vout_SetWallpaperModeEnabled()
-     *
-     * @param player unlocked player instance
-     * @param vout cf. vlc_player_vout_cbs note
-     * @param enabled true when wallpaper mode is enabled
-     * @param data opaque pointer set by vlc_player_vout_AddListener()
-     */
-    void (*on_wallpaper_mode_changed)(vlc_player_t *player,
-        vout_thread_t *vout, bool enabled, void *data);
-};
+VLC_API enum vlc_player_state
+vlc_player_GetState(vlc_player_t *player);
 
 /**
- * Player aout callbacks
- *
- * Can be registered with vlc_player_aout_AddListener().
+ * Get the error state of the player
  *
- * These callbacks are *not* called with the player locked. It is safe to lock
- * the player and call any vlc_player functions from these callbacks.
+ * @see vlc_player_cbs.on_capabilities_changed
  *
- * @warning To avoid deadlocks, users should never call audio_output_t
- * functions from these callbacks.
+ * @param player locked player instance
+ * @return the current error state
  */
-struct vlc_player_aout_cbs
-{
-    /**
-     * Called when the volume has changed
-     *
-     * @see vlc_player_aout_SetVolume()
-     *
-     * @param player unlocked player instance
-     * @param new_volume volume in the range [0;2.f]
-     * @param data opaque pointer set by vlc_player_aout_AddListener()
-     */
-    void (*on_volume_changed)(vlc_player_t *player,
-        float new_volume, void *data);
-
-    /**
-     * Called when the mute state has changed
-     *
-     * @see vlc_player_aout_Mute()
-     *
-     * @param player unlocked player instance
-     * @param new_mute true if muted
-     * @param data opaque pointer set by vlc_player_aout_AddListener()
-     */
-    void (*on_mute_changed)(vlc_player_t *player,
-        bool new_muted, void *data);
-
-    /**
-     * Called when the audio device has changed
-     *
-     * @param player unlocked player instance
-     * @param device the device name
-     * @param data opaque pointer set by vlc_player_aout_AddListener()
-     */
-    void (*on_device_changed)(vlc_player_t *player, const char *device,
-                              void *data);
-};
+VLC_API enum vlc_player_error
+vlc_player_GetError(vlc_player_t *player);
 
 /**
- * Duplicate a track
- *
- * This function can be used to pass a track from a callback to an other
- * context. The es_id will be held by the duplicated track.
- *
- * @warning The returned track won't be updated if the original one is modified
- * by the player.
- *
- * @see vlc_player_cbs.on_track_list_changed
- *
- * @return a duplicated track or NULL on allocation error
+ * Helper to get the started state
  */
-VLC_API struct vlc_player_track *
-vlc_player_track_Dup(const struct vlc_player_track *track);
+static inline bool
+vlc_player_IsStarted(vlc_player_t *player)
+{
+    switch (vlc_player_GetState(player))
+    {
+        case VLC_PLAYER_STATE_STARTED:
+        case VLC_PLAYER_STATE_PLAYING:
+        case VLC_PLAYER_STATE_PAUSED:
+            return true;
+        default:
+            return false;
+    }
+}
 
 /**
- * Delete a duplicated track
+ * Helper to get the paused state
  */
-VLC_API void
-vlc_player_track_Delete(struct vlc_player_track *track);
+static inline bool
+vlc_player_IsPaused(vlc_player_t *player)
+{
+    return vlc_player_GetState(player) == VLC_PLAYER_STATE_PAUSED;
+}
 
 /**
- * Duplicate a program
- *
- * This function can be used to pass a program from a callback to an other
- * context.
+ * Helper to toggle the pause state
+ */
+static inline void
+vlc_player_TogglePause(vlc_player_t *player)
+{
+    if (vlc_player_IsStarted(player))
+    {
+        if (vlc_player_IsPaused(player))
+            vlc_player_Resume(player);
+        else
+            vlc_player_Pause(player);
+    }
+}
+
+/**
+ * Get the player capabilities
  *
- * @see vlc_player_cbs.on_program_list_changed
+ * @see vlc_player_cbs.on_capabilities_changed
  *
- * @return a duplicated program or NULL on allocation error
+ * @param player locked player instance
+ * @return the player capabilities, a bitwise mask of @ref VLC_PLAYER_CAP_SEEK,
+ * @ref VLC_PLAYER_CAP_PAUSE, @ref VLC_PLAYER_CAP_CHANGE_RATE, @ref
+ * VLC_PLAYER_CAP_REWIND
  */
-VLC_API struct vlc_player_program *
-vlc_player_program_Dup(const struct vlc_player_program *prgm);
+VLC_API int
+vlc_player_GetCapabilities(vlc_player_t *player);
 
 /**
- * Delete a duplicated program
+ * Helper to get the seek capability
  */
-VLC_API void
-vlc_player_program_Delete(struct vlc_player_program *prgm);
+static inline bool
+vlc_player_CanSeek(vlc_player_t *player)
+{
+    return vlc_player_GetCapabilities(player) & VLC_PLAYER_CAP_SEEK;
+}
 
 /**
- * Hold the title list of the player
- *
- * This function can be used to pass this title list from a callback to an
- * other thread.
- *
- * @see vlc_player_cbs.on_titles_changed
- *
- * @return the same instance
+ * Helper to get the pause capability
  */
-VLC_API vlc_player_title_list *
-vlc_player_title_list_Hold(vlc_player_title_list *titles);
+static inline bool
+vlc_player_CanPause(vlc_player_t *player)
+{
+    return vlc_player_GetCapabilities(player) & VLC_PLAYER_CAP_PAUSE;
+}
 
 /**
- * Release of previously held title list
+ * Helper to get the change-rate capability
  */
-VLC_API void
-vlc_player_title_list_Release(vlc_player_title_list *titles);
+static inline bool
+vlc_player_CanChangeRate(vlc_player_t *player)
+{
+    return vlc_player_GetCapabilities(player) & VLC_PLAYER_CAP_CHANGE_RATE;
+}
 
 /**
- * Get the number of title of a list
+ * Helper to get the rewindable capability
  */
-VLC_API size_t
-vlc_player_title_list_GetCount(vlc_player_title_list *titles);
+static inline bool
+vlc_player_CanRewind(vlc_player_t *player)
+{
+    return vlc_player_GetCapabilities(player) & VLC_PLAYER_CAP_REWIND;
+}
 
 /**
- * Get the title at a given index
+ * Get the rate of the player
  *
- * @param idx index in the range [0; count[
- * @return a valid title (can't be NULL)
+ * @see vlc_player_cbs.on_rate_changed
+ *
+ * @param player locked player instance
+ * @return rate of the player (< 1.f is slower, > 1.f is faster)
  */
-VLC_API const struct vlc_player_title *
-vlc_player_title_list_GetAt(vlc_player_title_list *titles, size_t idx);
+VLC_API float
+vlc_player_GetRate(vlc_player_t *player);
 
 /**
- * Create a new player instance
+ * Change the rate of the player
  *
- * @param parent parent VLC object
- * @param media_provider pointer to a media_provider structure or NULL, the
- * structure must be valid during the lifetime of the player
- * @param media_provider_data opaque data used by provider callbacks
- * @return a pointer to a valid player instance or NULL in case of error
+ * @note The rate is saved across several medias
+ *
+ * @param player locked player instance
+ * @param rate new rate (< 1.f is slower, > 1.f is faster)
  */
-VLC_API vlc_player_t *
-vlc_player_New(vlc_object_t *parent, enum vlc_player_lock_type lock_type,
-               const struct vlc_player_media_provider *media_provider,
-               void *media_provider_data);
+VLC_API void
+vlc_player_ChangeRate(vlc_player_t *player, float rate);
 
 /**
- * Delete a player instance
- *
- * This function stop any playback previously started and wait for their
- * termination.
- *
- * @warning Blocking function if the player state is not STOPPED, don't call it
- * from an UI thread in that case.
+ * Increment the rate of the player (faster)
  *
- * @param player unlocked player instance created by vlc_player_New()
+ * @param player locked player instance
  */
 VLC_API void
-vlc_player_Delete(vlc_player_t *player);
+vlc_player_IncrementRate(vlc_player_t *player);
 
 /**
- * Lock the player.
- *
- * All player functions (except vlc_player_Delete()) need to be called while
- * the player lock is held.
+ * Decrement the rate of the player (Slower)
  *
- * @param player unlocked player instance
+ * @param player locked player instance
  */
 VLC_API void
-vlc_player_Lock(vlc_player_t *player);
+vlc_player_DecrementRate(vlc_player_t *player);
 
 /**
- * Unlock the player
+ * Get the length of the current media
+ *
+ * @note A started and playing media doesn't have necessarily a valid length.
+ *
+ * @see vlc_player_cbs.on_length_changed
  *
  * @param player locked player instance
+ * @return a valid length or VLC_TICK_INVALID (if no media is set,
+ * playback is not yet started or in case of error)
  */
-VLC_API void
-vlc_player_Unlock(vlc_player_t *player);
+VLC_API vlc_tick_t
+vlc_player_GetLength(vlc_player_t *player);
 
 /**
- * Wait on a condition variable
+ * Get the time of the current media
  *
- * This call allow users to use their own condition with the player mutex.
+ * @note A started and playing media doesn't have necessarily a valid time.
+ *
+ * @see vlc_player_cbs.on_position_changed
  *
  * @param player locked player instance
- * @param cond external condition
+ * @return a valid time or VLC_TICK_INVALID (if no media is set, the media
+ * doesn't have any time, if playback is not yet started or in case of error)
  */
-VLC_API void
-vlc_player_CondWait(vlc_player_t *player, vlc_cond_t *cond);
+VLC_API vlc_tick_t
+vlc_player_GetTime(vlc_player_t *player);
 
 /**
- * Add a listener callback
+ * Get the position of the current media
  *
- * @note Every registered callbacks need to be removed by the caller with
- * vlc_player_RemoveListener().
+ * @see vlc_player_cbs.on_position_changed
  *
  * @param player locked player instance
- * @param cbs pointer to a vlc_player_cbs structure, the structure must be
- * valid during the lifetime of the player
- * @param cbs_data opaque pointer used by the callbacks
- * @return a valid listener id, or NULL in case of allocation error
+ * @return a valid position in the range [0.f;1.f] or -1.f (if no media is
+ * set,if playback is not yet started or in case of error)
  */
-VLC_API vlc_player_listener_id *
-vlc_player_AddListener(vlc_player_t *player,
-                       const struct vlc_player_cbs *cbs, void *cbs_data);
+VLC_API float
+vlc_player_GetPosition(vlc_player_t *player);
 
 /**
- * Remove a listener callback
+ * Seek the current media by position
+ *
+ * @note This function can be called before vlc_player_Start() in order to set
+ * a starting position.
  *
  * @param player locked player instance
- * @param listener_id listener id returned by vlc_player_AddListener()
+ * @param position position in the range [0.f;1.f]
+ * @param speed precise of fast
+ * @param whence absolute or relative
  */
 VLC_API void
-vlc_player_RemoveListener(vlc_player_t *player,
-                          vlc_player_listener_id *listener_id);
+vlc_player_SeekByPos(vlc_player_t *player, float position,
+                     enum vlc_player_seek_speed speed,
+                     enum vlc_player_whence whence);
 
 /**
- * Set the current media
- *
- * This function replaces the current and next medias.
+ * Seek the current media by time
  *
- * @note A successful call will always result of
- * vlc_player_cbs.on_current_media_changed being called. This function is not
- * blocking. If a media is currently being played, this media will be stopped
- * and the requested media will be set after.
+ * @note This function can be called before vlc_player_Start() in order to set
+ * a starting position.
  *
- * @warning This function is either synchronous (if the player state is
- * STOPPED) or asynchronous. In the later case, vlc_player_GetCurrentMedia()
- * will return the old media, even after this call, and until the
- * vlc_player_cbs.on_current_media_changed is called.
+ * @warning This function has an effect only if the media has a valid length.
  *
  * @param player locked player instance
- * @param media new media to play (will be held by the player)
- * @return VLC_SUCCESS or a VLC error code
+ * @param time a time in the range [0;length]
+ * @param speed precise of fast
+ * @param whence absolute or relative
  */
-VLC_API int
-vlc_player_SetCurrentMedia(vlc_player_t *player, input_item_t *media);
+VLC_API void
+vlc_player_SeekByTime(vlc_player_t *player, vlc_tick_t time,
+                      enum vlc_player_seek_speed speed,
+                      enum vlc_player_whence whence);
 
 /**
- * Get the current played media.
- *
- * @see vlc_player_cbs.on_current_media_changed
+ * Helper to set the absolute position precisely
+ */
+static inline void
+vlc_player_SetPosition(vlc_player_t *player, float position)
+{
+    vlc_player_SeekByPos(player, position, VLC_PLAYER_SEEK_PRECISE,
+                         VLC_PLAYER_WHENCE_ABSOLUTE);
+}
+
+/**
+ * Helper to set the absolute position fast
+ */
+static inline void
+vlc_player_SetPositionFast(vlc_player_t *player, float position)
+{
+    vlc_player_SeekByPos(player, position, VLC_PLAYER_SEEK_FAST,
+                         VLC_PLAYER_WHENCE_ABSOLUTE);
+}
+
+/**
+ * Helper to jump the position precisely
+ */
+static inline void
+vlc_player_JumpPos(vlc_player_t *player, float jumppos)
+{
+    /* No fask seek for jumps. Indeed, jumps can seek to the current position
+     * if not precise enough or if the jump value is too small. */
+    vlc_player_SeekByPos(player, jumppos, VLC_PLAYER_SEEK_PRECISE,
+                         VLC_PLAYER_WHENCE_RELATIVE);
+}
+
+/**
+ * Helper to set the absolute time precisely
+ */
+static inline void
+vlc_player_SetTime(vlc_player_t *player, vlc_tick_t time)
+{
+    vlc_player_SeekByTime(player, time, VLC_PLAYER_SEEK_PRECISE,
+                          VLC_PLAYER_WHENCE_ABSOLUTE);
+}
+
+/**
+ * Helper to set the absolute time fast
+ */
+static inline void
+vlc_player_SetTimeFast(vlc_player_t *player, vlc_tick_t time)
+{
+    vlc_player_SeekByTime(player, time, VLC_PLAYER_SEEK_FAST,
+                          VLC_PLAYER_WHENCE_ABSOLUTE);
+}
+
+/**
+ * Helper to jump the time precisely
+ */
+static inline void
+vlc_player_JumpTime(vlc_player_t *player, vlc_tick_t jumptime)
+{
+    /* No fask seek for jumps. Indeed, jumps can seek to the current position
+     * if not precise enough or if the jump value is too small. */
+    vlc_player_SeekByTime(player, jumptime, VLC_PLAYER_SEEK_PRECISE,
+                          VLC_PLAYER_WHENCE_RELATIVE);
+}
+
+/**
+ * Display the player position on the vout OSD
  *
  * @param player locked player instance
- * @return a valid media or NULL (if no media is set)
  */
-VLC_API input_item_t *
-vlc_player_GetCurrentMedia(vlc_player_t *player);
+VLC_API void
+vlc_player_DisplayPosition(vlc_player_t *player);
 
 /**
- * Helper that hold the current media
+ * Enable A to B loop of the current media
+ *
+ * This function need to be called 2 times with VLC_PLAYER_ABLOOP_A and
+ * VLC_PLAYER_ABLOOP_B to setup an A to B loop. It current the current
+ * time/position when called. The B time must be higher than the A time.
+ *
+ * @param player locked player instance
+ * @return VLC_SUCCESS or a VLC error code
  */
-static inline input_item_t *
-vlc_player_HoldCurrentMedia(vlc_player_t *player)
-{
-    input_item_t *item = vlc_player_GetCurrentMedia(player);
-    return item ? input_item_Hold(item) : NULL;
-}
+VLC_API int
+vlc_player_SetAtoBLoop(vlc_player_t *player, enum vlc_player_abloop abloop);
 
 /**
- * Invalidate the next media.
+ * Get the A to B loop status
  *
- * This function can be used to invalidate the media returned by the
- * vlc_player_media_provider.get_next callback. This can be used when the next
- * item from a playlist was changed by the user.
+ * @note If the returned status is VLC_PLAYER_ABLOOP_A, then a_time and a_pos
+ * will be valid. If the returned status is VLC_PLAYER_ABLOOP_B, then all
+ * output parameters are valid. If the returned status is
+ * VLC_PLAYER_ABLOOP_NONE, then all output parameters are invalid.
  *
- * Calling this function will trigger the
- * vlc_player_media_provider.get_next callback to be called again.
+ * @see vlc_player_cbs.on_atobloop_changed
  *
  * @param player locked player instance
+ * @param a_time A time or VLC_TICK_INVALID (if the media doesn't have valid
+ * times)
+ * @param a_pos A position
+ * @param b_time B time or VLC_TICK_INVALID (if the media doesn't have valid
+ * times)
+ * @param b_pos B position
+ * @return A to B loop status
  */
-VLC_API void
-vlc_player_InvalidateNextMedia(vlc_player_t *player);
+VLC_API enum vlc_player_abloop
+vlc_player_GetAtoBLoop(vlc_player_t *player, vlc_tick_t *a_time, float *a_pos,
+                       vlc_tick_t *b_time, float *b_pos);
 
 /**
- * Ask to started in a paused state
- *
- * This function can be used before vlc_player_Start()
+ * Navigate (for DVD/Bluray menus or viewpoint)
  *
  * @param player locked player instance
- * @param start_paused true to start in a paused state, false to cancel it
+ * @param nav navigation key
  */
 VLC_API void
-vlc_player_SetStartPaused(vlc_player_t *player, bool start_paused);
+vlc_player_Navigate(vlc_player_t *player, enum vlc_player_nav nav);
 
 /**
- * Setup an action when a media is stopped
- *
- * @param player locked player instance
- * @param action action to do when a media is stopped
- */
+  * Update the viewpoint
+  *
+  * @param player locked player instance
+  * @param viewpoint the viewpoint value
+  * @param whence absolute or relative
+  * @return VLC_SUCCESS or a VLC error code
+  */
 VLC_API void
-vlc_player_SetMediaStoppedAction(vlc_player_t *player,
-                                 enum vlc_player_media_stopped_action action);
+vlc_player_UpdateViewpoint(vlc_player_t *player,
+                           const vlc_viewpoint_t *viewpoint,
+                           enum vlc_player_whence whence);
 
 /**
- * Start the playback of the current media.
+ * Check if the playing is recording
+ *
+ * @see vlc_player_cbs.on_recording_changed
  *
  * @param player locked player instance
- * @return VLC_SUCCESS or a VLC error code
+ * @return true if the player is recording
  */
-VLC_API int
-vlc_player_Start(vlc_player_t *player);
+VLC_API bool
+vlc_player_IsRecording(vlc_player_t *player);
 
 /**
- * Stop the playback of the current media
+ * Enable or disable recording for the current media
  *
- * @note This function is asynchronous. Users should wait on
- * STOPPED state event to know when the stop is finished.
+ * @note A successful call will trigger the vlc_player_cbs.on_recording_changed
+ * event.
  *
  * @param player locked player instance
+ * @param enabled true to enable recording
  */
 VLC_API void
-vlc_player_Stop(vlc_player_t *player);
+vlc_player_SetRecordingEnabled(vlc_player_t *player, bool enabled);
 
 /**
- * Pause the playback
- *
- * @param player locked player instance
+ * Helper to toggle the recording state
  */
-VLC_API void
-vlc_player_Pause(vlc_player_t *player);
+static inline void
+vlc_player_ToggleRecording(vlc_player_t *player)
+{
+    vlc_player_SetRecordingEnabled(player, !vlc_player_IsRecording(player));
+}
 
 /**
- * Resume the playback from a pause
+ * Add an associated (or external) media to the current media
  *
  * @param player locked player instance
+ * @param cat AUDIO_ES or SPU_ES
+ * @param uri absolute uri of the external media
+ * @param select true to select the track of this external media
+ * @param notify true to notify the OSD
+ * @param check_ext true to check subtitles extension
  */
-VLC_API void
-vlc_player_Resume(vlc_player_t *player);
+VLC_API int
+vlc_player_AddAssociatedMedia(vlc_player_t *player,
+                              enum es_format_category_e cat, const char *uri,
+                              bool select, bool notify, bool check_ext);
 
 /**
- * Pause and display the next video frame
+ * Get the signal quality and strength of the current media
  *
  * @param player locked player instance
  */
-VLC_API void
-vlc_player_NextVideoFrame(vlc_player_t *player);
+VLC_API int
+vlc_player_GetSignal(vlc_player_t *player, float *quality, float *strength);
 
 /**
- * Get the state of the player
+ * Get the statistics of the current media
  *
- * @note Since all players actions are asynchronous, this function won't
- * reflect the new state immediately. Wait for the
- * vlc_players_cbs.on_state_changed event to be notified.
+ * @warning The returned pointer becomes invalid when the player is unlocked.
+ * The referenced structure can be safely copied.
  *
- * @see vlc_player_state
- * @see vlc_player_cbs.on_state_changed
+ * @see vlc_player_cbs.on_statistics_changed
  *
  * @param player locked player instance
- * @return the current player state
+ * @return pointer to the player stats structure or NULL
  */
-VLC_API enum vlc_player_state
-vlc_player_GetState(vlc_player_t *player);
+VLC_API const struct input_stats_t *
+vlc_player_GetStatistics(vlc_player_t *player);
 
 /**
- * Get the error state of the player
- *
- * @see vlc_player_cbs.on_capabilities_changed
+ * Get the V4L2 object used to do controls
  *
  * @param player locked player instance
- * @return the current error state
+ * @return the V4L2 object or NULL if not any. This object must be used with
+ * the player lock held.
  */
-VLC_API enum vlc_player_error
-vlc_player_GetError(vlc_player_t *player);
+VLC_API vlc_object_t *
+vlc_player_GetV4l2Object(vlc_player_t *player) VLC_DEPRECATED;
+
+/** @} vlc_player__playback */
 
 /**
- * Helper to get the started state
+ * @defgroup vlc_player__titles Title and chapter control
+ * @{
  */
-static inline bool
-vlc_player_IsStarted(vlc_player_t *player)
-{
-    switch (vlc_player_GetState(player))
-    {
-        case VLC_PLAYER_STATE_STARTED:
-        case VLC_PLAYER_STATE_PLAYING:
-        case VLC_PLAYER_STATE_PAUSED:
-            return true;
-        default:
-            return false;
-    }
-}
 
 /**
- * Helper to get the paused state
+ * Player chapter structure
  */
-static inline bool
-vlc_player_IsPaused(vlc_player_t *player)
+struct vlc_player_chapter
 {
-    return vlc_player_GetState(player) == VLC_PLAYER_STATE_PAUSED;
-}
+    /** Chapter name, always valid */
+    const char *name;
+    /** Position of this chapter */
+    vlc_tick_t time;
+};
+
+/** vlc_player_title.flags: The title is a menu. */
+#define VLC_PLAYER_TITLE_MENU         0x01
+/** vlc_player_title.flags: The title is interactive. */
+#define VLC_PLAYER_TITLE_INTERACTIVE  0x02
+
+/** Player title structure */
+struct vlc_player_title
+{
+    /** Title name, always valid */
+    const char *name;
+    /** Length of the title */
+    vlc_tick_t length;
+    /** Bit flag of @ref VLC_PLAYER_TITLE_MENU and @ref
+     * VLC_PLAYER_TITLE_INTERACTIVE */
+    unsigned flags;
+    /** Number of chapters, can be 0 */
+    size_t chapter_count;
+    /** Array of chapters, can be NULL */
+    const struct vlc_player_chapter *chapters;
+};
 
 /**
- * Helper to toggle the pause state
+ * Opaque structure representing a list of @ref vlc_player_title.
+ *
+ * @see vlc_player_GetTitleList()
+ * @see vlc_player_title_list_GetCount()
+ * @see vlc_player_title_list_GetAt()
  */
-static inline void
-vlc_player_TogglePause(vlc_player_t *player)
-{
-    if (vlc_player_IsStarted(player))
-    {
-        if (vlc_player_IsPaused(player))
-            vlc_player_Resume(player);
-        else
-            vlc_player_Pause(player);
-    }
-}
+typedef struct vlc_player_title_list vlc_player_title_list;
 
 /**
- * Get the player capabilities
+ * Hold the title list of the player
  *
- * @see vlc_player_cbs.on_capabilities_changed
+ * This function can be used to pass this title list from a callback to an
+ * other thread.
  *
- * @param player locked player instance
- * @return the player capabilities, a bitwise mask of @ref VLC_PLAYER_CAP_SEEK,
- * @ref VLC_PLAYER_CAP_PAUSE, @ref VLC_PLAYER_CAP_CHANGE_RATE, @ref
- * VLC_PLAYER_CAP_REWIND
+ * @see vlc_player_cbs.on_titles_changed
+ *
+ * @return the same instance
  */
-VLC_API int
-vlc_player_GetCapabilities(vlc_player_t *player);
+VLC_API vlc_player_title_list *
+vlc_player_title_list_Hold(vlc_player_title_list *titles);
 
 /**
- * Helper to get the seek capability
+ * Release of previously held title list
  */
-static inline bool
-vlc_player_CanSeek(vlc_player_t *player)
-{
-    return vlc_player_GetCapabilities(player) & VLC_PLAYER_CAP_SEEK;
-}
+VLC_API void
+vlc_player_title_list_Release(vlc_player_title_list *titles);
 
 /**
- * Helper to get the pause capability
+ * Get the number of title of a list
+ */
+VLC_API size_t
+vlc_player_title_list_GetCount(vlc_player_title_list *titles);
+
+/**
+ * Get the title at a given index
+ *
+ * @param idx index in the range [0; count[
+ * @return a valid title (can't be NULL)
+ */
+VLC_API const struct vlc_player_title *
+vlc_player_title_list_GetAt(vlc_player_title_list *titles, size_t idx);
+
+/**
+ * Get the title list of the current media
+ *
+ * @see vlc_player_cbs.on_titles_changed
+ *
+ * @param player locked player instance
  */
-static inline bool
-vlc_player_CanPause(vlc_player_t *player)
-{
-    return vlc_player_GetCapabilities(player) & VLC_PLAYER_CAP_PAUSE;
-}
+VLC_API vlc_player_title_list *
+vlc_player_GetTitleList(vlc_player_t *player);
 
 /**
- * Helper to get the change-rate capability
+ * Get the selected title index for the current media
+ *
+ * @see vlc_player_cbs.on_title_selection_changed
+ *
+ * @param player locked player instance
  */
-static inline bool
-vlc_player_CanChangeRate(vlc_player_t *player)
-{
-    return vlc_player_GetCapabilities(player) & VLC_PLAYER_CAP_CHANGE_RATE;
-}
+VLC_API ssize_t
+vlc_player_GetSelectedTitleIdx(vlc_player_t *player);
 
 /**
- * Helper to get the rewindable capability
+ * Helper to get the current selected title
  */
-static inline bool
-vlc_player_CanRewind(vlc_player_t *player)
+static inline const struct vlc_player_title *
+vlc_player_GetSelectedTitle(vlc_player_t *player)
 {
-    return vlc_player_GetCapabilities(player) & VLC_PLAYER_CAP_REWIND;
+    vlc_player_title_list *titles = vlc_player_GetTitleList(player);
+    if (!titles)
+        return NULL;
+    ssize_t selected_idx = vlc_player_GetSelectedTitleIdx(player);
+    if (selected_idx < 0)
+        return NULL;
+    return vlc_player_title_list_GetAt(titles, selected_idx);
 }
 
 /**
- * Get the rate of the player
+ * Select a title index for the current media
  *
- * @see vlc_player_cbs.on_rate_changed
+ * @note A successful call will trigger the
+ * vlc_player_cbs.on_title_selection_changed event.
+ *
+ * @see vlc_player_title_list_GetAt()
+ * @see vlc_player_title_list_GetCount()
  *
  * @param player locked player instance
- * @return rate of the player (< 1.f is slower, > 1.f is faster)
+ * @param index valid index in the range [0;count[
  */
-VLC_API float
-vlc_player_GetRate(vlc_player_t *player);
+VLC_API void
+vlc_player_SelectTitleIdx(vlc_player_t *player, size_t index);
 
 /**
- * Change the rate of the player
+ * Select a title for the current media
  *
- * @note The rate is saved across several medias
+ * @note A successful call will trigger the
+ * vlc_player_cbs.on_title_selection_changed event.
+ *
+ * @see vlc_player_title_list_GetAt()
+ * @see vlc_player_title_list_GetCount()
  *
  * @param player locked player instance
- * @param rate new rate (< 1.f is slower, > 1.f is faster)
+ * @param title a valid title coming from the vlc_player_title_list
  */
 VLC_API void
-vlc_player_ChangeRate(vlc_player_t *player, float rate);
+vlc_player_SelectTitle(vlc_player_t *player,
+                       const struct vlc_player_title *title);
 
 /**
- * Increment the rate of the player (faster)
+ * Select a chapter for the current media
+ *
+ * @note A successful call will trigger the
+ * vlc_player_cbs.on_chapter_selection_changed event.
  *
  * @param player locked player instance
+ * @param title the selected title
+ * @param chapter_idx index from vlc_player_title.chapters
  */
 VLC_API void
-vlc_player_IncrementRate(vlc_player_t *player);
+vlc_player_SelectChapter(vlc_player_t *player,
+                         const struct vlc_player_title *title,
+                         size_t chapter_idx);
 
 /**
- * Decrement the rate of the player (Slower)
+ * Select the next title for the current media
  *
- * @param player locked player instance
+ * @see vlc_player_SelectTitleIdx()
  */
 VLC_API void
-vlc_player_DecrementRate(vlc_player_t *player);
+vlc_player_SelectNextTitle(vlc_player_t *player);
 
 /**
- * Get the length of the current media
+ * Select the previous title for the current media
  *
- * @note A started and playing media doesn't have necessarily a valid length.
+ * @see vlc_player_SelectTitleIdx()
+ */
+VLC_API void
+vlc_player_SelectPrevTitle(vlc_player_t *player);
+
+/**
+ * Get the selected chapter index for the current media
  *
- * @see vlc_player_cbs.on_length_changed
+ * @see vlc_player_cbs.on_chapter_selection_changed
  *
  * @param player locked player instance
- * @return a valid length or VLC_TICK_INVALID (if no media is set,
- * playback is not yet started or in case of error)
  */
-VLC_API vlc_tick_t
-vlc_player_GetLength(vlc_player_t *player);
+VLC_API ssize_t
+vlc_player_GetSelectedChapterIdx(vlc_player_t *player);
 
 /**
- * Get the time of the current media
+ * Helper to get the current selected chapter
+ */
+static inline const struct vlc_player_chapter *
+vlc_player_GetSelectedChapter(vlc_player_t *player)
+{
+    const struct vlc_player_title *title = vlc_player_GetSelectedTitle(player);
+    if (!title || !title->chapter_count)
+        return NULL;
+    ssize_t chapter_idx = vlc_player_GetSelectedChapterIdx(player);
+    return chapter_idx >= 0 ? &title->chapters[chapter_idx] : NULL;
+}
+
+/**
+ * Select a chapter index for the current media
  *
- * @note A started and playing media doesn't have necessarily a valid time.
+ * @note A successful call will trigger the
+ * vlc_player_cbs.on_chaper_selection_changed event.
  *
- * @see vlc_player_cbs.on_position_changed
+ * @see vlc_player_title.chapters
  *
  * @param player locked player instance
- * @return a valid time or VLC_TICK_INVALID (if no media is set, the media
- * doesn't have any time, if playback is not yet started or in case of error)
+ * @param index valid index in the range [0;vlc_player_title.chapter_count[
  */
-VLC_API vlc_tick_t
-vlc_player_GetTime(vlc_player_t *player);
+VLC_API void
+vlc_player_SelectChapterIdx(vlc_player_t *player, size_t index);
 
 /**
- * Get the position of the current media
+ * Select the next chapter for the current media
  *
- * @see vlc_player_cbs.on_position_changed
+ * @see vlc_player_SelectChapterIdx()
+ */
+VLC_API void
+vlc_player_SelectNextChapter(vlc_player_t *player);
+
+/**
+ * Select the previous chapter for the current media
  *
- * @param player locked player instance
- * @return a valid position in the range [0.f;1.f] or -1.f (if no media is
- * set,if playback is not yet started or in case of error)
+ * @see vlc_player_SelectChapterIdx()
  */
-VLC_API float
-vlc_player_GetPosition(vlc_player_t *player);
+VLC_API void
+vlc_player_SelectPrevChapter(vlc_player_t *player);
+
+/** @} vlc_player__titles */
 
 /**
- * Seek the current media by position
+ * @defgroup vlc_player__programs Program control
+ * @{
+ */
+
+/**
+ * Player program structure.
+ */
+struct vlc_player_program
+{
+    /** Id used for vlc_player_SelectProgram() */
+    int group_id;
+    /** Program name, always valid */
+    const char *name;
+    /** True if the program is selected */
+    bool selected;
+    /** True if the program is scrambled */
+    bool scrambled;
+};
+
+/**
+ * Duplicate a program
  *
- * @note This function can be called before vlc_player_Start() in order to set
- * a starting position.
+ * This function can be used to pass a program from a callback to an other
+ * context.
  *
- * @param player locked player instance
- * @param position position in the range [0.f;1.f]
- * @param speed precise of fast
- * @param whence absolute or relative
+ * @see vlc_player_cbs.on_program_list_changed
+ *
+ * @return a duplicated program or NULL on allocation error
+ */
+VLC_API struct vlc_player_program *
+vlc_player_program_Dup(const struct vlc_player_program *prgm);
+
+/**
+ * Delete a duplicated program
  */
 VLC_API void
-vlc_player_SeekByPos(vlc_player_t *player, float position,
-                     enum vlc_player_seek_speed speed,
-                     enum vlc_player_whence whence);
+vlc_player_program_Delete(struct vlc_player_program *prgm);
 
 /**
- * Seek the current media by time
- *
- * @note This function can be called before vlc_player_Start() in order to set
- * a starting position.
+ * Get the number of programs
  *
- * @warning This function has an effect only if the media has a valid length.
+ * @warning The returned size becomes invalid when the player is unlocked.
  *
  * @param player locked player instance
- * @param time a time in the range [0;length]
- * @param speed precise of fast
- * @param whence absolute or relative
+ * @return number of programs, or 0 (in case of error, or if the media is not
+ * started)
  */
-VLC_API void
-vlc_player_SeekByTime(vlc_player_t *player, vlc_tick_t time,
-                      enum vlc_player_seek_speed speed,
-                      enum vlc_player_whence whence);
+VLC_API size_t
+vlc_player_GetProgramCount(vlc_player_t *player);
 
 /**
- * Helper to set the absolute position precisely
+ * Get the program at a specific index
+ *
+ * @warning The behaviour is undefined if the index is not valid.
+ *
+ * @warning The returned pointer becomes invalid when the player is unlocked.
+ * The referenced structure can be safely copied with vlc_player_program_Dup().
+ *
+ * @param player locked player instance
+ * @param index valid index in the range [0; count[
+ * @return a valid program (can't be NULL if vlc_player_GetProgramCount()
+ * returned a valid count)
  */
-static inline void
-vlc_player_SetPosition(vlc_player_t *player, float position)
-{
-    vlc_player_SeekByPos(player, position, VLC_PLAYER_SEEK_PRECISE,
-                         VLC_PLAYER_WHENCE_ABSOLUTE);
-}
+VLC_API const struct vlc_player_program *
+vlc_player_GetProgramAt(vlc_player_t *player, size_t index);
 
 /**
- * Helper to set the absolute position fast
+ * Get a program from an ES group identifier
+ *
+ * @param player locked player instance
+ * @param group_id a program ID (retrieved from
+ * vlc_player_cbs.on_program_list_changed or vlc_player_GetProgramAt())
+ * @return a valid program or NULL (if the program was terminated by the
+ * playback thread)
  */
-static inline void
-vlc_player_SetPositionFast(vlc_player_t *player, float position)
-{
-    vlc_player_SeekByPos(player, position, VLC_PLAYER_SEEK_FAST,
-                         VLC_PLAYER_WHENCE_ABSOLUTE);
-}
+VLC_API const struct vlc_player_program *
+vlc_player_GetProgram(vlc_player_t *player, int group_id);
 
 /**
- * Helper to jump the position precisely
+ * Select a program from an ES group identifier
+ *
+ * @param player locked player instance
+ * @param group_id a program ID (retrieved from
+ * vlc_player_cbs.on_program_list_changed or vlc_player_GetProgramAt())
  */
-static inline void
-vlc_player_JumpPos(vlc_player_t *player, float jumppos)
-{
-    /* No fask seek for jumps. Indeed, jumps can seek to the current position
-     * if not precise enough or if the jump value is too small. */
-    vlc_player_SeekByPos(player, jumppos, VLC_PLAYER_SEEK_PRECISE,
-                         VLC_PLAYER_WHENCE_RELATIVE);
-}
+VLC_API void
+vlc_player_SelectProgram(vlc_player_t *player, int group_id);
 
 /**
- * Helper to set the absolute time precisely
+ * Select the next program
+ *
+ * @param player locked player instance
  */
-static inline void
-vlc_player_SetTime(vlc_player_t *player, vlc_tick_t time)
-{
-    vlc_player_SeekByTime(player, time, VLC_PLAYER_SEEK_PRECISE,
-                          VLC_PLAYER_WHENCE_ABSOLUTE);
-}
+VLC_API void
+vlc_player_SelectNextProgram(vlc_player_t *player);
 
 /**
- * Helper to set the absolute time fast
+ * Select the previous program
+ *
+ * @param player locked player instance
  */
-static inline void
-vlc_player_SetTimeFast(vlc_player_t *player, vlc_tick_t time)
-{
-    vlc_player_SeekByTime(player, time, VLC_PLAYER_SEEK_FAST,
-                          VLC_PLAYER_WHENCE_ABSOLUTE);
-}
+VLC_API void
+vlc_player_SelectPrevProgram(vlc_player_t *player);
 
 /**
- * Helper to jump the time precisely
+ * Helper to get the current selected program
  */
-static inline void
-vlc_player_JumpTime(vlc_player_t *player, vlc_tick_t jumptime)
+static inline const struct vlc_player_program *
+vlc_player_GetSelectedProgram(vlc_player_t *player)
 {
-    /* No fask seek for jumps. Indeed, jumps can seek to the current position
-     * if not precise enough or if the jump value is too small. */
-    vlc_player_SeekByTime(player, jumptime, VLC_PLAYER_SEEK_PRECISE,
-                          VLC_PLAYER_WHENCE_RELATIVE);
+    size_t count = vlc_player_GetProgramCount(player);
+    for (size_t i = 0; i < count; ++i)
+    {
+        const struct vlc_player_program *program =
+            vlc_player_GetProgramAt(player, i);
+        assert(program);
+        if (program->selected)
+            return program;
+    }
+    return NULL;
 }
 
+/** @} vlc_player__programs */
+
 /**
- * Display the player position on the vout OSD
+ * @defgroup vlc_player__tracks Tracks control
+ * @{
+ */
+
+/**
+ * Player selection policy
  *
- * @param player locked player instance
+ * @see vlc_player_SelectEsId()
  */
-VLC_API void
-vlc_player_DisplayPosition(vlc_player_t *player);
+enum vlc_player_select_policy
+{
+    /**
+     * Only one track per category is selected. Selecting a track with this
+     * policy will disable all other tracks for the same category.
+     */
+    VLC_PLAYER_SELECT_EXCLUSIVE,
+    /**
+     * Select multiple tracks for one category.
+     *
+     * Only one audio track can be selected at a time.
+     * Two subtitle tracks can be selected simultaneously.
+     * Multiple video tracks can be selected simultaneously.
+     */
+    VLC_PLAYER_SELECT_SIMULTANEOUS,
+};
 
 /**
- * Enable A to B loop of the current media
+ * Player track structure.
  *
- * This function need to be called 2 times with VLC_PLAYER_ABLOOP_A and
- * VLC_PLAYER_ABLOOP_B to setup an A to B loop. It current the current
- * time/position when called. The B time must be higher than the A time.
+ * A track is a representation of an ES identifier at a given time. Once the
+ * player is unlocked, all content except the es_id pointer can be updated.
  *
- * @param player locked player instance
- * @return VLC_SUCCESS or a VLC error code
+ * @see vlc_player_cbs.on_track_list_changed
+ * @see vlc_player_GetTrack
  */
-VLC_API int
-vlc_player_SetAtoBLoop(vlc_player_t *player, enum vlc_player_abloop abloop);
+struct vlc_player_track
+{
+    /** Id used for any player actions, like vlc_player_SelectEsId() */
+    vlc_es_id_t *es_id;
+    /** Track name, always valid */
+    const char *name;
+    /** Es format */
+    es_format_t fmt;
+    /** True if the track is selected */
+    bool selected;
+};
 
 /**
- * Get the A to B loop status
+ * Duplicate a track
  *
- * @note If the returned status is VLC_PLAYER_ABLOOP_A, then a_time and a_pos
- * will be valid. If the returned status is VLC_PLAYER_ABLOOP_B, then all
- * output parameters are valid. If the returned status is
- * VLC_PLAYER_ABLOOP_NONE, then all output parameters are invalid.
+ * This function can be used to pass a track from a callback to an other
+ * context. The es_id will be held by the duplicated track.
  *
- * @see vlc_player_cbs.on_atobloop_changed
+ * @warning The returned track won't be updated if the original one is modified
+ * by the player.
  *
- * @param player locked player instance
- * @param a_time A time or VLC_TICK_INVALID (if the media doesn't have valid
- * times)
- * @param a_pos A position
- * @param b_time B time or VLC_TICK_INVALID (if the media doesn't have valid
- * times)
- * @param b_pos B position
- * @return A to B loop status
+ * @see vlc_player_cbs.on_track_list_changed
+ *
+ * @return a duplicated track or NULL on allocation error
  */
-VLC_API enum vlc_player_abloop
-vlc_player_GetAtoBLoop(vlc_player_t *player, vlc_tick_t *a_time, float *a_pos,
-                       vlc_tick_t *b_time, float *b_pos);
+VLC_API struct vlc_player_track *
+vlc_player_track_Dup(const struct vlc_player_track *track);
+
+/**
+ * Delete a duplicated track
+ */
+VLC_API void
+vlc_player_track_Delete(struct vlc_player_track *track);
 
 /**
  * Get the number of tracks for an ES category
@@ -2026,125 +1776,206 @@ vlc_player_SetAudioEnabled(vlc_player_t *player, bool enabled)
 }
 
 /**
- * Helper to check if audio tracks are enabled
+ * Helper to check if audio tracks are enabled
+ */
+static inline bool
+vlc_player_IsAudioEnabled(vlc_player_t *player)
+{
+    return vlc_player_IsTrackCategoryEnabled(player, AUDIO_ES);
+}
+
+/**
+ * Helper to enable or disable subtitle tracks
+ */
+static inline void
+vlc_player_SetSubtitleEnabled(vlc_player_t *player, bool enabled)
+{
+    vlc_player_SetTrackCategoryEnabled(player, SPU_ES, enabled);
+}
+
+/**
+ * Helper to check if subtitle tracks are enabled
+ */
+static inline bool
+vlc_player_IsSubtitleEnabled(vlc_player_t *player)
+{
+    return vlc_player_IsTrackCategoryEnabled(player, SPU_ES);
+}
+
+/**
+ * Helper to toggle subtitles
+ */
+static inline void
+vlc_player_ToggleSubtitle(vlc_player_t *player)
+{
+    bool enabled = !vlc_player_IsSubtitleEnabled(player);
+    return vlc_player_SetSubtitleEnabled(player, enabled);
+}
+
+/**
+ * Set the subtitle text scaling factor
+ *
+ * @note This function have an effect only if the subtitle track is a text type.
+ *
+ * @param player locked player instance
+ * @param scale factor in the range [10;500] (default: 100)
+ */
+VLC_API void
+vlc_player_SetSubtitleTextScale(vlc_player_t *player, unsigned scale);
+
+/**
+ * Get the subtitle text scaling factor
+ *
+ * @param player locked player instance
+ * @return scale factor
+ */
+VLC_API unsigned
+vlc_player_GetSubtitleTextScale(vlc_player_t *player);
+
+/** @} vlc_player__tracks */
+
+/**
+ * @defgroup vlc_player__tracks_sync Tracks synchronisation (delay)
+ * @{
+ */
+
+/**
+ * Get the delay of an ES category for the current media
+ *
+ * @see vlc_player_cbs.on_category_delay_changed
+ *
+ * @param player locked player instance
+ * @param cat AUDIO_ES or SPU_ES (VIDEO_ES not supported yet)
+ * @return a valid delay or 0
+ */
+VLC_API vlc_tick_t
+vlc_player_GetCategoryDelay(vlc_player_t *player, enum es_format_category_e cat);
+
+/**
+ * Set the delay of one category for the current media
+ *
+ * @note A successful call will trigger the
+ * vlc_player_cbs.on_category_delay_changed event.
+ *
+ * @warning This has no effect on tracks where the delay was set by
+ * vlc_player_SetEsIdDelay()
+ *
+ * @param player locked player instance
+ * @param cat AUDIO_ES or SPU_ES (VIDEO_ES not supported yet)
+ * @param delay a valid time
+ * @param whence absolute or relative
+ * @return VLC_SUCCESS or VLC_EGENERIC if the category is not handled
+ */
+VLC_API int
+vlc_player_SetCategoryDelay(vlc_player_t *player, enum es_format_category_e cat,
+                            vlc_tick_t delay, enum vlc_player_whence whence);
+
+/**
+ * Get the delay of a track
+ *
+ * @see vlc_player_cbs.on_track_delay_changed
+ *
+ * @param player locked player instance
+ * @param id an ES ID (retrieved from vlc_player_cbs.on_track_list_changed or
+ * vlc_player_GetTrackAt())
+ * @return a valid delay or INT64_MAX is no delay is set for this track
+ */
+VLC_API vlc_tick_t
+vlc_player_GetEsIdDelay(vlc_player_t *player, vlc_es_id_t *es_id);
+
+/**
+ * Set the delay of one track
+ *
+ * @note A successful call will trigger the
+ * vlc_player_cbs.on_track_delay_changed event.
+ *
+ * @warning Setting the delay of one specific track will override previous and
+ * future changes of delay made by vlc_player_SetCategoryDelay()
+ *
+ * @param player locked player instance
+ * @param id an ES ID (retrieved from vlc_player_cbs.on_track_list_changed or
+ * vlc_player_GetTrackAt())
+ * @param delay a valid time or INT64_MAX to use default category delay
+ * @param whence absolute or relative
+ * @return VLC_SUCCESS or VLC_EGENERIC if the category of the es_id is not
+ * handled (VIDEO_ES not supported yet)
+ */
+VLC_API int
+vlc_player_SetEsIdDelay(vlc_player_t *player, vlc_es_id_t *es_id,
+                        vlc_tick_t delay, enum vlc_player_whence whence);
+
+/**
+ * Helper to get the audio delay
  */
-static inline bool
-vlc_player_IsAudioEnabled(vlc_player_t *player)
+static inline vlc_tick_t
+vlc_player_GetAudioDelay(vlc_player_t *player)
 {
-    return vlc_player_IsTrackCategoryEnabled(player, AUDIO_ES);
+    return vlc_player_GetCategoryDelay(player, AUDIO_ES);
 }
 
 /**
- * Helper to enable or disable subtitle tracks
+ * Helper to set the audio delay
  */
 static inline void
-vlc_player_SetSubtitleEnabled(vlc_player_t *player, bool enabled)
+vlc_player_SetAudioDelay(vlc_player_t *player, vlc_tick_t delay,
+                         enum vlc_player_whence whence)
+
 {
-    vlc_player_SetTrackCategoryEnabled(player, SPU_ES, enabled);
+    vlc_player_SetCategoryDelay(player, AUDIO_ES, delay, whence);
 }
 
 /**
- * Helper to check if subtitle tracks are enabled
+ * Helper to get the subtitle delay
  */
-static inline bool
-vlc_player_IsSubtitleEnabled(vlc_player_t *player)
+static inline vlc_tick_t
+vlc_player_GetSubtitleDelay(vlc_player_t *player)
 {
-    return vlc_player_IsTrackCategoryEnabled(player, SPU_ES);
+    return vlc_player_GetCategoryDelay(player, SPU_ES);
 }
 
 /**
- * Helper to toggle subtitles
+ * Helper to set the subtitle delay
  */
 static inline void
-vlc_player_ToggleSubtitle(vlc_player_t *player)
+vlc_player_SetSubtitleDelay(vlc_player_t *player, vlc_tick_t delay,
+                            enum vlc_player_whence whence)
 {
-    bool enabled = !vlc_player_IsSubtitleEnabled(player);
-    return vlc_player_SetSubtitleEnabled(player, enabled);
+    vlc_player_SetCategoryDelay(player, SPU_ES, delay, whence);
 }
 
 /**
- * Get the number of programs
- *
- * @warning The returned size becomes invalid when the player is unlocked.
- *
- * @param player locked player instance
- * @return number of programs, or 0 (in case of error, or if the media is not
- * started)
- */
-VLC_API size_t
-vlc_player_GetProgramCount(vlc_player_t *player);
-
-/**
- * Get the program at a specific index
- *
- * @warning The behaviour is undefined if the index is not valid.
+ * Set the associated subtitle FPS
  *
- * @warning The returned pointer becomes invalid when the player is unlocked.
- * The referenced structure can be safely copied with vlc_player_program_Dup().
+ * In order to correct the rate of the associated media according to this FPS
+ * and the media video FPS.
  *
- * @param player locked player instance
- * @param index valid index in the range [0; count[
- * @return a valid program (can't be NULL if vlc_player_GetProgramCount()
- * returned a valid count)
- */
-VLC_API const struct vlc_player_program *
-vlc_player_GetProgramAt(vlc_player_t *player, size_t index);
-
-/**
- * Get a program from an ES group identifier
+ * @note A successful call will trigger the
+ * vlc_player_cbs.on_associated_subs_fps_changed event.
  *
- * @param player locked player instance
- * @param group_id a program ID (retrieved from
- * vlc_player_cbs.on_program_list_changed or vlc_player_GetProgramAt())
- * @return a valid program or NULL (if the program was terminated by the
- * playback thread)
- */
-VLC_API const struct vlc_player_program *
-vlc_player_GetProgram(vlc_player_t *player, int group_id);
-
-/**
- * Select a program from an ES group identifier
+ * @warning this function will change the rate of all external subtitle files
+ * associated with the current media.
  *
  * @param player locked player instance
- * @param group_id a program ID (retrieved from
- * vlc_player_cbs.on_program_list_changed or vlc_player_GetProgramAt())
+ * @param fps FPS of the subtitle file
  */
 VLC_API void
-vlc_player_SelectProgram(vlc_player_t *player, int group_id);
+vlc_player_SetAssociatedSubsFPS(vlc_player_t *player, float fps);
 
 /**
- * Select the next program
+ * Get the associated subtitle FPS
  *
  * @param player locked player instance
+ * @return fps
  */
-VLC_API void
-vlc_player_SelectNextProgram(vlc_player_t *player);
+VLC_API float
+vlc_player_GetAssociatedSubsFPS(vlc_player_t *player);
 
-/**
- * Select the previous program
- *
- * @param player locked player instance
- */
-VLC_API void
-vlc_player_SelectPrevProgram(vlc_player_t *player);
+/** @} vlc_player__tracks_sync */
 
 /**
- * Helper to get the current selected program
+ * @defgroup vlc_player__teletext Teletext control
+ * @{
  */
-static inline const struct vlc_player_program *
-vlc_player_GetSelectedProgram(vlc_player_t *player)
-{
-    size_t count = vlc_player_GetProgramCount(player);
-    for (size_t i = 0; i < count; ++i)
-    {
-        const struct vlc_player_program *program =
-            vlc_player_GetProgramAt(player, i);
-        assert(program);
-        if (program->selected)
-            return program;
-    }
-    return NULL;
-}
 
 /**
  * Check if the media has a teletext menu
@@ -2226,757 +2057,1004 @@ vlc_player_SetTeletextTransparency(vlc_player_t *player, bool enabled);
 /**
  * Check if teletext is transparent
  *
- * @param player locked player instance
+ * @param player locked player instance
+ */
+VLC_API bool
+vlc_player_IsTeletextTransparent(vlc_player_t *player);
+
+/** @} vlc_player__teletext */
+
+/**
+ * @defgroup vlc_player__renderer External renderer control
+ * @{
+ */
+
+/**
+ * Set the renderer
+ *
+ * Valid for the current media and all future ones.
+ *
+ * @note A successful call will trigger the vlc_player_cbs.on_renderer_changed
+ * event.
+ *
+ * @param player locked player instance
+ * @param renderer a valid renderer item or NULL (to disable it), the item will
+ * be held by the player
+ */
+VLC_API void
+vlc_player_SetRenderer(vlc_player_t *player, vlc_renderer_item_t *renderer);
+
+/**
+ * Get the renderer
+ *
+ * @see vlc_player_cbs.on_renderer_changed
+ *
+ * @param player locked player instance
+ * @return the renderer item set by vlc_player_SetRenderer()
+ */
+VLC_API vlc_renderer_item_t *
+vlc_player_GetRenderer(vlc_player_t *player);
+
+/** @} vlc_player__renderer */
+
+/**
+ * @defgroup vlc_player__aout Audio output control
+ * @{
+ */
+
+/**
+ * Player aout listener opaque structure.
+ *
+ * This opaque structure is returned by vlc_player_aout_AddListener() and can
+ * be used to remove the listener via vlc_player_aout_RemoveListener().
+ */
+typedef struct vlc_player_aout_listener_id vlc_player_aout_listener_id;
+
+/**
+ * Player aout callbacks
+ *
+ * Can be registered with vlc_player_aout_AddListener().
+ *
+ * These callbacks are *not* called with the player locked. It is safe to lock
+ * the player and call any vlc_player functions from these callbacks.
+ *
+ * @warning To avoid deadlocks, users should never call audio_output_t
+ * functions from these callbacks.
+ */
+struct vlc_player_aout_cbs
+{
+    /**
+     * Called when the volume has changed
+     *
+     * @see vlc_player_aout_SetVolume()
+     *
+     * @param player unlocked player instance
+     * @param new_volume volume in the range [0;2.f]
+     * @param data opaque pointer set by vlc_player_aout_AddListener()
+     */
+    void (*on_volume_changed)(vlc_player_t *player,
+        float new_volume, void *data);
+
+    /**
+     * Called when the mute state has changed
+     *
+     * @see vlc_player_aout_Mute()
+     *
+     * @param player unlocked player instance
+     * @param new_mute true if muted
+     * @param data opaque pointer set by vlc_player_aout_AddListener()
+     */
+    void (*on_mute_changed)(vlc_player_t *player,
+        bool new_muted, void *data);
+
+    /**
+     * Called when the audio device has changed
+     *
+     * @param player unlocked player instance
+     * @param device the device name
+     * @param data opaque pointer set by vlc_player_aout_AddListener()
+     */
+    void (*on_device_changed)(vlc_player_t *player, const char *device,
+                              void *data);
+};
+
+/**
+ * Get the audio output
+ *
+ * @warning The returned pointer must be released with aout_Release().
+ *
+ * @param player player instance
+ * @return a valid audio_output_t * or NULL (if there is no aouts)
+ */
+VLC_API audio_output_t *
+vlc_player_aout_Hold(vlc_player_t *player);
+
+/**
+ * Add a listener callback for audio output events
+ *
+ * @note The player instance doesn't need to be locked for vlc_player_aout_*()
+ * functions.
+ * @note Every registered callbacks need to be removed by the caller with
+ * vlc_player_aout_RemoveListener().
+ *
+ * @param player player instance
+ * @param cbs pointer to a vlc_player_aout_cbs structure, the structure must be
+ * valid during the lifetime of the player
+ * @param cbs_data opaque pointer used by the callbacks
+ * @return a valid listener id, or NULL in case of allocation error
+ */
+VLC_API vlc_player_aout_listener_id *
+vlc_player_aout_AddListener(vlc_player_t *player,
+                            const struct vlc_player_aout_cbs *cbs,
+                            void *cbs_data);
+
+/**
+ * Remove a aout listener callback
+ *
+ * @param player player instance
+ * @param listener_id listener id returned by vlc_player_aout_AddListener()
+ */
+VLC_API void
+vlc_player_aout_RemoveListener(vlc_player_t *player,
+                               vlc_player_aout_listener_id *listener_id);
+
+/**
+ * Get the audio volume
+ *
+ * @note The player instance doesn't need to be locked for vlc_player_aout_*()
+ * functions.
+ *
+ * @see vlc_player_aout_cbs.on_volume_changed
+ *
+ * @param player player instance
+ * @return volume in the range [0;2.f] or -1.f if there is no audio outputs
+ * (independent of mute)
  */
-VLC_API bool
-vlc_player_IsTeletextTransparent(vlc_player_t *player);
+VLC_API float
+vlc_player_aout_GetVolume(vlc_player_t *player);
 
 /**
- * Get the title list of the current media
+ * Set the audio volume
  *
- * @see vlc_player_cbs.on_titles_changed
+ * @note The player instance doesn't need to be locked for vlc_player_aout_*()
+ * functions.
  *
- * @param player locked player instance
+ * @note A successful call will trigger the
+ * vlc_player_vout_cbs.on_volume_changed event.
+ *
+ * @param player player instance
+ * @param volume volume in the range [0;2.f]
+ * @return VLC_SUCCESS or VLC_EGENERIC if there is no audio outputs
  */
-VLC_API vlc_player_title_list *
-vlc_player_GetTitleList(vlc_player_t *player);
+VLC_API int
+vlc_player_aout_SetVolume(vlc_player_t *player, float volume);
 
 /**
- * Get the selected title index for the current media
+ * Increment the audio volume
  *
- * @see vlc_player_cbs.on_title_selection_changed
+ * @see vlc_player_aout_SetVolume()
  *
- * @param player locked player instance
+ * @param player player instance
+ * @param steps number of "volume-step"
+ * @param result pointer to store the resulting volume (can be NULL)
+ * @return VLC_SUCCESS or VLC_EGENERIC if there is no audio outputs
  */
-VLC_API ssize_t
-vlc_player_GetSelectedTitleIdx(vlc_player_t *player);
+VLC_API int
+vlc_player_aout_IncrementVolume(vlc_player_t *player, int steps, float *result);
 
 /**
- * Helper to get the current selected title
+ * Helper to decrement the audio volume
  */
-static inline const struct vlc_player_title *
-vlc_player_GetSelectedTitle(vlc_player_t *player)
+static inline int
+vlc_player_aout_DecrementVolume(vlc_player_t *player, int steps, float *result)
 {
-    vlc_player_title_list *titles = vlc_player_GetTitleList(player);
-    if (!titles)
-        return NULL;
-    ssize_t selected_idx = vlc_player_GetSelectedTitleIdx(player);
-    if (selected_idx < 0)
-        return NULL;
-    return vlc_player_title_list_GetAt(titles, selected_idx);
+    return vlc_player_aout_IncrementVolume(player, -steps, result);
 }
 
 /**
- * Select a title index for the current media
+ * Check if the audio output is muted
  *
- * @note A successful call will trigger the
- * vlc_player_cbs.on_title_selection_changed event.
+ * @note The player instance doesn't need to be locked for vlc_player_aout_*()
+ * functions.
  *
- * @see vlc_player_title_list_GetAt()
- * @see vlc_player_title_list_GetCount()
+ * @see vlc_player_aout_cbs.on_mute_changed
  *
- * @param player locked player instance
- * @param index valid index in the range [0;count[
+ * @param player player instance
+ * @return 0 if not muted, 1 if muted, -1 if there is no audio outputs
  */
-VLC_API void
-vlc_player_SelectTitleIdx(vlc_player_t *player, size_t index);
+VLC_API int
+vlc_player_aout_IsMuted(vlc_player_t *player);
 
 /**
- * Select a title for the current media
+ * Mute or unmute the audio output
  *
- * @note A successful call will trigger the
- * vlc_player_cbs.on_title_selection_changed event.
+ * @note The player instance doesn't need to be locked for vlc_player_aout_*()
+ * functions.
  *
- * @see vlc_player_title_list_GetAt()
- * @see vlc_player_title_list_GetCount()
+ * @note A successful call will trigger the
+ * vlc_player_aout_cbs.on_mute_changed event.
  *
- * @param player locked player instance
- * @param title a valid title coming from the vlc_player_title_list
+ * @param player player instance
+ * @param mute true to mute
+ * @return VLC_SUCCESS or VLC_EGENERIC if there is no audio outputs
  */
-VLC_API void
-vlc_player_SelectTitle(vlc_player_t *player,
-                       const struct vlc_player_title *title);
+VLC_API int
+vlc_player_aout_Mute(vlc_player_t *player, bool mute);
 
 /**
- * Select a chapter for the current media
- *
- * @note A successful call will trigger the
- * vlc_player_cbs.on_chapter_selection_changed event.
- *
- * @param player locked player instance
- * @param title the selected title
- * @param chapter_idx index from vlc_player_title.chapters
+ * Helper to toggle the mute state
  */
-VLC_API void
-vlc_player_SelectChapter(vlc_player_t *player,
-                         const struct vlc_player_title *title,
-                         size_t chapter_idx);
+static inline int
+vlc_player_aout_ToggleMute(vlc_player_t *player)
+{
+    return vlc_player_aout_Mute(player,
+                                !vlc_player_aout_IsMuted(player));
+}
 
 /**
- * Select the next title for the current media
+ * Enable or disable an audio filter
  *
- * @see vlc_player_SelectTitleIdx()
+ * @see aout_EnableFilter()
+ *
+ * @return VLC_SUCCESS or VLC_EGENERIC if there is no audio outputs
  */
-VLC_API void
-vlc_player_SelectNextTitle(vlc_player_t *player);
+VLC_API int
+vlc_player_aout_EnableFilter(vlc_player_t *player, const char *name, bool add);
+
+/** @} vlc_player__aout */
 
 /**
- * Select the previous title for the current media
- *
- * @see vlc_player_SelectTitleIdx()
+ * @defgroup vlc_player__vout Video output control
+ * @{
  */
-VLC_API void
-vlc_player_SelectPrevTitle(vlc_player_t *player);
 
 /**
- * Get the selected chapter index for the current media
- *
- * @see vlc_player_cbs.on_chapter_selection_changed
+ * Player vout listener opaque structure.
  *
- * @param player locked player instance
+ * This opaque structure is returned by vlc_player_vout_AddListener() and can
+ * be used to remove the listener via vlc_player_vout_RemoveListener().
  */
-VLC_API ssize_t
-vlc_player_GetSelectedChapterIdx(vlc_player_t *player);
+typedef struct vlc_player_vout_listener_id vlc_player_vout_listener_id;
 
 /**
- * Helper to get the current selected chapter
+ * action of vlc_player_cbs.on_vout_changed callback
  */
-static inline const struct vlc_player_chapter *
-vlc_player_GetSelectedChapter(vlc_player_t *player)
+enum vlc_player_vout_action
 {
-    const struct vlc_player_title *title = vlc_player_GetSelectedTitle(player);
-    if (!title || !title->chapter_count)
-        return NULL;
-    ssize_t chapter_idx = vlc_player_GetSelectedChapterIdx(player);
-    return chapter_idx >= 0 ? &title->chapters[chapter_idx] : NULL;
-}
+    VLC_PLAYER_VOUT_STARTED,
+    VLC_PLAYER_VOUT_STOPPED,
+};
 
 /**
- * Select a chapter index for the current media
+ * Player vout callbacks
  *
- * @note A successful call will trigger the
- * vlc_player_cbs.on_chaper_selection_changed event.
+ * Can be registered with vlc_player_vout_AddListener().
  *
- * @see vlc_player_title.chapters
+ * These callbacks are *not* called with the player locked. It is safe to lock
+ * the player and call any vlc_player functions from these callbacks.
  *
- * @param player locked player instance
- * @param index valid index in the range [0;vlc_player_title.chapter_count[
- */
-VLC_API void
-vlc_player_SelectChapterIdx(vlc_player_t *player, size_t index);
-
-/**
- * Select the next chapter for the current media
+ * @note The state changed from the callbacks can be either applied on the
+ * player (and all future video outputs), or on a specified video output. The
+ * state is applied on the player when the vout argument is NULL.
  *
- * @see vlc_player_SelectChapterIdx()
+ * @warning To avoid deadlocks, users should never call vout_thread_t functions
+ * from these callbacks.
  */
-VLC_API void
-vlc_player_SelectNextChapter(vlc_player_t *player);
+struct vlc_player_vout_cbs
+{
+    /**
+     * Called when the player and/or vout fullscreen state has changed
+     *
+     * @see vlc_player_vout_SetFullscreen()
+     *
+     * @param player unlocked player instance
+     * @param vout cf. vlc_player_vout_cbs note
+     * @param enabled true when fullscreen is enabled
+     * @param data opaque pointer set by vlc_player_vout_AddListener()
+     */
+    void (*on_fullscreen_changed)(vlc_player_t *player,
+        vout_thread_t *vout, bool enabled, void *data);
+
+    /**
+     * Called when the player and/or vout wallpaper mode has changed
+     *
+     * @see vlc_player_vout_SetWallpaperModeEnabled()
+     *
+     * @param player unlocked player instance
+     * @param vout cf. vlc_player_vout_cbs note
+     * @param enabled true when wallpaper mode is enabled
+     * @param data opaque pointer set by vlc_player_vout_AddListener()
+     */
+    void (*on_wallpaper_mode_changed)(vlc_player_t *player,
+        vout_thread_t *vout, bool enabled, void *data);
+};
+
 
 /**
- * Select the previous chapter for the current media
+ * Get and hold the main video output
  *
- * @see vlc_player_SelectChapterIdx()
+ * @warning the returned vout_thread_t * must be released with vout_Release().
+ * @see vlc_players_cbs.on_vout_changed
+ *
+ * @note The player is guaranteed to always hold one valid vout. Only vout
+ * variables can be changed from this instance. The vout returned before
+ * playback is not necessarily the same one that will be used for playback.
+ *
+ * @param player player instance
+ * @return a valid vout_thread_t * or NULL, cf. warning
  */
-VLC_API void
-vlc_player_SelectPrevChapter(vlc_player_t *player);
+VLC_API vout_thread_t *
+vlc_player_vout_Hold(vlc_player_t *player);
 
 /**
- * Add an associated (or external) media to the current media
+ * Get and hold the list of video output
  *
- * @param player locked player instance
- * @param cat AUDIO_ES or SPU_ES
- * @param uri absolute uri of the external media
- * @param select true to select the track of this external media
- * @param notify true to notify the OSD
- * @param check_ext true to check subtitles extension
+ * @warning All vout_thread_t * element of the array must be released with
+ * vout_Release(). The returned array must be freed.
+ *
+ * @see vlc_players_cbs.on_vout_changed
+ *
+ * @param player player instance
+ * @param count valid pointer to store the array count
+ * @return a array of vout_thread_t * or NULL, cf. warning
  */
-VLC_API int
-vlc_player_AddAssociatedMedia(vlc_player_t *player,
-                              enum es_format_category_e cat, const char *uri,
-                              bool select, bool notify, bool check_ext);
+VLC_API vout_thread_t **
+vlc_player_vout_HoldAll(vlc_player_t *player, size_t *count);
 
 /**
- * Set the associated subtitle FPS
- *
- * In order to correct the rate of the associated media according to this FPS
- * and the media video FPS.
- *
- * @note A successful call will trigger the
- * vlc_player_cbs.on_associated_subs_fps_changed event.
+ * Add a listener callback for video output events
  *
- * @warning this function will change the rate of all external subtitle files
- * associated with the current media.
+ * @note The player instance doesn't need to be locked for vlc_player_vout_*()
+ * functions.
+ * @note Every registered callbacks need to be removed by the caller with
+ * vlc_player_vout_RemoveListener().
  *
- * @param player locked player instance
- * @param fps FPS of the subtitle file
+ * @param player player instance
+ * @param cbs pointer to a vlc_player_vout_cbs structure, the structure must be
+ * valid during the lifetime of the player
+ * @param cbs_data opaque pointer used by the callbacks
+ * @return a valid listener id, or NULL in case of allocation error
  */
-VLC_API void
-vlc_player_SetAssociatedSubsFPS(vlc_player_t *player, float fps);
+VLC_API vlc_player_vout_listener_id *
+vlc_player_vout_AddListener(vlc_player_t *player,
+                            const struct vlc_player_vout_cbs *cbs,
+                            void *cbs_data);
 
 /**
- * Get the associated subtitle FPS
+ * Remove a vout listener callback
  *
- * @param player locked player instance
- * @return fps
+ * @param player player instance
+ * @param listener_id listener id returned by vlc_player_vout_AddListener()
  */
-VLC_API float
-vlc_player_GetAssociatedSubsFPS(vlc_player_t *player);
+VLC_API void
+vlc_player_vout_RemoveListener(vlc_player_t *player,
+                               vlc_player_vout_listener_id *listener_id);
 
 /**
- * Set the renderer
+ * Check if the player is fullscreen
  *
- * Valid for the current media and all future ones.
+ * @warning The fullscreen state of the player and all vouts can be different.
  *
- * @note A successful call will trigger the vlc_player_cbs.on_renderer_changed
- * event.
+ * @note The player instance doesn't need to be locked for vlc_player_vout_*()
+ * functions.
  *
- * @param player locked player instance
- * @param renderer a valid renderer item or NULL (to disable it), the item will
- * be held by the player
+ * @see vlc_player_vout_cbs.on_fullscreen_changed
+ *
+ * @param player player instance
+ * @return true if the player is fullscreen
  */
-VLC_API void
-vlc_player_SetRenderer(vlc_player_t *player, vlc_renderer_item_t *renderer);
+VLC_API bool
+vlc_player_vout_IsFullscreen(vlc_player_t *player);
 
 /**
- * Get the renderer
+ * Enable or disable the player fullscreen state
  *
- * @see vlc_player_cbs.on_renderer_changed
+ * This will have an effect on all current and future vouts.
  *
- * @param player locked player instance
- * @return the renderer item set by vlc_player_SetRenderer()
- */
-VLC_API vlc_renderer_item_t *
-vlc_player_GetRenderer(vlc_player_t *player);
-
-/**
- * Navigate (for DVD/Bluray menus or viewpoint)
+ * @note The player instance doesn't need to be locked for vlc_player_vout_*()
+ * functions.
+ * @note A successful call will trigger the
+ * vlc_player_vout_cbs.on_fullscreen_changed event.
  *
- * @param player locked player instance
- * @param nav navigation key
+ * @param player player instance
+ * @param enabled true to enable fullscreen
  */
 VLC_API void
-vlc_player_Navigate(vlc_player_t *player, enum vlc_player_nav nav);
+vlc_player_vout_SetFullscreen(vlc_player_t *player, bool enabled);
 
 /**
-  * Update the viewpoint
-  *
-  * @param player locked player instance
-  * @param viewpoint the viewpoint value
-  * @param whence absolute or relative
-  * @return VLC_SUCCESS or a VLC error code
-  */
-VLC_API void
-vlc_player_UpdateViewpoint(vlc_player_t *player,
-                           const vlc_viewpoint_t *viewpoint,
-                           enum vlc_player_whence whence);
+ * Helper to toggle the player fullscreen state
+ */
+static inline void
+vlc_player_vout_ToggleFullscreen(vlc_player_t *player)
+{
+    vlc_player_vout_SetFullscreen(player,
+                                  !vlc_player_vout_IsFullscreen(player));
+}
 
 /**
- * Check if the playing is recording
+ * Check if the player has wallpaper-mode enaled
  *
- * @see vlc_player_cbs.on_recording_changed
+ * @warning The wallpaper-mode state of the player and all vouts can be
+ * different.
  *
- * @param player locked player instance
- * @return true if the player is recording
+ * @note The player instance doesn't need to be locked for vlc_player_vout_*()
+ * functions.
+ *
+ * @see vlc_player_vout_cbs.on_wallpaper_mode_changed
+ *
+ * @param player player instance
+ * @return true if the player is fullscreen
  */
 VLC_API bool
-vlc_player_IsRecording(vlc_player_t *player);
+vlc_player_vout_IsWallpaperModeEnabled(vlc_player_t *player);
 
 /**
- * Enable or disable recording for the current media
+ * Enable or disable the player wallpaper-mode
  *
- * @note A successful call will trigger the vlc_player_cbs.on_recording_changed
- * event.
+ * This will have an effect on all current and future vouts.
  *
- * @param player locked player instance
- * @param enabled true to enable recording
+ * @note The player instance doesn't need to be locked for vlc_player_vout_*()
+ * functions.
+ * @note A successful call will trigger the
+ * vlc_player_vout_cbs.on_wallpaper_mode_changed event.
+ *
+ * @param player player instance
+ * @param enabled true to enable wallpaper-mode
  */
 VLC_API void
-vlc_player_SetRecordingEnabled(vlc_player_t *player, bool enabled);
+vlc_player_vout_SetWallpaperModeEnabled(vlc_player_t *player, bool enabled);
 
 /**
- * Helper to toggle the recording state
+ * Helper to toggle the player wallpaper-mode state
  */
 static inline void
-vlc_player_ToggleRecording(vlc_player_t *player)
+vlc_player_vout_ToggleWallpaperMode(vlc_player_t *player)
 {
-    vlc_player_SetRecordingEnabled(player, !vlc_player_IsRecording(player));
+    vlc_player_vout_SetWallpaperModeEnabled(player,
+        !vlc_player_vout_IsWallpaperModeEnabled(player));
 }
 
 /**
- * Get the delay of an ES category for the current media
- *
- * @see vlc_player_cbs.on_category_delay_changed
+ * Take a snapshot on all vouts
  *
- * @param player locked player instance
- * @param cat AUDIO_ES or SPU_ES (VIDEO_ES not supported yet)
- * @return a valid delay or 0
+ * @param player player instance
  */
-VLC_API vlc_tick_t
-vlc_player_GetCategoryDelay(vlc_player_t *player, enum es_format_category_e cat);
+VLC_API void
+vlc_player_vout_Snapshot(vlc_player_t *player);
 
 /**
- * Set the delay of one category for the current media
- *
- * @note A successful call will trigger the
- * vlc_player_cbs.on_category_delay_changed event.
+ * Display an OSD message on all vouts
  *
- * @warning This has no effect on tracks where the delay was set by
- * vlc_player_SetEsIdDelay()
+ * @param player player instance
+ * @param fmt format string
+ */
+VLC_API void
+vlc_player_vout_OSDMessage(vlc_player_t *player, const char *fmt, ...);
+
+/** @} vlc_player__vout */
+
+/**
+ * @defgroup vlc_player__events Player events
+ * @{
+ */
+
+/**
+ * Player listener opaque structure.
  *
- * @param player locked player instance
- * @param cat AUDIO_ES or SPU_ES (VIDEO_ES not supported yet)
- * @param delay a valid time
- * @param whence absolute or relative
- * @return VLC_SUCCESS or VLC_EGENERIC if the category is not handled
+ * This opaque structure is returned by vlc_player_AddListener() and can be
+ * used to remove the listener via vlc_player_RemoveListener().
  */
-VLC_API int
-vlc_player_SetCategoryDelay(vlc_player_t *player, enum es_format_category_e cat,
-                            vlc_tick_t delay, enum vlc_player_whence whence);
+typedef struct vlc_player_listener_id vlc_player_listener_id;
 
 /**
- * Get the delay of a track
+ * Action of vlc_player_cbs.on_track_list_changed,
+ * vlc_player_cbs.on_program_list_changed callbacks
+ */
+enum vlc_player_list_action
+{
+    VLC_PLAYER_LIST_ADDED,
+    VLC_PLAYER_LIST_REMOVED,
+    VLC_PLAYER_LIST_UPDATED,
+};
+
+/**
+ * Player callbacks
  *
- * @see vlc_player_cbs.on_track_delay_changed
+ * Can be registered with vlc_player_AddListener().
  *
- * @param player locked player instance
- * @param id an ES ID (retrieved from vlc_player_cbs.on_track_list_changed or
- * vlc_player_GetTrackAt())
- * @return a valid delay or INT64_MAX is no delay is set for this track
+ * All callbacks are called with the player locked (cf. vlc_player_Lock()) and
+ * from any threads (and even synchronously from a vlc_player function in some
+ * cases). It is safe to call any vlc_player functions from these callbacks
+ * except vlc_player_Delete().
+ *
+ * @warning To avoid deadlocks, users should never call vlc_player functions
+ * with an external mutex locked and lock this same mutex from a player
+ * callback.
  */
-VLC_API vlc_tick_t
-vlc_player_GetEsIdDelay(vlc_player_t *player, vlc_es_id_t *es_id);
+struct vlc_player_cbs
+{
+    /**
+     * Called when the current media has changed
+     *
+     * @note This can be called from the PLAYING state (when the player plays
+     * the next media internally) or from the STOPPED state (from
+     * vlc_player_SetCurrentMedia() or from an internal transition).
+     *
+     * @see vlc_player_SetCurrentMedia()
+     * @see vlc_player_InvalidateNextMedia()
+     *
+     * @param player locked player instance
+     * @param new_media new media currently played or NULL (when there is no
+     * more media to play)
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_current_media_changed)(vlc_player_t *player,
+        input_item_t *new_media, void *data);
+
+    /**
+     * Called when the player state has changed
+     *
+     * @see vlc_player_state
+     *
+     * @param player locked player instance
+     * @param new_state new player state
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_state_changed)(vlc_player_t *player,
+        enum vlc_player_state new_state, void *data);
+
+    /**
+     * Called when a media triggered an error
+     *
+     * Can be called from any states. When it happens the player will stop
+     * itself. It is safe to play an other media or event restart the player
+     * (This will reset the error state).
+     *
+     * @param player locked player instance
+     * @param error player error
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_error_changed)(vlc_player_t *player,
+        enum vlc_player_error error, void *data);
+
+    /**
+     * Called when the player buffering (or cache) has changed
+     *
+     * This event is always called with the 0 and 1 values before a playback
+     * (in case of success).  Values in between depends on the media type.
+     *
+     * @param player locked player instance
+     * @param new_buffering buffering in the range [0:1]
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_buffering_changed)(vlc_player_t *player,
+        float new_buffering, void *data);
+
+    /**
+     * Called when the player rate has changed
+     *
+     * Triggered by vlc_player_ChangeRate(), not sent when the media starts
+     * with the default rate (1.f)
+     *
+     * @param player locked player instance
+     * @param new_rate player
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_rate_changed)(vlc_player_t *player,
+        float new_rate, void *data);
 
-/**
- * Set the delay of one track
- *
- * @note A successful call will trigger the
- * vlc_player_cbs.on_track_delay_changed event.
- *
- * @warning Setting the delay of one specific track will override previous and
- * future changes of delay made by vlc_player_SetCategoryDelay()
- *
- * @param player locked player instance
- * @param id an ES ID (retrieved from vlc_player_cbs.on_track_list_changed or
- * vlc_player_GetTrackAt())
- * @param delay a valid time or INT64_MAX to use default category delay
- * @param whence absolute or relative
- * @return VLC_SUCCESS or VLC_EGENERIC if the category of the es_id is not
- * handled (VIDEO_ES not supported yet)
- */
-VLC_API int
-vlc_player_SetEsIdDelay(vlc_player_t *player, vlc_es_id_t *es_id,
-                        vlc_tick_t delay, enum vlc_player_whence whence);
+    /**
+     * Called when the media capabilities has changed
+     *
+     * Always called when the media is opening. Can be called during playback.
+     *
+     * @param player locked player instance
+     * @param old_caps old player capabilities
+     * @param new_caps new player capabilities
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_capabilities_changed)(vlc_player_t *player,
+        int old_caps, int new_caps, void *data);
 
-/**
- * Helper to get the audio delay
- */
-static inline vlc_tick_t
-vlc_player_GetAudioDelay(vlc_player_t *player)
-{
-    return vlc_player_GetCategoryDelay(player, AUDIO_ES);
-}
+    /**
+     * Called when the player position has changed
+     *
+     * @note A started and playing media doesn't have necessarily a valid time.
+     *
+     * @param player locked player instance
+     * @param new_time a valid time or VLC_TICK_INVALID
+     * @param new_pos a valid position
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_position_changed)(vlc_player_t *player,
+        vlc_tick_t new_time, float new_pos, void *data);
 
-/**
- * Helper to set the audio delay
- */
-static inline void
-vlc_player_SetAudioDelay(vlc_player_t *player, vlc_tick_t delay,
-                         enum vlc_player_whence whence)
+    /**
+     * Called when the media length has changed
+     *
+     * May be called when the media is opening or during playback.
+     *
+     * @note A started and playing media doesn't have necessarily a valid length.
+     *
+     * @param player locked player instance
+     * @param new_length a valid time or VLC_TICK_INVALID
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_length_changed)(vlc_player_t *player,
+        vlc_tick_t new_length, void *data);
 
-{
-    vlc_player_SetCategoryDelay(player, AUDIO_ES, delay, whence);
-}
+    /**
+     * Called when a track is added, removed, or updated
+     *
+     * @note The track is only valid from this callback context. Users should
+     * duplicate this track via vlc_player_track_Dup() if they want to use it
+     * from an other context.
+     *
+     * @param player locked player instance
+     * @param action added, removed or updated
+     * @param track valid track
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_track_list_changed)(vlc_player_t *player,
+        enum vlc_player_list_action action,
+        const struct vlc_player_track *track, void *data);
 
-/**
- * Helper to get the subtitle delay
- */
-static inline vlc_tick_t
-vlc_player_GetSubtitleDelay(vlc_player_t *player)
-{
-    return vlc_player_GetCategoryDelay(player, SPU_ES);
-}
+    /**
+     * Called when a new track is selected and/or unselected
+     *
+     * @note This event can be called with both unselected_id and selected_id
+     * valid. This mean that a new track is replacing the old one.
+     *
+     * @param player locked player instance
+     * @param unselected_id valid track id or NULL (when nothing is unselected)
+     * @param selected_id valid track id or NULL (when nothing is selected)
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_track_selection_changed)(vlc_player_t *player,
+        vlc_es_id_t *unselected_id, vlc_es_id_t *selected_id, void *data);
 
-/**
- * Helper to set the subtitle delay
- */
-static inline void
-vlc_player_SetSubtitleDelay(vlc_player_t *player, vlc_tick_t delay,
-                            enum vlc_player_whence whence)
-{
-    vlc_player_SetCategoryDelay(player, SPU_ES, delay, whence);
-}
+    /**
+     * Called when a track delay has changed
+     *
+     * @param player locked player instance
+     * @param es_id valid track id
+     * @param delay a valid delay or INT64_MAX if the delay of this track is
+     * canceled
+     */
+    void (*on_track_delay_changed)(vlc_player_t *player,
+        vlc_es_id_t *es_id, vlc_tick_t delay, void *data);
 
-/**
- * Set the subtitle text scaling factor
- *
- * @note This function have an effect only if the subtitle track is a text type.
- *
- * @param player locked player instance
- * @param scale factor in the range [10;500] (default: 100)
- */
-VLC_API void
-vlc_player_SetSubtitleTextScale(vlc_player_t *player, unsigned scale);
+    /**
+     * Called when a new program is added, removed or updated
+     *
+     * @note The program is only valid from this callback context. Users should
+     * duplicate this program via vlc_player_program_Dup() if they want to use
+     * it from an other context.
+     *
+     * @param player locked player instance
+     * @param action added, removed or updated
+     * @param prgm valid program
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_program_list_changed)(vlc_player_t *player,
+        enum vlc_player_list_action action,
+        const struct vlc_player_program *prgm, void *data);
 
-/**
- * Get the subtitle text scaling factor
- *
- * @param player locked player instance
- * @return scale factor
- */
-VLC_API unsigned
-vlc_player_GetSubtitleTextScale(vlc_player_t *player);
+    /**
+     * Called when a new program is selected and/or unselected
+     *
+     * @note This event can be called with both unselected_id and selected_id
+     * valid. This mean that a new program is replacing the old one.
+     *
+     * @param player locked player instance
+     * @param unselected_id valid program id or -1 (when nothing is unselected)
+     * @param selected_id valid program id or -1 (when nothing is selected)
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_program_selection_changed)(vlc_player_t *player,
+        int unselected_id, int selected_id, void *data);
 
-/**
- * Get the signal quality and strength of the current media
- *
- * @param player locked player instance
- */
-VLC_API int
-vlc_player_GetSignal(vlc_player_t *player, float *quality, float *strength);
+    /**
+     * Called when the media titles has changed
+     *
+     * This event is not called when the opening media doesn't have any titles.
+     * This title list and all its elements are constant. If an element is to
+     * be updated, a new list will be sent from this callback.
+     *
+     * @note Users should hold this list with vlc_player_title_list_Hold() if
+     * they want to use it from an other context.
+     *
+     * @param player locked player instance
+     * @param titles valid title list or NULL
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_titles_changed)(vlc_player_t *player,
+        vlc_player_title_list *titles, void *data);
 
-/**
- * Get the statistics of the current media
- *
- * @warning The returned pointer becomes invalid when the player is unlocked.
- * The referenced structure can be safely copied.
- *
- * @see vlc_player_cbs.on_statistics_changed
- *
- * @param player locked player instance
- * @return pointer to the player stats structure or NULL
- */
-VLC_API const struct input_stats_t *
-vlc_player_GetStatistics(vlc_player_t *player);
+    /**
+     * Called when a new title is selected
+     *
+     * There are no events when a title is unselected. Titles are automatically
+     * unselected when the title list changes. Titles and indexes are always
+     * valid inside the vlc_player_title_list sent by
+     * vlc_player_cbs.on_titles_changed.
+     *
+     * @param player locked player instance
+     * @param new_title new selected title
+     * @param new_idx index of this title
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_title_selection_changed)(vlc_player_t *player,
+        const struct vlc_player_title *new_title, size_t new_idx, void *data);
 
-/**
- * Enable or disable pause on cork event
- *
- * If enabled, the player will automatically pause and resume on cork events.
- * In that case, cork events won't be propagated via callbacks.
- * @see vlc_player_cbs.on_cork_changed
- *
- * @param player locked player instance
- * @param enabled true to enable
- */
-VLC_API void
-vlc_player_SetPauseOnCork(vlc_player_t *player, bool enabled);
+    /**
+     * Called when a new chapter is selected
+     *
+     * There are no events when a chapter is unselected. Chapters are
+     * automatically unselected when the title list changes. Titles, chapters
+     * and indexes are always valid inside the vlc_player_title_list sent by
+     * vlc_player_cbs.on_titles_changed.
+     *
+     * @param player locked player instance
+     * @param title selected title
+     * @param title_idx selected title index
+     * @param chapter new selected chapter
+     * @param chapter_idx new selected chapter index
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_chapter_selection_changed)(vlc_player_t *player,
+        const struct vlc_player_title *title, size_t title_idx,
+        const struct vlc_player_chapter *new_chapter, size_t new_chapter_idx,
+        void *data);
 
-/**
- * Get the V4L2 object used to do controls
- *
- * @param player locked player instance
- * @return the V4L2 object or NULL if not any. This object must be used with
- * the player lock held.
- */
-VLC_API vlc_object_t *
-vlc_player_GetV4l2Object(vlc_player_t *player) VLC_DEPRECATED;
+    /**
+     * Called when the media has a teletext menu
+     *
+     * @param player locked player instance
+     * @param has_teletext_menu true if the media has a teletext menu
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_teletext_menu_changed)(vlc_player_t *player,
+        bool has_teletext_menu, void *data);
 
-/**
- * Get the audio output
- *
- * @warning The returned pointer must be released with aout_Release().
- *
- * @param player player instance
- * @return a valid audio_output_t * or NULL (if there is no aouts)
- */
-VLC_API audio_output_t *
-vlc_player_aout_Hold(vlc_player_t *player);
+    /**
+     * Called when teletext is enabled or disabled
+     *
+     * @see vlc_player_SetTeletextEnabled()
+     *
+     * @param player locked player instance
+     * @param enabled true if teletext is enabled
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_teletext_enabled_changed)(vlc_player_t *player,
+        bool enabled, void *data);
 
-/**
- * Add a listener callback for audio output events
- *
- * @note The player instance doesn't need to be locked for vlc_player_aout_*()
- * functions.
- * @note Every registered callbacks need to be removed by the caller with
- * vlc_player_aout_RemoveListener().
- *
- * @param player player instance
- * @param cbs pointer to a vlc_player_aout_cbs structure, the structure must be
- * valid during the lifetime of the player
- * @param cbs_data opaque pointer used by the callbacks
- * @return a valid listener id, or NULL in case of allocation error
- */
-VLC_API vlc_player_aout_listener_id *
-vlc_player_aout_AddListener(vlc_player_t *player,
-                            const struct vlc_player_aout_cbs *cbs,
-                            void *cbs_data);
+    /**
+     * Called when the teletext page has changed
+     *
+     * @see vlc_player_SelectTeletextPage()
+     *
+     * @param player locked player instance
+     * @param new_page page in the range ]0;888]
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_teletext_page_changed)(vlc_player_t *player,
+        unsigned new_page, void *data);
 
-/**
- * Remove a aout listener callback
- *
- * @param player player instance
- * @param listener_id listener id returned by vlc_player_aout_AddListener()
- */
-VLC_API void
-vlc_player_aout_RemoveListener(vlc_player_t *player,
-                               vlc_player_aout_listener_id *listener_id);
+    /**
+     * Called when the teletext transparency has changed
+     *
+     * @see vlc_player_SetTeletextTransparency()
+     *
+     * @param player locked player instance
+     * @param enabled true is the teletext overlay is transparent
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_teletext_transparency_changed)(vlc_player_t *player,
+        bool enabled, void *data);
 
-/**
- * Get the audio volume
- *
- * @note The player instance doesn't need to be locked for vlc_player_aout_*()
- * functions.
- *
- * @see vlc_player_aout_cbs.on_volume_changed
- *
- * @param player player instance
- * @return volume in the range [0;2.f] or -1.f if there is no audio outputs
- * (independent of mute)
- */
-VLC_API float
-vlc_player_aout_GetVolume(vlc_player_t *player);
+    /**
+     * Called when the player category delay has changed for the current media
+     *
+     * @see vlc_player_SetCategoryDelay()
+     *
+     * @param player locked player instance
+     * @param cat AUDIO_ES or SPU_ES
+     * @param new_delay audio delay
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_category_delay_changed)(vlc_player_t *player,
+         enum es_format_category_e cat, vlc_tick_t new_delay, void *data);
 
-/**
- * Set the audio volume
- *
- * @note The player instance doesn't need to be locked for vlc_player_aout_*()
- * functions.
- *
- * @note A successful call will trigger the
- * vlc_player_vout_cbs.on_volume_changed event.
- *
- * @param player player instance
- * @param volume volume in the range [0;2.f]
- * @return VLC_SUCCESS or VLC_EGENERIC if there is no audio outputs
- */
-VLC_API int
-vlc_player_aout_SetVolume(vlc_player_t *player, float volume);
+    /**
+     * Called when associated subtitle has changed
+     *
+     * @see vlc_player_SetAssociatedSubsFPS()
+     *
+     * @param player locked player instance
+     * @param sub_fps subtitle fps
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_associated_subs_fps_changed)(vlc_player_t *player,
+        float subs_fps, void *data);
 
-/**
- * Increment the audio volume
- *
- * @see vlc_player_aout_SetVolume()
- *
- * @param player player instance
- * @param steps number of "volume-step"
- * @param result pointer to store the resulting volume (can be NULL)
- * @return VLC_SUCCESS or VLC_EGENERIC if there is no audio outputs
- */
-VLC_API int
-vlc_player_aout_IncrementVolume(vlc_player_t *player, int steps, float *result);
+    /**
+     * Called when a new renderer item is set
+     *
+     * @see vlc_player_SetRenderer()
+     *
+     * @param player locked player instance
+     * @param new_item a valid renderer item or NULL (if unset)
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_renderer_changed)(vlc_player_t *player,
+        vlc_renderer_item_t *new_item, void *data);
 
-/**
- * Helper to decrement the audio volume
- */
-static inline int
-vlc_player_aout_DecrementVolume(vlc_player_t *player, int steps, float *result)
-{
-    return vlc_player_aout_IncrementVolume(player, -steps, result);
-}
+    /**
+     * Called when the player recording state has changed
+     *
+     * @see vlc_player_SetRecordingEnabled()
+     *
+     * @param player locked player instance
+     * @param recording true if recording is enabled
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_recording_changed)(vlc_player_t *player,
+        bool recording, void *data);
 
-/**
- * Check if the audio output is muted
- *
- * @note The player instance doesn't need to be locked for vlc_player_aout_*()
- * functions.
- *
- * @see vlc_player_aout_cbs.on_mute_changed
- *
- * @param player player instance
- * @return 0 if not muted, 1 if muted, -1 if there is no audio outputs
- */
-VLC_API int
-vlc_player_aout_IsMuted(vlc_player_t *player);
+    /**
+     * Called when the media signal has changed
+     *
+     * @param player locked player instance
+     * @param new_quality signal quality
+     * @param new_strength signal strength,
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_signal_changed)(vlc_player_t *player,
+        float quality, float strength, void *data);
 
-/**
- * Mute or unmute the audio output
- *
- * @note The player instance doesn't need to be locked for vlc_player_aout_*()
- * functions.
- *
- * @note A successful call will trigger the
- * vlc_player_aout_cbs.on_mute_changed event.
- *
- * @param player player instance
- * @param mute true to mute
- * @return VLC_SUCCESS or VLC_EGENERIC if there is no audio outputs
- */
-VLC_API int
-vlc_player_aout_Mute(vlc_player_t *player, bool mute);
+    /**
+     * Called when the player has new statisics
+     *
+     * @note The stats structure is only valid from this callback context. It
+     * can be copied in order to use it from an other context.
+     *
+     * @param player locked player instance
+     * @param stats valid stats, only valid from this context
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_statistics_changed)(vlc_player_t *player,
+        const struct input_stats_t *stats, void *data);
+
+    /**
+     * Called when the A to B loop has changed
+     *
+     * @see vlc_player_SetAtoBLoop()
+     *
+     * @param player locked player instance
+     * @param state A, when only A is set, B when both A and B are set, None by
+     * default
+     * @param time valid time or VLC_TICK_INVALID of the current state
+     * @param pos valid pos of the current state
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_atobloop_changed)(vlc_player_t *player,
+        enum vlc_player_abloop new_state, vlc_tick_t time, float pos,
+        void *data);
 
-/**
- * Helper to toggle the mute state
- */
-static inline int
-vlc_player_aout_ToggleMute(vlc_player_t *player)
-{
-    return vlc_player_aout_Mute(player,
-                                !vlc_player_aout_IsMuted(player));
-}
+    /**
+     * Called when media stopped action has changed
+     *
+     * @see vlc_player_SetMediaStoppedAction()
+     *
+     * @param player locked player instance
+     * @param new_action action to execute when a media is stopped
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_media_stopped_action_changed)(vlc_player_t *player,
+        enum vlc_player_media_stopped_action new_action, void *data);
 
-/**
- * Enable or disable an audio filter
- *
- * @see aout_EnableFilter()
- *
- * @return VLC_SUCCESS or VLC_EGENERIC if there is no audio outputs
- */
-VLC_API int
-vlc_player_aout_EnableFilter(vlc_player_t *player, const char *name, bool add);
+    /**
+     * Called when the media meta has changed
+     *
+     * @param player locked player instance
+     * @param media current media
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_media_meta_changed)(vlc_player_t *player,
+        input_item_t *media, void *data);
 
-/**
- * Get and hold the main video output
- *
- * @warning the returned vout_thread_t * must be released with vout_Release().
- * @see vlc_players_cbs.on_vout_changed
- *
- * @note The player is guaranteed to always hold one valid vout. Only vout
- * variables can be changed from this instance. The vout returned before
- * playback is not necessarily the same one that will be used for playback.
- *
- * @param player player instance
- * @return a valid vout_thread_t * or NULL, cf. warning
- */
-VLC_API vout_thread_t *
-vlc_player_vout_Hold(vlc_player_t *player);
+    /**
+     * Called when media epg has changed
+     *
+     * @param player locked player instance
+     * @param media current media
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_media_epg_changed)(vlc_player_t *player,
+        input_item_t *media, void *data);
 
-/**
- * Get and hold the list of video output
- *
- * @warning All vout_thread_t * element of the array must be released with
- * vout_Release(). The returned array must be freed.
- *
- * @see vlc_players_cbs.on_vout_changed
- *
- * @param player player instance
- * @param count valid pointer to store the array count
- * @return a array of vout_thread_t * or NULL, cf. warning
- */
-VLC_API vout_thread_t **
-vlc_player_vout_HoldAll(vlc_player_t *player, size_t *count);
+    /**
+     * Called when the media has new subitems
+     *
+     * @param player locked player instance
+     * @param media current media
+     * @param new_subitems node representing all media subitems
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_media_subitems_changed)(vlc_player_t *player,
+        input_item_t *media, input_item_node_t *new_subitems, void *data);
+
+    /**
+     * Called when a vout is started or stopped
+     *
+     * @note In case, several media with only one video track are played
+     * successively, the same vout instance will be started and stopped several
+     * time.
+     *
+     * @param player locked player instance
+     * @param action started or stopped
+     * @param vout vout (can't be NULL)
+     * @param order vout order
+     * @param es_id the ES id associated with this vout
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_vout_changed)(vlc_player_t *player,
+        enum vlc_player_vout_action action, vout_thread_t *vout,
+        enum vlc_vout_order order, vlc_es_id_t *es_id, void *data);
+
+    /**
+     * Called when the player is corked
+     *
+     * The player can be corked when the audio output loose focus or when a
+     * renderer was paused from the outside.
+     *
+     * @note called only if pause on cork was not set to true (by
+     * vlc_player_SetPauseOnCork())
+     * @note a cork_count higher than 0 means the player is corked. In that
+     * case, the user should pause the player and release all external resource
+     * needed by the player. A value higher than 1 mean that the player was
+     * corked more than one time (for different reasons). A value of 0 means
+     * the player is no longer corked. In that case, the user could resume the
+     * player.
+     *
+     * @param player locked player instance
+     * @param cork_count 0 for uncorked, > 0 for corked
+     * @param data opaque pointer set by vlc_player_AddListener()
+     */
+    void (*on_cork_changed)(vlc_player_t *player, unsigned cork_count,
+                            void *data);
+};
 
 /**
- * Add a listener callback for video output events
+ * Add a listener callback
  *
- * @note The player instance doesn't need to be locked for vlc_player_vout_*()
- * functions.
  * @note Every registered callbacks need to be removed by the caller with
- * vlc_player_vout_RemoveListener().
+ * vlc_player_RemoveListener().
  *
- * @param player player instance
- * @param cbs pointer to a vlc_player_vout_cbs structure, the structure must be
+ * @param player locked player instance
+ * @param cbs pointer to a vlc_player_cbs structure, the structure must be
  * valid during the lifetime of the player
  * @param cbs_data opaque pointer used by the callbacks
  * @return a valid listener id, or NULL in case of allocation error
  */
-VLC_API vlc_player_vout_listener_id *
-vlc_player_vout_AddListener(vlc_player_t *player,
-                            const struct vlc_player_vout_cbs *cbs,
-                            void *cbs_data);
-
-/**
- * Remove a vout listener callback
- *
- * @param player player instance
- * @param listener_id listener id returned by vlc_player_vout_AddListener()
- */
-VLC_API void
-vlc_player_vout_RemoveListener(vlc_player_t *player,
-                               vlc_player_vout_listener_id *listener_id);
-
-/**
- * Check if the player is fullscreen
- *
- * @warning The fullscreen state of the player and all vouts can be different.
- *
- * @note The player instance doesn't need to be locked for vlc_player_vout_*()
- * functions.
- *
- * @see vlc_player_vout_cbs.on_fullscreen_changed
- *
- * @param player player instance
- * @return true if the player is fullscreen
- */
-VLC_API bool
-vlc_player_vout_IsFullscreen(vlc_player_t *player);
-
-/**
- * Enable or disable the player fullscreen state
- *
- * This will have an effect on all current and future vouts.
- *
- * @note The player instance doesn't need to be locked for vlc_player_vout_*()
- * functions.
- * @note A successful call will trigger the
- * vlc_player_vout_cbs.on_fullscreen_changed event.
- *
- * @param player player instance
- * @param enabled true to enable fullscreen
- */
-VLC_API void
-vlc_player_vout_SetFullscreen(vlc_player_t *player, bool enabled);
-
-/**
- * Helper to toggle the player fullscreen state
- */
-static inline void
-vlc_player_vout_ToggleFullscreen(vlc_player_t *player)
-{
-    vlc_player_vout_SetFullscreen(player,
-                                  !vlc_player_vout_IsFullscreen(player));
-}
-
-/**
- * Check if the player has wallpaper-mode enaled
- *
- * @warning The wallpaper-mode state of the player and all vouts can be
- * different.
- *
- * @note The player instance doesn't need to be locked for vlc_player_vout_*()
- * functions.
- *
- * @see vlc_player_vout_cbs.on_wallpaper_mode_changed
- *
- * @param player player instance
- * @return true if the player is fullscreen
- */
-VLC_API bool
-vlc_player_vout_IsWallpaperModeEnabled(vlc_player_t *player);
-
-/**
- * Enable or disable the player wallpaper-mode
- *
- * This will have an effect on all current and future vouts.
- *
- * @note The player instance doesn't need to be locked for vlc_player_vout_*()
- * functions.
- * @note A successful call will trigger the
- * vlc_player_vout_cbs.on_wallpaper_mode_changed event.
- *
- * @param player player instance
- * @param enabled true to enable wallpaper-mode
- */
-VLC_API void
-vlc_player_vout_SetWallpaperModeEnabled(vlc_player_t *player, bool enabled);
-
-/**
- * Helper to toggle the player wallpaper-mode state
- */
-static inline void
-vlc_player_vout_ToggleWallpaperMode(vlc_player_t *player)
-{
-    vlc_player_vout_SetWallpaperModeEnabled(player,
-        !vlc_player_vout_IsWallpaperModeEnabled(player));
-}
+VLC_API vlc_player_listener_id *
+vlc_player_AddListener(vlc_player_t *player,
+                       const struct vlc_player_cbs *cbs, void *cbs_data);
 
 /**
- * Take a snapshot on all vouts
+ * Remove a listener callback
  *
- * @param player player instance
+ * @param player locked player instance
+ * @param listener_id listener id returned by vlc_player_AddListener()
  */
 VLC_API void
-vlc_player_vout_Snapshot(vlc_player_t *player);
+vlc_player_RemoveListener(vlc_player_t *player,
+                          vlc_player_listener_id *listener_id);
 
-/**
- * Display an OSD message on all vouts
- *
- * @param player player instance
- * @param fmt format string
- */
-VLC_API void
-vlc_player_vout_OSDMessage(vlc_player_t *player, const char *fmt, ...);
+/** @} vlc_player__events */
 
+/** @} player */
 
-/** @} */
 #endif
-- 
2.20.1




More information about the vlc-devel mailing list