[vlc-devel] [PATCH 1/9] dbus: use new playlist / player

Victorien Le Couviour--Tuffet victorien.lecouviour.tuffet at gmail.com
Tue Nov 27 13:34:39 CET 2018


---
 modules/control/dbus/dbus.c           | 535 +++++++++++++++-----------
 modules/control/dbus/dbus_common.h    |  18 +-
 modules/control/dbus/dbus_player.c    | 335 ++++++++--------
 modules/control/dbus/dbus_root.c      |  47 +--
 modules/control/dbus/dbus_tracklist.c | 162 +++-----
 5 files changed, 573 insertions(+), 524 deletions(-)

diff --git a/modules/control/dbus/dbus.c b/modules/control/dbus/dbus.c
index 7582e8df35..24bbb59819 100644
--- a/modules/control/dbus/dbus.c
+++ b/modules/control/dbus/dbus.c
@@ -57,8 +57,6 @@
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 #include <vlc_interface.h>
-#include <vlc_playlist_legacy.h>
-#include <vlc_input.h>
 #include <vlc_meta.h>
 #include <vlc_tick.h>
 #include <vlc_fs.h>
@@ -105,8 +103,6 @@ static void Close   ( vlc_object_t * );
 static void *Run    ( void * );
 
 static int TrackChange( intf_thread_t * );
-static int AllCallback( vlc_object_t*, const char*, vlc_value_t, vlc_value_t, void* );
-static int InputCallback( vlc_object_t*, const char*, vlc_value_t, vlc_value_t, void* );
 
 static dbus_bool_t add_timeout(DBusTimeout *, void *);
 static void remove_timeout(DBusTimeout *, void *);
@@ -130,6 +126,38 @@ static void ProcessWatches ( intf_thread_t    *p_intf,
 
 static void DispatchDBusMessages( intf_thread_t *p_intf );
 
+
+static void playlist_on_items_added(vlc_playlist_t *,
+                                    size_t, vlc_playlist_item_t *const [],
+                                    size_t, void *);
+static void playlist_on_items_removed(vlc_playlist_t *,
+                                      size_t, size_t, void *);
+static void playlist_on_playback_repeat_changed(vlc_playlist_t *,
+                                                enum vlc_playlist_playback_repeat,
+                                                void *);
+static void playlist_on_playback_order_changed(vlc_playlist_t *,
+                                               enum vlc_playlist_playback_order,
+                                               void *);
+static void playlist_on_current_index_changed(vlc_playlist_t *,
+                                              ssize_t, void *);
+
+static void player_on_state_changed(vlc_player_t *,
+                                    enum vlc_player_state, void *);
+static void player_on_error_changed(vlc_player_t *,
+                                    enum vlc_player_error, void *);
+static void player_on_rate_changed(vlc_player_t *, float, void *);
+static void player_on_capabilities_changed(vlc_player_t *, int, void *);
+static void player_on_position_changed(vlc_player_t *,
+                                       vlc_tick_t, float, void *);
+static void player_on_media_meta_changed(vlc_player_t *,
+                                         input_item_t *, void *);
+
+static void player_aout_on_volume_changed(vlc_player_t *, float, void *);
+static void player_aout_on_mute_changed(vlc_player_t *, bool, void *);
+
+static void player_vout_on_fullscreen_changed(vlc_player_t *,
+                                              vout_thread_t *, bool, void *);
+
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
@@ -148,6 +176,7 @@ vlc_module_end ()
 static int Open( vlc_object_t *p_this )
 {
     intf_thread_t   *p_intf = (intf_thread_t*)p_this;
+    vlc_playlist_t *playlist = NULL;
 
     /* initialisation of the connection */
     if( !dbus_threads_init_default() )
@@ -157,7 +186,6 @@ static int Open( vlc_object_t *p_this )
     if( unlikely(!p_sys) )
         return VLC_ENOMEM;
 
-    playlist_t      *p_playlist;
     DBusConnection  *p_conn;
     p_sys->i_player_caps   = PLAYER_CAPS_NONE;
     p_sys->i_playing_state = PLAYBACK_STATE_INVALID;
@@ -181,10 +209,7 @@ static int Open( vlc_object_t *p_this )
         msg_Err( p_this, "Failed to connect to the D-Bus session daemon: %s",
                 error.message );
         dbus_error_free( &error );
-        vlc_close( p_sys->p_pipe_fds[1] );
-        vlc_close( p_sys->p_pipe_fds[0] );
-        free( p_sys );
-        return VLC_EGENERIC;
+        goto dbus_connection_failure;
     }
 
     dbus_connection_set_exit_on_disconnect( p_conn, FALSE );
@@ -232,39 +257,90 @@ static int Open( vlc_object_t *p_this )
     vlc_array_init( &p_sys->watches );
     vlc_mutex_init( &p_sys->lock );
 
-    p_playlist = pl_Get( p_intf );
-    p_sys->p_playlist = p_playlist;
+    p_sys->playlist = playlist = vlc_intf_GetMainPlaylist(p_intf);
+    vlc_player_t *player = vlc_playlist_GetPlayer(playlist);
+
+    vlc_playlist_Lock(playlist);
+
+    static struct vlc_playlist_callbacks const playlist_cbs =
+    {
+        .on_items_added = playlist_on_items_added,
+        .on_items_removed = playlist_on_items_removed,
+        .on_playback_repeat_changed = playlist_on_playback_repeat_changed,
+        .on_playback_order_changed = playlist_on_playback_order_changed,
+        .on_current_index_changed = playlist_on_current_index_changed,
+    };
+    p_sys->playlist_listener =
+        vlc_playlist_AddListener(playlist, &playlist_cbs, p_intf, false);
+    if (!p_sys->playlist_listener)
+        goto playlist_listener_failure;
+
+    static struct vlc_player_cbs const player_cbs =
+    {
+        .on_state_changed = player_on_state_changed,
+        .on_error_changed = player_on_error_changed,
+        .on_rate_changed = player_on_rate_changed,
+        .on_capabilities_changed = player_on_capabilities_changed,
+        .on_position_changed = player_on_position_changed,
+        .on_media_meta_changed = player_on_media_meta_changed,
+    };
+    p_sys->player_listener =
+        vlc_player_AddListener(player, &player_cbs, p_intf);
+    if (!p_sys->player_listener)
+        goto player_listener_failure;
+
+    static struct vlc_player_aout_cbs const player_aout_cbs =
+    {
+        .on_volume_changed = player_aout_on_volume_changed,
+        .on_mute_changed = player_aout_on_mute_changed
+    };
+    p_sys->player_aout_listener =
+        vlc_player_aout_AddListener(player, &player_aout_cbs, p_intf);
+    if (!p_sys->player_aout_listener)
+        goto player_aout_listener_failure;
+
+    static struct vlc_player_vout_cbs const player_vout_cbs =
+    {
+        .on_fullscreen_changed = player_vout_on_fullscreen_changed,
+    };
+    p_sys->player_vout_listener =
+        vlc_player_vout_AddListener(player, &player_vout_cbs, p_intf);
+    if (!p_sys->player_vout_listener)
+        goto player_vout_listener_failure;
 
-    var_AddCallback( p_playlist, "input-current", AllCallback, p_intf );
-    var_AddCallback( p_playlist, "volume", AllCallback, p_intf );
-    var_AddCallback( p_playlist, "mute", AllCallback, p_intf );
-    var_AddCallback( p_playlist, "playlist-item-append", AllCallback, p_intf );
-    var_AddCallback( p_playlist, "playlist-item-deleted", AllCallback, p_intf );
-    var_AddCallback( p_playlist, "random", AllCallback, p_intf );
-    var_AddCallback( p_playlist, "repeat", AllCallback, p_intf );
-    var_AddCallback( p_playlist, "loop", AllCallback, p_intf );
-    var_AddCallback( p_playlist, "fullscreen", AllCallback, p_intf );
+    vlc_playlist_Unlock(playlist);
 
     if( !dbus_connection_set_timeout_functions( p_conn,
                                                 add_timeout,
                                                 remove_timeout,
                                                 toggle_timeout,
                                                 p_intf, NULL ) )
-        goto error;
+        goto late_failure;
 
     if( !dbus_connection_set_watch_functions( p_conn,
                                               add_watch,
                                               remove_watch,
                                               watch_toggled,
                                               p_intf, NULL ) )
-        goto error;
+        goto late_failure;
 
     if( vlc_clone( &p_sys->thread, Run, p_intf, VLC_THREAD_PRIORITY_LOW ) )
-        goto error;
+        goto late_failure;
 
     return VLC_SUCCESS;
 
-error:
+late_failure:
+    vlc_playlist_Lock(playlist);
+player_vout_listener_failure:
+    vlc_player_vout_RemoveListener(player, p_sys->player_vout_listener);
+player_aout_listener_failure:
+    vlc_player_aout_RemoveListener(player, p_sys->player_aout_listener);
+player_listener_failure:
+    vlc_player_RemoveListener(player, p_sys->player_listener);
+playlist_listener_failure:
+    vlc_playlist_RemoveListener(playlist, p_sys->playlist_listener);
+    vlc_playlist_Unlock(playlist);
+
     var_Destroy(p_intf->obj.libvlc, "dbus-mpris-name");
     /* The dbus connection is private,
      * so we are responsible for closing it
@@ -272,12 +348,14 @@ error:
     dbus_connection_close( p_sys->p_conn );
     dbus_connection_unref( p_conn );
 
+dbus_connection_failure:
     vlc_mutex_destroy( &p_sys->lock );
 
     vlc_close( p_sys->p_pipe_fds[1] );
     vlc_close( p_sys->p_pipe_fds[0] );
+
     free( p_sys );
-    return VLC_ENOMEM;
+    return VLC_EGENERIC;
 }
 
 /*****************************************************************************
@@ -288,28 +366,18 @@ static void Close   ( vlc_object_t *p_this )
 {
     intf_thread_t   *p_intf     = (intf_thread_t*) p_this;
     intf_sys_t      *p_sys      = p_intf->p_sys;
-    playlist_t      *p_playlist = p_sys->p_playlist;
+    vlc_playlist_t  *playlist = p_sys->playlist;
 
     vlc_cancel( p_sys->thread );
     vlc_join( p_sys->thread, NULL );
 
-    var_DelCallback( p_playlist, "input-current", AllCallback, p_intf );
-    var_DelCallback( p_playlist, "volume", AllCallback, p_intf );
-    var_DelCallback( p_playlist, "mute", AllCallback, p_intf );
-    var_DelCallback( p_playlist, "playlist-item-append", AllCallback, p_intf );
-    var_DelCallback( p_playlist, "playlist-item-deleted", AllCallback, p_intf );
-    var_DelCallback( p_playlist, "random", AllCallback, p_intf );
-    var_DelCallback( p_playlist, "repeat", AllCallback, p_intf );
-    var_DelCallback( p_playlist, "loop", AllCallback, p_intf );
-    var_DelCallback( p_playlist, "fullscreen", AllCallback, p_intf );
-
-    if( p_sys->p_input )
-    {
-        var_DelCallback( p_sys->p_input, "intf-event", InputCallback, p_intf );
-        var_DelCallback( p_sys->p_input, "can-pause", AllCallback, p_intf );
-        var_DelCallback( p_sys->p_input, "can-seek", AllCallback, p_intf );
-        vlc_object_release( p_sys->p_input );
-    }
+    vlc_player_t *player = vlc_playlist_GetPlayer(playlist);
+    vlc_playlist_Lock(playlist);
+    vlc_player_vout_RemoveListener(player, p_sys->player_vout_listener);
+    vlc_player_aout_RemoveListener(player, p_sys->player_aout_listener);
+    vlc_player_RemoveListener(player, p_sys->player_listener);
+    vlc_playlist_RemoveListener(playlist, p_sys->playlist_listener);
+    vlc_playlist_Unlock(playlist);
 
     /* The dbus connection is private, so we are responsible
      * for closing it */
@@ -552,10 +620,10 @@ static void ProcessEvents( intf_thread_t *p_intf,
         case SIGNAL_PLAYLIST_ITEM_APPEND:
         case SIGNAL_PLAYLIST_ITEM_DELETED:
         {
-            playlist_t *p_playlist = p_intf->p_sys->p_playlist;
-            PL_LOCK;
-            b_can_play = !playlist_IsEmpty( p_playlist );
-            PL_UNLOCK;
+            vlc_playlist_t *playlist = p_intf->p_sys->playlist;
+            vlc_playlist_Lock(playlist);
+            b_can_play = vlc_playlist_Count(playlist) > 0;
+            vlc_playlist_Unlock(playlist);
 
             if( b_can_play != p_intf->p_sys->b_can_play )
             {
@@ -589,17 +657,14 @@ static void ProcessEvents( intf_thread_t *p_intf,
             break;
         case SIGNAL_INPUT_METADATA:
         {
-            input_thread_t *p_input = pl_CurrentInput( p_intf );
-            input_item_t   *p_item;
-            if( p_input )
-            {
-                p_item = input_GetItem( p_input );
-                vlc_object_release( p_input );
-
-                if( p_item )
-                    vlc_dictionary_insert( &player_properties,
-                                           "Metadata", NULL );
-            }
+            vlc_player_t *player =
+                vlc_playlist_GetPlayer(p_intf->p_sys->playlist);
+            vlc_player_Lock(player);
+            input_item_t *p_item = vlc_player_GetCurrentMedia(player);
+            if( p_item )
+                vlc_dictionary_insert( &player_properties,
+                                       "Metadata", NULL );
+            vlc_player_Unlock(player);
             break;
         }
         case SIGNAL_CAN_SEEK:
@@ -810,7 +875,7 @@ static void *Run( void *data )
          *
          * The signal functions could lock mutex X while p_events is locked;
          * While some other function in vlc (playlist) might lock mutex X
-         * and then set a variable which would call AllCallback(), which itself
+         * and then set a variable which would call PlaylistCallback(), which itself
          * needs to lock p_events to add a new event.
          */
         vlc_mutex_lock( &p_intf->p_sys->lock );
@@ -883,231 +948,250 @@ static void   wakeup_main_loop( void *p_data )
                  vlc_strerror_c(errno) );
 }
 
-static bool add_event_locked( intf_thread_t *p_intf, callback_info_t *p_info )
+static bool add_event_locked( intf_thread_t *p_intf, const callback_info_t *p_info )
 {
     if( !p_info->signal )
-    {
-        free( p_info );
         return false;
-    }
 
     for( size_t i = 0; i < vlc_array_count( &p_intf->p_sys->events ); ++ i )
     {
         callback_info_t *oldinfo =
             vlc_array_item_at_index( &p_intf->p_sys->events, i );
         if( p_info->signal == oldinfo->signal )
-        {
-            free( p_info );
             return false;
-        }
     }
 
-    vlc_array_append( &p_intf->p_sys->events, p_info );
+    callback_info_t *p_dup = malloc( sizeof( *p_dup ) );
+    if( unlikely(p_dup == NULL) )
+        return false;
+    *p_dup = *p_info;
+
+    vlc_array_append( &p_intf->p_sys->events, p_dup );
     return true;
 }
 
-/* Flls a callback_info_t data structure in response
- * to an "intf-event" input event.
- *
- * @warning This function executes in the input thread.
- *
- * @return VLC_SUCCESS on success, VLC_E* on error.
- */
-static int InputCallback( vlc_object_t *p_this, const char *psz_var,
-                          vlc_value_t oldval, vlc_value_t newval, void *data )
+static bool add_event_signal( intf_thread_t *p_intf, const callback_info_t *p_info )
 {
-    input_thread_t *p_input = (input_thread_t *)p_this;
-    intf_thread_t *p_intf = data;
     intf_sys_t *p_sys = p_intf->p_sys;
+    vlc_mutex_lock(&p_sys->lock);
+    bool added = add_event_locked(p_intf, p_info);
+    vlc_mutex_unlock(&p_sys->lock);
 
-    dbus_int32_t i_state = PLAYBACK_STATE_INVALID;
-
-    callback_info_t *p_info = calloc( 1, sizeof( callback_info_t ) );
-    if( unlikely(p_info == NULL) )
-        return VLC_ENOMEM;
-
-    switch( newval.i_int )
-    {
-        case INPUT_EVENT_DEAD:
-            i_state = PLAYBACK_STATE_STOPPED;
-            break;
-        case INPUT_EVENT_STATE:
-            switch( var_GetInteger( p_input, "state" ) )
-            {
-                case OPENING_S:
-                case PLAYING_S:
-                    i_state = PLAYBACK_STATE_PLAYING;
-                    break;
-                case PAUSE_S:
-                    i_state = PLAYBACK_STATE_PAUSED;
-                    break;
-                default:
-                    i_state = PLAYBACK_STATE_STOPPED;
-            }
-            break;
-        case INPUT_EVENT_ITEM_META:
-            p_info->signal = SIGNAL_INPUT_METADATA;
-            break;
-        case INPUT_EVENT_RATE:
-            p_info->signal = SIGNAL_RATE;
-            break;
-        case INPUT_EVENT_POSITION:
-        {
-            vlc_tick_t i_now = vlc_tick_now(), i_pos, i_projected_pos, i_interval;
-            float f_current_rate;
+    if( added )
+        wakeup_main_loop( p_intf );
+    return added;
+}
 
-            /* Detect seeks
-             * XXX: This is way more convoluted than it should be... */
-            i_pos = var_GetInteger( p_input, "time" );
+static void
+playlist_on_items_added(vlc_playlist_t *playlist, size_t index,
+                        vlc_playlist_item_t *const items[], size_t count,
+                        void *data)
+{
+    add_event_signal(data,
+            &(callback_info_t){ .signal = SIGNAL_PLAYLIST_ITEM_APPEND });
+    (void) playlist; (void) index; (void) items; (void) count;
+}
 
-            if( !p_intf->p_sys->i_last_input_pos_event ||
-                !( var_GetInteger( p_input, "state" ) == PLAYING_S ) )
-            {
-                p_intf->p_sys->i_last_input_pos_event = i_now;
-                p_intf->p_sys->i_last_input_pos = i_pos;
-                break;
-            }
+static void
+playlist_on_items_removed(vlc_playlist_t *playlist,
+                          size_t index, size_t count, void *data)
+{
+    add_event_signal(data,
+            &(callback_info_t){ .signal = SIGNAL_PLAYLIST_ITEM_DELETED });
+    (void) playlist; (void) index; (void) count;
+}
 
-            f_current_rate = var_GetFloat( p_input, "rate" );
-            i_interval = ( i_now - p_intf->p_sys->i_last_input_pos_event );
+static void
+playlist_on_playback_repeat_changed(vlc_playlist_t *playlist,
+                                    enum vlc_playlist_playback_repeat repeat,
+                                    void *data)
+{
+    add_event_signal(data, &(callback_info_t){ .signal = SIGNAL_REPEAT });
+    (void) playlist; (void) repeat;
+}
 
-            i_projected_pos = p_intf->p_sys->i_last_input_pos +
-                ( i_interval * f_current_rate );
+static void
+playlist_on_playback_order_changed(vlc_playlist_t *playlist,
+                                   enum vlc_playlist_playback_order order,
+                                   void *data)
+{
+    add_event_signal(data, &(callback_info_t){ .signal = SIGNAL_RANDOM });
+    (void) playlist; (void) order;
+}
 
-            p_intf->p_sys->i_last_input_pos_event = i_now;
-            p_intf->p_sys->i_last_input_pos = i_pos;
+static void
+playlist_on_current_index_changed(vlc_playlist_t *playlist,
+                                  ssize_t index, void *data)
+{
+    add_event_signal(data,
+            &(callback_info_t){ .signal = SIGNAL_ITEM_CURRENT });
+    (void) playlist; (void) index;
+}
 
-            if( llabs( i_pos - i_projected_pos ) < SEEK_THRESHOLD )
-                break;
+static void
+player_on_state_changed(vlc_player_t *player, enum vlc_player_state state,
+                        void *data)
+{
+    intf_thread_t *intf = data;
+    intf_sys_t *sys = intf->p_sys;
+    dbus_int32_t playing_state;
 
-            p_info->signal = SIGNAL_SEEK;
+    switch (state)
+    {
+        case VLC_PLAYER_STATE_STARTED:
+        case VLC_PLAYER_STATE_PLAYING:
+            playing_state = PLAYBACK_STATE_PLAYING;
             break;
-        }
+        case VLC_PLAYER_STATE_PAUSED:
+            playing_state = PLAYBACK_STATE_PAUSED;
+            break;
+        case VLC_PLAYER_STATE_STOPPED:
         default:
-            free( p_info );
-            return VLC_SUCCESS; /* don't care */
+            playing_state = PLAYBACK_STATE_STOPPED;
+            break;
     }
 
-    vlc_mutex_lock( &p_sys->lock );
-    if( i_state != PLAYBACK_STATE_INVALID &&
-        i_state != p_sys->i_playing_state )
+    bool added = false;
+    vlc_mutex_lock(&sys->lock);
+    if (playing_state != sys->i_playing_state)
     {
-        p_sys->i_playing_state = i_state;
-        p_info->signal = SIGNAL_STATE;
+        sys->i_playing_state = playing_state;
+        added = add_event_locked(intf,
+                &(callback_info_t) { .signal = SIGNAL_STATE });
     }
-    bool added = add_event_locked( p_intf, p_info );
-    vlc_mutex_unlock( &p_intf->p_sys->lock );
+    vlc_mutex_unlock(&sys->lock);
 
-    if( added )
-        wakeup_main_loop( p_intf );
+    if (added)
+        wakeup_main_loop(intf);
+    (void) player;
+}
 
-    (void)psz_var;
-    (void)oldval;
-    return VLC_SUCCESS;
+static void
+player_on_error_changed(vlc_player_t *player, enum vlc_player_error error,
+                        void *data)
+{
+    if (error == VLC_PLAYER_ERROR_GENERIC)
+        player_on_state_changed(player, VLC_PLAYER_STATE_STOPPED, data);
 }
 
-// Get all the callbacks
-static int AllCallback( vlc_object_t *p_this, const char *psz_var,
-                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
+static void
+player_on_rate_changed(vlc_player_t *player, float new_rate, void *data)
 {
-    intf_thread_t *p_intf = p_data;
-    callback_info_t info = { .signal = SIGNAL_NONE };
+    add_event_signal(data, &(callback_info_t){ .signal = SIGNAL_RATE });
+    (void) player; (void) new_rate;
+}
 
-    // Wich event is it ?
-    if( !strcmp( "input-current", psz_var ) )
-        info.signal = SIGNAL_ITEM_CURRENT;
-    else if( !strcmp( "volume", psz_var ) )
-    {
-        if( oldval.f_float != newval.f_float )
-            info.signal = SIGNAL_VOLUME_CHANGE;
-    }
-    else if( !strcmp( "mute", psz_var ) )
+static void
+player_on_capabilities_changed(vlc_player_t *player, int new_caps, void *data)
+{
+    intf_thread_t *intf = data;
+    intf_sys_t *sys = intf->p_sys;
+
+    vlc_mutex_lock(&sys->lock);
+    bool ok1 = add_event_locked(intf,
+            &(callback_info_t) { .signal =  SIGNAL_CAN_SEEK });
+    bool ok2 = add_event_locked(intf,
+            &(callback_info_t) { .signal =  SIGNAL_CAN_PAUSE });
+    vlc_mutex_unlock(&sys->lock);
+    if (ok1 || ok2)
+        wakeup_main_loop(intf);
+    (void) player; (void) new_caps;
+}
+
+static void
+player_on_position_changed(vlc_player_t *player, vlc_tick_t time, float pos,
+                           void *data)
+{
+    intf_thread_t *intf = data;
+    intf_sys_t *sys = intf->p_sys;
+    vlc_tick_t i_now = vlc_tick_now(), i_projected_pos, i_interval;
+    float f_current_rate;
+
+    /* Detect seeks: moved from 1857cab238c
+     * XXX: This is way more convoluted than it should be... */
+
+    if( !sys->i_last_input_pos_event ||
+        vlc_player_GetState(player) != VLC_PLAYER_STATE_PLAYING )
     {
-        if( oldval.b_bool != newval.b_bool )
-            info.signal = SIGNAL_VOLUME_MUTED;
+        sys->i_last_input_pos_event = i_now;
+        sys->i_last_input_pos = pos;
+        return;
     }
-    else if( !strcmp( "playlist-item-append", psz_var ) )
-        info.signal = SIGNAL_PLAYLIST_ITEM_APPEND;
-    else if( !strcmp( "playlist-item-deleted", psz_var ) )
-        info.signal = SIGNAL_PLAYLIST_ITEM_DELETED;
-    else if( !strcmp( "random", psz_var ) )
-        info.signal = SIGNAL_RANDOM;
-    else if( !strcmp( "fullscreen", psz_var ) )
-        info.signal = SIGNAL_FULLSCREEN;
-    else if( !strcmp( "repeat", psz_var ) )
-        info.signal = SIGNAL_REPEAT;
-    else if( !strcmp( "loop", psz_var ) )
-        info.signal = SIGNAL_LOOP;
-    else if( !strcmp( "can-seek", psz_var ) )
-        info.signal = SIGNAL_CAN_SEEK;
-    else if( !strcmp( "can-pause", psz_var ) )
-        info.signal = SIGNAL_CAN_PAUSE;
-    else
-        vlc_assert_unreachable();
 
-    if( info.signal == SIGNAL_NONE )
-        return VLC_SUCCESS;
+    f_current_rate = vlc_player_GetRate(player);
+    i_interval = ( i_now - sys->i_last_input_pos_event );
 
-    callback_info_t *p_info = malloc( sizeof( *p_info ) );
-    if( unlikely(p_info == NULL) )
-        return VLC_ENOMEM;
+    i_projected_pos = sys->i_last_input_pos + ( i_interval * f_current_rate );
 
-    // Append the event
-    *p_info = info;
-    vlc_mutex_lock( &p_intf->p_sys->lock );
-    bool added = add_event_locked( p_intf, p_info );
-    vlc_mutex_unlock( &p_intf->p_sys->lock );
+    sys->i_last_input_pos_event = i_now;
+    sys->i_last_input_pos = pos;
 
-    if( added )
-        wakeup_main_loop( p_intf );
+    if( llabs( pos - i_projected_pos ) < SEEK_THRESHOLD )
+        return;
 
-    (void) p_this;
-    return VLC_SUCCESS;
+    add_event_signal(intf, &(callback_info_t){ .signal = SIGNAL_SEEK });
+    (void) time;
+}
+
+static void
+player_on_media_meta_changed(vlc_player_t *player,
+                             input_item_t *item, void *data)
+{
+    add_event_signal(data,
+            &(callback_info_t){ .signal = SIGNAL_INPUT_METADATA });
+    (void) player; (void) item;
+}
+
+static void
+player_aout_on_volume_changed(vlc_player_t *player, float volume, void *data)
+{
+    add_event_signal(data,
+            &(callback_info_t){ .signal = SIGNAL_VOLUME_CHANGE });
+    (void) player; (void) volume;
+}
+
+static void
+player_aout_on_mute_changed(vlc_player_t *player, bool muted, void *data)
+{
+    add_event_signal(data,
+            &(callback_info_t){ .signal = SIGNAL_VOLUME_MUTED });
+    (void) player; (void) muted;
+}
+
+static void
+player_vout_on_fullscreen_changed(vlc_player_t *player,
+                                  vout_thread_t *vout, bool enabled,
+                                  void *data)
+{
+    add_event_signal(data, &(callback_info_t){ .signal = SIGNAL_FULLSCREEN });
+    (void) player; (void) vout; (void) enabled;
 }
 
 /*****************************************************************************
- * TrackChange: callback on playlist "input-current"
+ * TrackChange: callback on playlist_on_current_index_changed
  *****************************************************************************/
 static int TrackChange( intf_thread_t *p_intf )
 {
     intf_sys_t          *p_sys      = p_intf->p_sys;
-    input_thread_t      *p_input    = NULL;
-    input_item_t        *p_item     = NULL;
 
     if( p_intf->p_sys->b_dead )
         return VLC_SUCCESS;
 
-    if( p_sys->p_input )
-    {
-        var_DelCallback( p_sys->p_input, "intf-event", InputCallback, p_intf );
-        var_DelCallback( p_sys->p_input, "can-pause", AllCallback, p_intf );
-        var_DelCallback( p_sys->p_input, "can-seek", AllCallback, p_intf );
-        vlc_object_release( p_sys->p_input );
-        p_sys->p_input = NULL;
-    }
+    p_sys->has_input = false;
 
     p_sys->b_meta_read = false;
 
-    p_input = pl_CurrentInput( p_intf );
-    if( !p_input )
-    {
-        return VLC_SUCCESS;
-    }
-
-    p_item = input_GetItem( p_input );
-    if( !p_item )
-    {
-        vlc_object_release( p_input );
+    vlc_player_t *player = vlc_playlist_GetPlayer(p_sys->playlist);
+    vlc_player_Lock(player);
+    input_item_t *item = vlc_player_GetCurrentMedia(player);
+    vlc_player_Unlock(player);
+    if( !item )
         return VLC_EGENERIC;
-    }
 
-    if( input_item_IsPreparsed( p_item ) )
+    if( input_item_IsPreparsed( item ) )
         p_sys->b_meta_read = true;
 
-    p_sys->p_input = p_input;
-    var_AddCallback( p_input, "intf-event", InputCallback, p_intf );
-    var_AddCallback( p_input, "can-pause", AllCallback, p_intf );
-    var_AddCallback( p_input, "can-seek", AllCallback, p_intf );
+    p_sys->has_input = true;
 
     return VLC_SUCCESS;
 }
@@ -1189,9 +1273,9 @@ int DemarshalSetPropertyValue( DBusMessage *p_msg, void *p_arg )
         free( psz ); \
     }
 
-int GetInputMeta( playlist_item_t *item, DBusMessageIter *args )
+int GetInputMeta(vlc_playlist_t *playlist, vlc_playlist_item_t *item, DBusMessageIter *args)
 {
-    input_item_t *p_input = item->p_input;
+    input_item_t *p_input = vlc_playlist_item_GetMedia(item);
     DBusMessageIter dict, dict_entry, variant, list;
     /** The duration of the track can be expressed in second, milli-seconds and
         ยต-seconds */
@@ -1200,7 +1284,8 @@ int GetInputMeta( playlist_item_t *item, DBusMessageIter *args )
     dbus_int64_t i_length = i_mtime / 1000;
     char *psz_trackid;
 
-    if( -1 == asprintf( &psz_trackid, MPRIS_TRACKID_FORMAT, item->i_id ) )
+    if (asprintf(&psz_trackid, MPRIS_TRACKID_FORMAT,
+                 vlc_playlist_IndexOf(playlist, item)) == -1)
         return VLC_ENOMEM;
 
     const char* ppsz_meta_items[] =
diff --git a/modules/control/dbus/dbus_common.h b/modules/control/dbus/dbus_common.h
index cce16efefd..034cc93785 100644
--- a/modules/control/dbus/dbus_common.h
+++ b/modules/control/dbus/dbus_common.h
@@ -31,6 +31,8 @@
 
 #include <vlc_common.h>
 #include <vlc_interface.h>
+#include <vlc_player.h>
+#include <vlc_playlist.h>
 #include <dbus/dbus.h>
 
 #define DBUS_MPRIS_OBJECT_PATH "/org/mpris/MediaPlayer2"
@@ -38,7 +40,7 @@
 /* MACROS */
 
 #define INTF ((intf_thread_t *)p_this)
-#define PL   (INTF->p_sys->p_playlist)
+#define PL   (INTF->p_sys->playlist)
 
 #define DBUS_METHOD( method_function ) \
     static DBusHandlerResult method_function \
@@ -86,12 +88,17 @@
 #define ADD_INT64( i ) DBUS_ADD( DBUS_TYPE_INT64, i )
 #define ADD_BYTE( b ) DBUS_ADD( DBUS_TYPE_BYTE, b )
 
-#define MPRIS_TRACKID_FORMAT "/org/videolan/vlc/playlist/%d"
+#define MPRIS_TRACKID_FORMAT "/org/videolan/vlc/playlist/%lu"
 
 struct intf_sys_t
 {
+    vlc_playlist_t              *playlist;
+    vlc_playlist_listener_id    *playlist_listener;
+    vlc_player_listener_id      *player_listener;
+    vlc_player_aout_listener_id *player_aout_listener;
+    vlc_player_vout_listener_id *player_vout_listener;
+
     DBusConnection *p_conn;
-    playlist_t     *p_playlist;
     bool            b_meta_read;
     dbus_int32_t    i_player_caps;
     dbus_int32_t    i_playing_state;
@@ -103,7 +110,7 @@ struct intf_sys_t
     int             p_pipe_fds[2];
     vlc_mutex_t     lock;
     vlc_thread_t    thread;
-    input_thread_t *p_input;
+    bool            has_input;
 
     vlc_tick_t      i_last_input_pos; /* Only access from input thread */
     vlc_tick_t      i_last_input_pos_event; /* Same as above */
@@ -138,7 +145,8 @@ enum
 };
 
 int DemarshalSetPropertyValue( DBusMessage *p_msg, void *p_arg );
-int GetInputMeta( playlist_item_t *, DBusMessageIter *args );
+int GetInputMeta( vlc_playlist_t *, vlc_playlist_item_t *,
+                  DBusMessageIter *args );
 int AddProperty ( intf_thread_t *p_intf,
                   DBusMessageIter *p_container,
                   const char* psz_property_name,
diff --git a/modules/control/dbus/dbus_player.c b/modules/control/dbus/dbus_player.c
index ed1ea61147..d635387571 100644
--- a/modules/control/dbus/dbus_player.c
+++ b/modules/control/dbus/dbus_player.c
@@ -31,8 +31,6 @@
 #endif
 
 #include <vlc_common.h>
-#include <vlc_playlist_legacy.h>
-#include <vlc_input.h>
 #include <vlc_interface.h>
 
 #include <math.h>
@@ -43,17 +41,13 @@
 static int
 MarshalPosition( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    /* returns position in microseconds */
+    /* returns time in microseconds */
     dbus_int64_t i_pos;
-    input_thread_t *p_input = pl_CurrentInput( p_intf );
-
-    if( !p_input )
-        i_pos = 0;
-    else
-    {
-        i_pos = US_FROM_VLC_TICK(var_GetInteger( p_input, "time" ));
-        vlc_object_release( p_input );
-    }
+    vlc_player_t *player = vlc_playlist_GetPlayer(p_intf->p_sys->playlist);
+    vlc_player_Lock(player);
+    i_pos = vlc_player_GetTime(player);
+    vlc_player_Unlock(player);
+    i_pos = i_pos == VLC_TICK_INVALID ? 0 : US_FROM_VLC_TICK(i_pos);
 
     if( !dbus_message_iter_append_basic( container, DBUS_TYPE_INT64, &i_pos ) )
         return VLC_ENOMEM;
@@ -62,15 +56,13 @@ MarshalPosition( intf_thread_t *p_intf, DBusMessageIter *container )
 }
 
 DBUS_METHOD( SetPosition )
-{ /* set position in microseconds */
+{ /* set time in microseconds */
 
     REPLY_INIT;
     dbus_int64_t i_pos;
     const char *psz_trackid;
-    playlist_t *playlist = pl_Get(p_this);
-    playlist_item_t *item;
-    input_thread_t *input = NULL;
-    int i_id;
+    ssize_t i_item_id;
+    size_t i_id;
 
     DBusError error;
     dbus_error_init( &error );
@@ -91,17 +83,15 @@ DBUS_METHOD( SetPosition )
     if( sscanf( psz_trackid, MPRIS_TRACKID_FORMAT, &i_id ) < 1 )
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
-    playlist_Lock( playlist );
-    item = playlist_CurrentPlayingItem( playlist );
-    if( item != NULL && item->i_id == i_id )
-        input = playlist_CurrentInputLocked( playlist );
-    playlist_Unlock( playlist );
-
-    if( input != NULL )
+    vlc_playlist_t *playlist = PL;
+    vlc_playlist_Lock(playlist);
+    i_item_id = vlc_playlist_GetCurrentIndex( playlist );
+    if (i_item_id != -1 && (size_t)i_item_id == i_id)
     {
-        var_SetInteger( input, "time", VLC_TICK_FROM_US(i_pos) );
-        vlc_object_release( input );
+        vlc_player_t *player = vlc_playlist_GetPlayer(playlist);
+        vlc_player_SetTime(player, VLC_TICK_FROM_US(i_pos));
     }
+    vlc_playlist_Unlock(playlist);
 
     REPLY_SEND;
 }
@@ -126,15 +116,10 @@ DBUS_METHOD( Seek )
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     }
 
-    input_thread_t *p_input = pl_CurrentInput( p_this );
-    if( p_input && var_GetBool( p_input, "can-seek" ) )
-    {
-        vlc_tick_t i_pos = var_GetInteger( p_input, "time" ) + i_step;
-        var_SetInteger( p_input, "time", (i_pos >= 0) ? VLC_TICK_FROM_US(i_pos) : 0 );
-    }
-
-    if( p_input )
-        vlc_object_release( p_input );
+    vlc_player_t *player = vlc_playlist_GetPlayer(PL);
+    vlc_player_Lock(player);
+    vlc_player_JumpTime(player, VLC_TICK_FROM_US(i_step));
+    vlc_player_Unlock(player);
 
     REPLY_SEND;
 }
@@ -142,13 +127,12 @@ DBUS_METHOD( Seek )
 static int
 MarshalVolume( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    float f_vol = playlist_VolumeGet( p_intf->p_sys->p_playlist );
-    if( f_vol < 0.f )
-        f_vol = 1.f; /* ? */
+    vlc_player_t *player = vlc_playlist_GetPlayer(p_intf->p_sys->playlist);
+    double vol = vlc_player_aout_GetVolume(player);
+    if( vol < .0f )
+        vol = .0f;
 
-    double d_vol = f_vol;
-
-    if( !dbus_message_iter_append_basic( container, DBUS_TYPE_DOUBLE, &d_vol ) )
+    if( !dbus_message_iter_append_basic( container, DBUS_TYPE_DOUBLE, &vol ) )
         return VLC_ENOMEM;
 
     return VLC_SUCCESS;
@@ -162,7 +146,8 @@ DBUS_METHOD( VolumeSet )
     if( VLC_SUCCESS != DemarshalSetPropertyValue( p_from, &d_dbus_vol ) )
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
-    playlist_VolumeSet( PL, fmaxf( d_dbus_vol, 0.f ) );
+    vlc_player_t *player = vlc_playlist_GetPlayer(PL);
+    vlc_player_aout_SetVolume(player, fmaxf(d_dbus_vol, .0f));
 
     REPLY_SEND;
 }
@@ -170,42 +155,63 @@ DBUS_METHOD( VolumeSet )
 DBUS_METHOD( Next )
 { /* next playlist item */
     REPLY_INIT;
-    playlist_Next( PL );
+    vlc_playlist_t *playlist = PL;
+    vlc_playlist_Lock(playlist);
+    vlc_playlist_Next(playlist);
+    vlc_playlist_Unlock(playlist);
     REPLY_SEND;
 }
 
 DBUS_METHOD( Prev )
 { /* previous playlist item */
     REPLY_INIT;
-    playlist_Prev( PL );
+    vlc_playlist_t *playlist = PL;
+    vlc_playlist_Lock(playlist);
+    vlc_playlist_Prev(playlist);
+    vlc_playlist_Unlock(playlist);
     REPLY_SEND;
 }
 
 DBUS_METHOD( Stop )
 { /* stop playing */
     REPLY_INIT;
-    playlist_Stop( PL );
+    vlc_playlist_t *playlist = PL;
+    vlc_playlist_Lock(playlist);
+    vlc_playlist_Stop(playlist);
+    vlc_playlist_Unlock(playlist);
     REPLY_SEND;
 }
 
 DBUS_METHOD( Play )
 {
     REPLY_INIT;
-    playlist_Play( PL );
+    vlc_player_t *player = vlc_playlist_GetPlayer(PL);
+    vlc_player_Lock(player);
+    if (vlc_player_IsPaused(player))
+        vlc_player_Resume(player);
+    else
+        vlc_player_Start(player);
+    vlc_player_Unlock(player);
     REPLY_SEND;
 }
 
 DBUS_METHOD( Pause )
 {
     REPLY_INIT;
-    playlist_Pause( PL );
+    vlc_playlist_t *playlist = PL;
+    vlc_playlist_Lock(playlist);
+    vlc_playlist_Pause(playlist);
+    vlc_playlist_Unlock(playlist);
     REPLY_SEND;
 }
 
 DBUS_METHOD( PlayPause )
 {
     REPLY_INIT;
-    playlist_TogglePause( PL );
+    vlc_player_t *player = vlc_playlist_GetPlayer(PL);
+    vlc_player_Lock(player);
+    vlc_player_TogglePause(player);
+    vlc_player_Unlock(player);
     REPLY_SEND;
 }
 
@@ -229,7 +235,18 @@ DBUS_METHOD( OpenUri )
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     }
 
-    playlist_Add( PL, psz_mrl, true );
+    input_item_t *item = input_item_New(psz_mrl, NULL);
+    if (!item)
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    vlc_playlist_t *playlist = PL;
+    vlc_playlist_Lock(playlist);
+    size_t count = vlc_playlist_Count(playlist);
+    vlc_playlist_InsertOne(playlist, count, item);
+    vlc_playlist_PlayAt(playlist, count);
+    vlc_playlist_Unlock(playlist);
+
+    input_item_Release(item);
 
     REPLY_SEND;
 }
@@ -237,9 +254,18 @@ DBUS_METHOD( OpenUri )
 static int
 MarshalCanGoNext( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    VLC_UNUSED( p_intf );
+    vlc_playlist_t *playlist = p_intf->p_sys->playlist;
+    vlc_playlist_Lock(playlist);
+    size_t count = vlc_playlist_Count(playlist);
+    ssize_t index = vlc_playlist_GetCurrentIndex(playlist);
+    enum vlc_playlist_playback_repeat repeat_mode =
+        vlc_playlist_GetPlaybackRepeat(playlist);
+    vlc_playlist_Unlock(playlist);
 
-    dbus_bool_t b_can_go_next = TRUE;
+    dbus_bool_t b_can_go_next =
+        count != 0 &&
+        (index != -1 && (size_t)index < count - 1 ||
+         repeat_mode != VLC_PLAYLIST_PLAYBACK_REPEAT_NONE);
 
     if( !dbus_message_iter_append_basic( container, DBUS_TYPE_BOOLEAN,
                                          &b_can_go_next ) )
@@ -251,9 +277,17 @@ MarshalCanGoNext( intf_thread_t *p_intf, DBusMessageIter *container )
 static int
 MarshalCanGoPrevious( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    VLC_UNUSED( p_intf );
+    vlc_playlist_t *playlist = p_intf->p_sys->playlist;
+    vlc_playlist_Lock(playlist);
+    size_t count = vlc_playlist_Count(playlist);
+    ssize_t index = vlc_playlist_GetCurrentIndex(playlist);
+    enum vlc_playlist_playback_repeat repeat_mode =
+        vlc_playlist_GetPlaybackRepeat(playlist);
+    vlc_playlist_Unlock(playlist);
 
-    dbus_bool_t b_can_go_previous = TRUE;
+    dbus_bool_t b_can_go_previous =
+        count != 0 &&
+        (index > 0 || repeat_mode != VLC_PLAYLIST_PLAYBACK_REPEAT_NONE);
 
     if( !dbus_message_iter_append_basic( container, DBUS_TYPE_BOOLEAN,
                                          &b_can_go_previous ) )
@@ -265,11 +299,10 @@ MarshalCanGoPrevious( intf_thread_t *p_intf, DBusMessageIter *container )
 static int
 MarshalCanPlay( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    playlist_t *p_playlist = p_intf->p_sys->p_playlist;
-
-    PL_LOCK;
-    dbus_bool_t b_can_play = !playlist_IsEmpty( p_playlist );
-    PL_UNLOCK;
+    vlc_playlist_t *playlist = p_intf->p_sys->playlist;
+    vlc_playlist_Lock(playlist);
+    dbus_bool_t b_can_play = vlc_playlist_Count(playlist) != 0;
+    vlc_playlist_Unlock(playlist);
 
     if( !dbus_message_iter_append_basic( container, DBUS_TYPE_BOOLEAN,
                                          &b_can_play ) )
@@ -281,14 +314,10 @@ MarshalCanPlay( intf_thread_t *p_intf, DBusMessageIter *container )
 static int
 MarshalCanPause( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    dbus_bool_t b_can_pause = FALSE;
-    input_thread_t *p_input = pl_CurrentInput( p_intf );
-
-    if( p_input )
-    {
-        b_can_pause = var_GetBool( p_input, "can-pause" );
-        vlc_object_release( p_input );
-    }
+    vlc_player_t *player = vlc_playlist_GetPlayer(p_intf->p_sys->playlist);
+    vlc_player_Lock(player);
+    dbus_bool_t b_can_pause = vlc_player_CanPause(player);
+    vlc_player_Unlock(player);
 
     if( !dbus_message_iter_append_basic( container, DBUS_TYPE_BOOLEAN,
                                          &b_can_pause ) )
@@ -313,14 +342,10 @@ MarshalCanControl( intf_thread_t *p_intf, DBusMessageIter *container )
 static int
 MarshalCanSeek( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    dbus_bool_t b_can_seek = FALSE;
-    input_thread_t *p_input = pl_CurrentInput( p_intf );
-
-    if( p_input )
-    {
-        b_can_seek = var_GetBool( p_input, "can-seek" );
-        vlc_object_release( p_input );
-    }
+    vlc_player_t *player = vlc_playlist_GetPlayer(p_intf->p_sys->playlist);
+    vlc_player_Lock(player);
+    dbus_bool_t b_can_seek = vlc_player_CanSeek(player);
+    vlc_player_Unlock(player);
 
     if( !dbus_message_iter_append_basic( container, DBUS_TYPE_BOOLEAN,
                                          &b_can_seek ) )
@@ -332,8 +357,13 @@ MarshalCanSeek( intf_thread_t *p_intf, DBusMessageIter *container )
 static int
 MarshalShuffle( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    dbus_bool_t b_shuffle = var_GetBool( p_intf->p_sys->p_playlist, "random" );
+    vlc_playlist_t *playlist = p_intf->p_sys->playlist;
+    vlc_playlist_Lock(playlist);
+    enum vlc_playlist_playback_order order_mode =
+        vlc_playlist_GetPlaybackOrder(playlist);
+    vlc_playlist_Unlock(playlist);
 
+    dbus_bool_t b_shuffle = order_mode == VLC_PLAYLIST_PLAYBACK_ORDER_RANDOM;
     if( !dbus_message_iter_append_basic( container, DBUS_TYPE_BOOLEAN,
                                          &b_shuffle ))
         return VLC_ENOMEM;
@@ -349,7 +379,12 @@ DBUS_METHOD( ShuffleSet )
     if( VLC_SUCCESS != DemarshalSetPropertyValue( p_from, &b_shuffle ) )
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
-    var_SetBool( PL, "random", ( b_shuffle == TRUE ) );
+    vlc_playlist_t *playlist = PL;
+    vlc_playlist_Lock(playlist);
+    vlc_playlist_SetPlaybackOrder(playlist, b_shuffle == TRUE
+            ? VLC_PLAYLIST_PLAYBACK_ORDER_RANDOM
+            : VLC_PLAYLIST_PLAYBACK_ORDER_NORMAL);
+    vlc_playlist_Unlock(playlist);
 
     REPLY_SEND;
 }
@@ -357,28 +392,24 @@ DBUS_METHOD( ShuffleSet )
 static int
 MarshalPlaybackStatus( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    input_thread_t *p_input = pl_CurrentInput( p_intf );
-    const char *psz_playback_status;
+    vlc_player_t *player = vlc_playlist_GetPlayer(p_intf->p_sys->playlist);
+    vlc_player_Lock(player);
+    enum vlc_player_state state = vlc_player_GetState(player);
+    vlc_player_Unlock(player);
 
-    if( p_input != NULL )
+    const char *psz_playback_status;
+    switch (state)
     {
-        switch( var_GetInteger( p_input, "state" ) )
-        {
-            case OPENING_S:
-            case PLAYING_S:
-                psz_playback_status = PLAYBACK_STATUS_PLAYING;
-                break;
-            case PAUSE_S:
-                psz_playback_status = PLAYBACK_STATUS_PAUSED;
-                break;
-            default:
-                psz_playback_status = PLAYBACK_STATUS_STOPPED;
-        }
-
-        vlc_object_release( (vlc_object_t*) p_input );
+        case VLC_PLAYER_STATE_STARTED:
+        case VLC_PLAYER_STATE_PLAYING:
+            psz_playback_status = PLAYBACK_STATUS_PLAYING;
+            break;
+        case VLC_PLAYER_STATE_PAUSED:
+            psz_playback_status = PLAYBACK_STATUS_PAUSED;
+            break;
+        default:
+            psz_playback_status = PLAYBACK_STATUS_STOPPED;
     }
-    else
-        psz_playback_status = PLAYBACK_STATUS_STOPPED;
 
     if( !dbus_message_iter_append_basic( container, DBUS_TYPE_STRING,
                                          &psz_playback_status ) )
@@ -390,16 +421,10 @@ MarshalPlaybackStatus( intf_thread_t *p_intf, DBusMessageIter *container )
 static int
 MarshalRate( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    double d_rate;
-    input_thread_t *p_input = pl_CurrentInput( p_intf );
-
-    if( p_input != NULL )
-    {
-        d_rate = var_GetFloat( p_input, "rate" );
-        vlc_object_release( (vlc_object_t*) p_input );
-    }
-    else
-        d_rate = 1.0;
+    vlc_player_t *player = vlc_playlist_GetPlayer(p_intf->p_sys->playlist);
+    vlc_player_Lock(player);
+    double d_rate = vlc_player_GetRate(player);
+    vlc_player_Unlock(player);
 
     if( !dbus_message_iter_append_basic( container, DBUS_TYPE_DOUBLE,
                                          &d_rate ) )
@@ -417,14 +442,10 @@ DBUS_METHOD( RateSet )
     if( VLC_SUCCESS != DemarshalSetPropertyValue( p_from, &d_rate ) )
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
-    input_thread_t *p_input = pl_CurrentInput( p_this );
-    if( p_input != NULL )
-    {
-        var_SetFloat( p_input, "rate", (float) d_rate );
-        vlc_object_release( (vlc_object_t*) p_input );
-    }
-    else
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+    vlc_player_t *player = vlc_playlist_GetPlayer(PL);
+    vlc_player_Lock(player);
+    vlc_player_ChangeRate(player, d_rate);
+    vlc_player_Unlock(player);
 
     REPLY_SEND;
 }
@@ -456,16 +477,27 @@ MarshalMaximumRate( intf_thread_t *p_intf, DBusMessageIter *container )
 static int
 MarshalLoopStatus( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    const char *psz_loop_status;
-
-    if( var_GetBool( p_intf->p_sys->p_playlist, "repeat" ) )
-        psz_loop_status = LOOP_STATUS_TRACK;
+    vlc_playlist_t *playlist = p_intf->p_sys->playlist;
+    vlc_playlist_Lock(playlist);
+    enum vlc_playlist_playback_repeat repeat_mode =
+        vlc_playlist_GetPlaybackRepeat(playlist);
+    vlc_playlist_Unlock(playlist);
 
-    else if( var_GetBool( p_intf->p_sys->p_playlist, "loop" ) )
-        psz_loop_status = LOOP_STATUS_PLAYLIST;
-
-    else
-        psz_loop_status = LOOP_STATUS_NONE;
+    const char *psz_loop_status;
+    switch (repeat_mode)
+    {
+        case VLC_PLAYLIST_PLAYBACK_REPEAT_ALL:
+            psz_loop_status = LOOP_STATUS_PLAYLIST;
+            break;
+        case VLC_PLAYLIST_PLAYBACK_REPEAT_CURRENT:
+            psz_loop_status = LOOP_STATUS_TRACK;
+            break;
+        case VLC_PLAYLIST_PLAYBACK_REPEAT_NONE:
+            psz_loop_status = LOOP_STATUS_NONE;
+            break;
+        default:
+            vlc_assert_unreachable();
+    }
 
     if( !dbus_message_iter_append_basic( container, DBUS_TYPE_STRING,
                                          &psz_loop_status ) )
@@ -482,50 +514,45 @@ DBUS_METHOD( LoopStatusSet )
     if( VLC_SUCCESS != DemarshalSetPropertyValue( p_from, &psz_loop_status ) )
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
-    if( !strcmp( psz_loop_status, LOOP_STATUS_NONE ) )
-    {
-        var_SetBool( PL, "loop",   FALSE );
-        var_SetBool( PL, "repeat", FALSE );
-    }
-    else if( !strcmp( psz_loop_status, LOOP_STATUS_TRACK ) )
-    {
-        var_SetBool( PL, "loop",   FALSE );
-        var_SetBool( PL, "repeat", TRUE  );
-    }
-    else if( !strcmp( psz_loop_status, LOOP_STATUS_PLAYLIST ) )
-    {
-        var_SetBool( PL, "loop",   TRUE );
-        var_SetBool( PL, "repeat", FALSE  );
-    }
+    enum vlc_playlist_playback_repeat repeat_mode;
+    if (!strcmp(psz_loop_status, LOOP_STATUS_NONE))
+        repeat_mode = VLC_PLAYLIST_PLAYBACK_REPEAT_NONE;
+    else if (!strcmp(psz_loop_status, LOOP_STATUS_TRACK))
+        repeat_mode = VLC_PLAYLIST_PLAYBACK_REPEAT_CURRENT;
+    else if (!strcmp(psz_loop_status, LOOP_STATUS_PLAYLIST))
+        repeat_mode = VLC_PLAYLIST_PLAYBACK_REPEAT_ALL;
     else
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
+    vlc_playlist_t *playlist = PL;
+    vlc_playlist_Lock(playlist);
+    vlc_playlist_SetPlaybackRepeat(playlist, repeat_mode);
+    vlc_playlist_Unlock(playlist);
+
     REPLY_SEND;
 }
 
 static int
 MarshalMetadata( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    playlist_t *playlist = pl_Get( p_intf );
-    playlist_item_t *item;
     int result = VLC_SUCCESS;
-
-    playlist_Lock( playlist );
-    item = playlist_CurrentPlayingItem( playlist );
-
-    if( item != NULL )
-        result = GetInputMeta( item, container );
+    vlc_playlist_t *playlist = p_intf->p_sys->playlist;
+    vlc_playlist_Lock(playlist);
+    ssize_t id = vlc_playlist_GetCurrentIndex(playlist);
+    if(id != -1)
+    {
+        vlc_playlist_item_t *plitem = vlc_playlist_Get(playlist, id);
+        result = GetInputMeta(playlist, plitem, container);
+    }
     else
     {   // avoid breaking the type marshalling
         DBusMessageIter a;
-
         if( !dbus_message_iter_open_container( container, DBUS_TYPE_ARRAY,
                                                "{sv}", &a ) ||
             !dbus_message_iter_close_container( container, &a ) )
             result = VLC_ENOMEM;
     }
-
-    playlist_Unlock( playlist );
+    vlc_playlist_Unlock(playlist);
     return result;
 }
 
@@ -543,13 +570,11 @@ DBUS_SIGNAL( SeekedSignal )
 
     dbus_int64_t i_pos = 0;
     intf_thread_t *p_intf = (intf_thread_t*) p_data;
-    input_thread_t *p_input = pl_CurrentInput( p_intf );
-
-    if( p_input )
-    {
-        i_pos = US_FROM_VLC_TICK(var_GetInteger( p_input, "time" ));
-        vlc_object_release( p_input );
-    }
+    vlc_player_t *player = vlc_playlist_GetPlayer(p_intf->p_sys->playlist);
+    vlc_player_Lock(player);
+    i_pos = vlc_player_GetTime(player);
+    vlc_player_Unlock(player);
+    i_pos = i_pos == VLC_TICK_INVALID ? 0 : US_FROM_VLC_TICK(i_pos);
 
     ADD_INT64( &i_pos );
     SIGNAL_SEND;
diff --git a/modules/control/dbus/dbus_root.c b/modules/control/dbus/dbus_root.c
index 8c5bdeb7a0..2d998178e1 100644
--- a/modules/control/dbus/dbus_root.c
+++ b/modules/control/dbus/dbus_root.c
@@ -32,10 +32,8 @@
 
 #include <vlc_common.h>
 #include <vlc_interface.h>
-#include <vlc_input.h>
 #include <vlc_vout.h>
 #include <vlc_plugin.h>
-#include <vlc_playlist_legacy.h>
 
 #include <unistd.h>
 #include <limits.h>
@@ -88,26 +86,10 @@ MarshalIdentity( intf_thread_t *p_intf, DBusMessageIter *container )
 
 static int
 MarshalCanSetFullscreen( intf_thread_t *p_intf, DBusMessageIter *container )
-{
-    input_thread_t *p_input = NULL;
-    dbus_bool_t     b_ret   = FALSE;
-
-    if (p_intf->p_sys->p_input)
-    {
-        p_input = (input_thread_t*) vlc_object_hold( p_intf->p_sys->p_input );
-        vout_thread_t* p_vout = input_GetVout( p_input );
-        vlc_object_release( p_input );
-
-        if ( p_vout )
-        {
-            b_ret = TRUE;
-            vlc_object_release( p_vout );
-        }
-    }
-
+{ VLC_UNUSED(p_intf);
+    dbus_bool_t b_ret = TRUE;
     if (!dbus_message_iter_append_basic( container, DBUS_TYPE_BOOLEAN, &b_ret ))
         return VLC_ENOMEM;
-
     return VLC_SUCCESS;
 }
 
@@ -115,16 +97,11 @@ static int
 MarshalFullscreen( intf_thread_t *p_intf, DBusMessageIter *container )
 {
     dbus_bool_t b_fullscreen;
-
-    if ( p_intf->p_sys->p_playlist )
-        b_fullscreen = var_GetBool( p_intf->p_sys->p_playlist , "fullscreen" );
-    else
-        b_fullscreen = FALSE;
-
+    vlc_player_t *player = vlc_playlist_GetPlayer(p_intf->p_sys->playlist);
+    b_fullscreen = vlc_player_vout_IsFullscreen(player);
     if (!dbus_message_iter_append_basic( container,
             DBUS_TYPE_BOOLEAN, &b_fullscreen ))
         return VLC_ENOMEM;
-
     return VLC_SUCCESS;
 }
 
@@ -132,22 +109,12 @@ DBUS_METHOD( FullscreenSet )
 {
     REPLY_INIT;
     dbus_bool_t b_fullscreen;
-    input_thread_t *p_input = NULL;
 
     if( VLC_SUCCESS != DemarshalSetPropertyValue( p_from, &b_fullscreen ) )
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
-    if (INTF->p_sys->p_input)
-    {
-        p_input = (input_thread_t*) vlc_object_hold( INTF->p_sys->p_input );
-        vout_thread_t* p_vout = input_GetVout( p_input );
-        vlc_object_release( p_input );
-
-        if ( p_vout )
-            var_SetBool( p_vout, "fullscreen", ( b_fullscreen == TRUE ) );
-        if ( PL )
-            var_SetBool( PL , "fullscreen", ( b_fullscreen == TRUE ) );
-    }
+    vlc_player_t *player = vlc_playlist_GetPlayer(PL);
+    vlc_player_vout_SetFullscreen(player, b_fullscreen);
 
     REPLY_SEND;
 }
@@ -268,7 +235,7 @@ DBUS_METHOD( Quit )
 DBUS_METHOD( Raise )
 {/* shows vlc's main window */
     REPLY_INIT;
-    var_TriggerCallback( pl_Get(INTF), "intf-show" );
+    var_TriggerCallback(INTF->obj.libvlc, "intf-show" );
     REPLY_SEND;
 }
 
diff --git a/modules/control/dbus/dbus_tracklist.c b/modules/control/dbus/dbus_tracklist.c
index 606e204b76..9aacabd44a 100644
--- a/modules/control/dbus/dbus_tracklist.c
+++ b/modules/control/dbus/dbus_tracklist.c
@@ -31,8 +31,6 @@
 #endif
 
 #include <vlc_common.h>
-#include <vlc_playlist_legacy.h>
-#include <vlc_input.h>
 
 #include <assert.h>
 
@@ -49,8 +47,8 @@ DBUS_METHOD( AddTrack )
     char *psz_mrl, *psz_aftertrack;
     dbus_bool_t b_play;
 
-    int i_input_id = -1;
-    int i_pos = PLAYLIST_END;
+    bool b_append = false;
+    size_t i_pos;
 
     size_t i_append_len  = sizeof( DBUS_MPRIS_APPEND );
     size_t i_notrack_len = sizeof( DBUS_MPRIS_NOTRACK );
@@ -71,49 +69,32 @@ DBUS_METHOD( AddTrack )
     }
 
     if( !strncmp( DBUS_MPRIS_APPEND, psz_aftertrack, i_append_len ) )
-        ;
+        b_append = true;
     else if( !strncmp( DBUS_MPRIS_NOTRACK, psz_aftertrack, i_notrack_len ) )
         i_pos = 0;
-    else if( 1 == sscanf( psz_aftertrack, MPRIS_TRACKID_FORMAT, &i_input_id ) )
+    else if(sscanf( psz_aftertrack, MPRIS_TRACKID_FORMAT, &i_pos) == 1)
         ;
     else
     {
         msg_Warn( (vlc_object_t *) p_this,
                 "AfterTrack: Invalid track ID \"%s\", appending instead",
                 psz_aftertrack );
-        i_pos = PLAYLIST_END;
+        b_append = true;
     }
 
     input_item_t *item = input_item_New( psz_mrl, NULL );
     if( unlikely(item == NULL) )
         return DBUS_HANDLER_RESULT_NEED_MEMORY;
 
-    playlist_t *p_playlist = PL;
-    playlist_item_t *node, *plitem;
-
-    PL_LOCK;
-    node = p_playlist->p_playing;
-
-    if( i_input_id != -1 )
-    {
-        playlist_item_t *prev = playlist_ItemGetById( p_playlist, i_input_id );
-        if( prev != NULL )
-        {
-            node = prev->p_parent;
-            for( i_pos = 0; i_pos < node->i_children; i_pos++ )
-                if( node->pp_children[i_pos] == prev )
-                {
-                    i_pos++;
-                    break;
-                }
-        }
-    }
-
-    plitem = playlist_NodeAddInput( p_playlist, item, node, i_pos );
-    if( likely(plitem != NULL) && b_play )
-        playlist_ViewPlay( p_playlist, NULL, plitem );
-
-    PL_UNLOCK;
+    vlc_playlist_t *playlist = PL;
+    vlc_playlist_Lock(playlist);
+    size_t count = vlc_playlist_Count(playlist);
+    if (b_append || i_pos > count)
+        i_pos = count;
+    vlc_playlist_InsertOne(playlist, i_pos, item);
+    if (b_play)
+        vlc_playlist_PlayAt(playlist, i_pos);
+    vlc_playlist_Unlock(playlist);
 
     input_item_Release( item );
 
@@ -125,10 +106,10 @@ DBUS_METHOD( GetTracksMetadata )
     REPLY_INIT;
     OUT_ARGUMENTS;
 
-    int i_track_id = -1;
+    size_t i_track_id;
     const char *psz_track_id = NULL;
 
-    playlist_t   *p_playlist = PL;
+    vlc_playlist_t *playlist = PL;
 
     DBusMessageIter in_args, track_ids, meta;
     dbus_message_iter_init( p_from, &in_args );
@@ -148,25 +129,24 @@ DBUS_METHOD( GetTracksMetadata )
         dbus_message_iter_get_basic( &track_ids, &psz_track_id );
 
         if( 1 != sscanf( psz_track_id, MPRIS_TRACKID_FORMAT, &i_track_id ) )
+            goto invalid_track_id;
+
+        vlc_playlist_Lock(playlist);
+        bool id_valid = i_track_id < vlc_playlist_Count(playlist);
+        if (id_valid)
         {
+            vlc_playlist_item_t *item = vlc_playlist_Get(playlist, i_track_id);
+            GetInputMeta(playlist, item, &meta);
+        }
+        vlc_playlist_Unlock(playlist);
+        if (!id_valid)
+        {
+invalid_track_id:
             msg_Err( (vlc_object_t*) p_this, "Invalid track id: %s",
                                              psz_track_id );
             continue;
         }
 
-        PL_LOCK;
-        for( int i = 0; i < p_playlist->current.i_size; i++ )
-        {
-            playlist_item_t *item = p_playlist->current.p_elems[i];
-
-            if( item->i_id == i_track_id )
-            {
-                GetInputMeta( item, &meta );
-                break;
-            }
-        }
-        PL_UNLOCK;
-
         dbus_message_iter_next( &track_ids );
     }
 
@@ -178,9 +158,8 @@ DBUS_METHOD( GoTo )
 {
     REPLY_INIT;
 
-    int i_track_id = -1;
+    size_t i_track_id;
     const char *psz_track_id = NULL;
-    playlist_t *p_playlist = PL;
 
     DBusError error;
     dbus_error_init( &error );
@@ -198,26 +177,22 @@ DBUS_METHOD( GoTo )
     }
 
     if( 1 != sscanf( psz_track_id, MPRIS_TRACKID_FORMAT, &i_track_id ) )
-    {
-        msg_Err( (vlc_object_t*) p_this, "Invalid track id %s", psz_track_id );
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-    }
+        goto invalid_track_id;
 
-    PL_LOCK;
-
-    for( int i = 0; i < p_playlist->current.i_size; i++ )
-    {
-        playlist_item_t *item = p_playlist->current.p_elems[i];
+    vlc_playlist_t *playlist = PL;
+    vlc_playlist_Lock(playlist);
+    bool id_valid = i_track_id < vlc_playlist_Count(playlist);
+    if (id_valid)
+        vlc_playlist_PlayAt(playlist, i_track_id);
+    vlc_playlist_Unlock(playlist);
+    if (!id_valid)
+        goto invalid_track_id;
 
-        if( item->i_id == i_track_id )
-        {
-            playlist_ViewPlay( p_playlist, item->p_parent, item );
-            break;
-        }
-    }
-
-    PL_UNLOCK;
     REPLY_SEND;
+
+invalid_track_id:
+    msg_Err( (vlc_object_t*) p_this, "Invalid track id %s", psz_track_id );
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
 DBUS_METHOD( RemoveTrack )
@@ -227,9 +202,8 @@ DBUS_METHOD( RemoveTrack )
     DBusError error;
     dbus_error_init( &error );
 
-    int   i_id = -1;
+    size_t i_id;
     char *psz_id = NULL;
-    playlist_t *p_playlist = PL;
 
     dbus_message_get_args( p_from, &error,
             DBUS_TYPE_OBJECT_PATH, &psz_id,
@@ -244,52 +218,44 @@ DBUS_METHOD( RemoveTrack )
     }
 
     if( 1 != sscanf( psz_id, MPRIS_TRACKID_FORMAT, &i_id ) )
-    {
-        msg_Err( (vlc_object_t*) p_this, "Invalid track id: %s", psz_id );
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-    }
-
-    PL_LOCK;
+        goto invalid_track_id;
 
-    for( int i = 0; i < p_playlist->current.i_size; i++ )
-    {
-        playlist_item_t *item = p_playlist->current.p_elems[i];
-
-        if( item->i_id == i_id )
-        {
-            playlist_NodeDelete( p_playlist, item );
-            break;
-        }
-    }
+    vlc_playlist_t *playlist = PL;
+    vlc_playlist_Lock(playlist);
+    bool valid_id = i_id < vlc_playlist_Count(playlist);
+    if (valid_id)
+        vlc_playlist_RemoveOne(playlist, i_id);
+    vlc_playlist_Unlock(playlist);
+    if (!valid_id)
+        goto invalid_track_id;
 
-    PL_UNLOCK;
     REPLY_SEND;
+
+invalid_track_id:
+    msg_Err( (vlc_object_t*) p_this, "Invalid track id: %s", psz_id );
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
 static int
 MarshalTracks( intf_thread_t *p_intf, DBusMessageIter *container )
 {
     DBusMessageIter tracks;
-    char         *psz_track_id = NULL;
-    playlist_t   *p_playlist   = p_intf->p_sys->p_playlist;
+    char *psz_track_id = NULL;
+    vlc_playlist_t *playlist = p_intf->p_sys->playlist;
 
     dbus_message_iter_open_container( container, DBUS_TYPE_ARRAY, "o",
                                       &tracks );
 
-    PL_LOCK;
-
-    for( int i = 0; i < p_playlist->current.i_size; i++ )
+    vlc_playlist_Lock(playlist);
+    size_t pl_size = vlc_playlist_Count(playlist);
+    vlc_playlist_Unlock(playlist);
+    for (size_t i = 0; i < pl_size; i++)
     {
-        playlist_item_t *item = p_playlist->current.p_elems[i];
-
-        if( ( -1 == asprintf( &psz_track_id,
-                              MPRIS_TRACKID_FORMAT,
-                              item->i_id ) ) ||
+        if (asprintf(&psz_track_id, MPRIS_TRACKID_FORMAT, i) == -1 ||
             !dbus_message_iter_append_basic( &tracks,
                                              DBUS_TYPE_OBJECT_PATH,
                                              &psz_track_id ) )
         {
-            PL_UNLOCK;
             dbus_message_iter_abandon_container( container, &tracks );
             return VLC_ENOMEM;
         }
@@ -297,8 +263,6 @@ MarshalTracks( intf_thread_t *p_intf, DBusMessageIter *container )
         free( psz_track_id );
     }
 
-    PL_UNLOCK;
-
     if( !dbus_message_iter_close_container( container, &tracks ) )
         return VLC_ENOMEM;
 
-- 
2.19.1



More information about the vlc-devel mailing list