[vlc-devel] [PATCH 2/2] remove vlc_playlist_legacy

Thomas Guillem thomas at gllm.fr
Tue Apr 16 16:28:28 CEST 2019


---
 include/vlc_interface.h                  |   8 -
 include/vlc_playlist_legacy.h            | 429 -----------
 lib/media.c                              |   1 -
 lib/playlist.c                           |   2 -
 modules/gui/qt/dialogs/epg.cpp           |   1 -
 po/POTFILES.in                           |  10 -
 src/Makefile.am                          |  13 -
 src/check_symbols                        |   1 -
 src/input/meta.c                         |   1 -
 src/interface/interface.c                |  36 -
 src/libvlc-module.c                      |   1 -
 src/libvlc.c                             |   2 -
 src/libvlccore.sym                       |   1 -
 src/playlist_legacy/aout.c               | 124 ----
 src/playlist_legacy/control.c            | 147 ----
 src/playlist_legacy/engine.c             | 501 -------------
 src/playlist_legacy/item.c               | 883 -----------------------
 src/playlist_legacy/loadsave.c           |  67 --
 src/playlist_legacy/playlist_internal.h  | 186 -----
 src/playlist_legacy/renderer.c           |  51 --
 src/playlist_legacy/search.c             | 130 ----
 src/playlist_legacy/services_discovery.c | 242 -------
 src/playlist_legacy/sort.c               | 376 ----------
 src/playlist_legacy/thread.c             | 525 --------------
 src/playlist_legacy/tree.c               | 427 -----------
 25 files changed, 4165 deletions(-)
 delete mode 100644 include/vlc_playlist_legacy.h
 delete mode 100644 src/playlist_legacy/aout.c
 delete mode 100644 src/playlist_legacy/control.c
 delete mode 100644 src/playlist_legacy/engine.c
 delete mode 100644 src/playlist_legacy/item.c
 delete mode 100644 src/playlist_legacy/loadsave.c
 delete mode 100644 src/playlist_legacy/playlist_internal.h
 delete mode 100644 src/playlist_legacy/renderer.c
 delete mode 100644 src/playlist_legacy/search.c
 delete mode 100644 src/playlist_legacy/services_discovery.c
 delete mode 100644 src/playlist_legacy/sort.c
 delete mode 100644 src/playlist_legacy/thread.c
 delete mode 100644 src/playlist_legacy/tree.c

diff --git a/include/vlc_interface.h b/include/vlc_interface.h
index 66331e3a99..a396c1fa96 100644
--- a/include/vlc_interface.h
+++ b/include/vlc_interface.h
@@ -91,8 +91,6 @@ VLC_API int intf_Create( libvlc_int_t *, const char * );
 
 VLC_API void libvlc_Quit( libvlc_int_t * );
 
-VLC_API playlist_t *pl_Get( struct intf_thread_t *intf );
-
 /**
  * Recover the main playlist from an interface module
  *
@@ -101,12 +99,6 @@ VLC_API playlist_t *pl_Get( struct intf_thread_t *intf );
 VLC_API vlc_playlist_t *
 vlc_intf_GetMainPlaylist(intf_thread_t *intf);
 
-/**
- * Retrieves the current input thread from the playlist.
- * @note The returned object must be released with input_Release().
- */
-#define pl_CurrentInput(intf) (playlist_CurrentInput(pl_Get(intf)))
-
 /**
  * @ingroup messages
  * @{
diff --git a/include/vlc_playlist_legacy.h b/include/vlc_playlist_legacy.h
deleted file mode 100644
index 8f4521e7af..0000000000
--- a/include/vlc_playlist_legacy.h
+++ /dev/null
@@ -1,429 +0,0 @@
-/*****************************************************************************
- * vlc_playlist_legacy.h : Legacy playlist functions
- *****************************************************************************
- * Copyright (C) 1999-2004 VLC authors and VideoLAN
- *
- * Authors: Samuel Hocevar <sam at zoy.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifndef VLC_PLAYLIST_LEGACY_H_
-#define VLC_PLAYLIST_LEGACY_H_
-
-# ifdef __cplusplus
-extern "C" {
-# endif
-
-#include <vlc_events.h>
-
-TYPEDEF_ARRAY(playlist_item_t*, playlist_item_array_t)
-
-struct intf_thread_t;
-
-/**
- * \defgroup playlist_legacy VLC playlist legacy
- * \ingroup interface
- * VLC playlist controls
- * @{
- * \file
- * VLC playlist control interface
- *
- * The VLC playlist system has a tree structure. This allows advanced
- * categorization, like for SAP streams (which are grouped by "sap groups").
- *
- * The base structure for all playlist operations is the playlist_item_t.
- * This is essentially a node within the playlist tree. Each playlist item
- * references an input_item_t which contains the input stream info, such as
- * location, name and meta-data.
- *
- * A playlist item is uniquely identified by its input item:
- * \ref playlist_ItemGetByInput(). A single input item cannot be used by more
- * than one playlist item at a time; if necessary, a copy of the input item can
- * be made instead.
- *
- * The same playlist tree is visible to all user interfaces. To arbitrate
- * access, a lock is used, see \ref playlist_Lock() and \ref playlist_Unlock().
- *
- * Under the playlist root item node, the top-level items are the main
- * media sources and include:
- * - the actual playlist,
- * - the service discovery root node, whose children are services discovery
- *   module instances.
- *
- * So, here is an example:
- * \verbatim
- * Inputs array
- *  - input 1 -> name = foo 1 uri = ...
- *  - input 2 -> name = foo 2 uri = ...
- *
- * Playlist items tree
- * - playlist (id 1)
- *    - category 1 (id 2)
- *      - foo 2 (id 6 - input 2)
- * \endverbatim
- *
- * Sometimes, an item creates subitems. This happens for the directory access
- * for example. In that case, if the item is under the "playlist" top-level
- * item and playlist is configured to be flat then the item will be deleted and
- * replaced with new subitems. If the item is under another top-level item, it
- * will be transformed to a node and removed from the list of all items without
- * nodes.
- *
- * For "standard" item addition, you can use playlist_Add(), playlist_AddExt()
- * (more options) or playlist_AddInput() if you already created your input
- * item. This will add the item at the root of "Playlist" in each of the two trees.
- *
- * You can create nodes with playlist_NodeCreate() and can create items from
- * existing input items to be placed under any node with
- * playlist_NodeAddInput().
- *
- * To delete an item, use playlist_NodeDelete( p_item ).
- *
- * The playlist defines the following event variables:
- *
- * - "item-change": It will contain a pointer to the input_item_t of a
- * changed input item monitored by the playlist.
- *
- * - "playlist-item-append": It will contain a pointer to a playlist_item_t.
- * - "playlist-item-deleted": It will contain a pointer to the playlist_item_t
- * about to be deleted.
- *
- * - "leaf-to-parent": It will contain the playlist_item_t->i_id of an item that is transformed
- *   into a node.
- *
- * The playlist contains rate-variable which is propagated to current input if
- * available also rate-slower/rate-faster is in use.
- */
-
-/** Helper structure to export to file part of the playlist */
-typedef struct playlist_export_t
-{
-    struct vlc_object_t obj;
-    char *base_url;
-    FILE *p_file;
-    playlist_item_t *p_root;
-} playlist_export_t;
-
-/** playlist item / node */
-struct playlist_item_t
-{
-    input_item_t           *p_input;    /**< Linked input item */
-
-    playlist_item_t      **pp_children; /**< Children nodes/items */
-    playlist_item_t       *p_parent;    /**< Item parent */
-    int                    i_children;  /**< Number of children, -1 if not a node */
-    unsigned               i_nb_played; /**< Times played */
-
-    int                    i_id;        /**< Playlist item specific id */
-    uint8_t                i_flags;     /**< Flags \see playlist_item_flags_e */
-};
-
-typedef enum {
-    PLAYLIST_DBL_FLAG          = 0x04,  /**< Is it disabled ? */
-    PLAYLIST_RO_FLAG           = 0x08,  /**< Write-enabled ? */
-    PLAYLIST_SUBITEM_STOP_FLAG = 0x40,  /**< Must playlist stop if the item gets subitems ?*/
-    PLAYLIST_NO_INHERIT_FLAG   = 0x80,  /**< Will children inherit flags the R/O flag ? */
-} playlist_item_flags_e;
-
-/** Playlist status */
-typedef enum
-{ PLAYLIST_STOPPED,PLAYLIST_RUNNING,PLAYLIST_PAUSED } playlist_status_t;
-
-/** Structure containing information about the playlist */
-struct playlist_t
-{
-    struct vlc_object_t obj;
-
-    playlist_item_array_t items; /**< Arrays of items */
-
-    playlist_item_array_t current; /**< Items currently being played */
-    int                   i_current_index; /**< Index in current array */
-
-    /* Predefined items */
-    playlist_item_t  root;
-    playlist_item_t *p_playing;
-};
-
-/* A bit of macro magic to generate an enum out of the following list,
- * and later, to generate a list of static functions out of the same list.
- * There is also SORT_RANDOM, which is always last and handled specially.
- */
-#define VLC_DEFINE_SORT_FUNCTIONS \
-    DEF( SORT_ID )\
-    DEF( SORT_TITLE )\
-    DEF( SORT_TITLE_NODES_FIRST )\
-    DEF( SORT_ARTIST )\
-    DEF( SORT_GENRE )\
-    DEF( SORT_DURATION )\
-    DEF( SORT_TITLE_NUMERIC )\
-    DEF( SORT_ALBUM )\
-    DEF( SORT_TRACK_NUMBER )\
-    DEF( SORT_DESCRIPTION )\
-    DEF( SORT_RATING )\
-    DEF( SORT_URI )\
-    DEF( SORT_DISC_NUMBER )\
-    DEF( SORT_DATE )
-
-#define DEF( s ) s,
-enum
-{
-    VLC_DEFINE_SORT_FUNCTIONS
-    SORT_RANDOM,
-    NUM_SORT_FNS=SORT_RANDOM
-};
-#undef  DEF
-#ifndef VLC_INTERNAL_PLAYLIST_SORT_FUNCTIONS
-#undef  VLC_DEFINE_SORT_FUNCTIONS
-#endif
-
-enum
-{
-    ORDER_NORMAL = 0,
-    ORDER_REVERSE = 1,
-};
-
-#define PLAYLIST_END           -1
-
-enum pl_locked_state
-{
-    pl_Locked = true,
-    pl_Unlocked = false
-};
-
-/*****************************************************************************
- * Prototypes
- *****************************************************************************/
-
-/* Helpers */
-#define PL_LOCK playlist_Lock( p_playlist )
-#define PL_UNLOCK playlist_Unlock( p_playlist )
-#define PL_ASSERT_LOCKED assert(playlist_Locked(p_playlist))
-
-/** Playlist commands */
-enum {
-    PLAYLIST_PLAY,      /**< No arg.                            res=can fail*/
-    PLAYLIST_VIEWPLAY,  /**< arg1= playlist_item_t*,*/
-                        /**  arg2 = playlist_item_t*          , res=can fail */
-    PLAYLIST_TOGGLE_PAUSE, /**< No arg                          res=can fail */
-    PLAYLIST_STOP,      /**< No arg                             res=can fail*/
-    PLAYLIST_SKIP,      /**< arg1=int,                          res=can fail*/
-    PLAYLIST_PAUSE,     /**< No arg */
-    PLAYLIST_RESUME,    /**< No arg */
-};
-
-#define playlist_Play(p) playlist_Control(p,PLAYLIST_PLAY, pl_Unlocked )
-#define playlist_TogglePause(p) \
-        playlist_Control(p, PLAYLIST_TOGGLE_PAUSE, pl_Unlocked)
-#define playlist_Stop(p) playlist_Control(p,PLAYLIST_STOP, pl_Unlocked )
-#define playlist_Next(p) playlist_Control(p,PLAYLIST_SKIP, pl_Unlocked, 1)
-#define playlist_Prev(p) playlist_Control(p,PLAYLIST_SKIP, pl_Unlocked, -1)
-#define playlist_Skip(p,i) playlist_Control(p,PLAYLIST_SKIP, pl_Unlocked,  (i) )
-#define playlist_Pause(p) \
-        playlist_Control(p, PLAYLIST_PAUSE, pl_Unlocked)
-#define playlist_Resume(p) \
-        playlist_Control(p, PLAYLIST_RESUME, pl_Unlocked)
-
-/**
- * Locks the playlist.
- *
- * This function locks the playlist. While the playlist is locked, no other
- * thread can modify the playlist tree layout or current playing item and node.
- *
- * Locking the playlist is necessary before accessing, either for reading or
- * writing, any playlist item.
- *
- * \note Because of the potential for lock inversion / deadlocks, locking the
- * playlist shall not be attemped while holding an input item lock. An input
- * item lock can be acquired while holding the playlist lock.
- *
- * While holding the playlist lock, a thread shall not attempt to:
- * - probe, initialize or deinitialize a module or a plugin,
- * - install or deinstall a variable or event callback,
- * - set a variable or trigger a variable callback, with the sole exception
- *   of the playlist core triggering add/remove/leaf item callbacks,
- * - invoke a module/plugin callback other than:
- *   - playlist export,
- *   - logger message callback.
- */
-VLC_API void playlist_Lock( playlist_t * );
-
-/**
- * Unlocks the playlist.
- *
- * This function unlocks the playlist, allowing other threads to lock it. The
- * calling thread must have called playlist_Lock() before.
- *
- * This function invalidates all or any playlist item pointers.
- * There are no ways to ensure that playlist items are not modified or deleted
- * by another thread past this function call.
- *
- * To retain a reference to a playlist item while not holding the playlist
- * lock, a thread should take a reference to the input item within the
- * playlist item before unlocking. If this is not practical, then the thread
- * can store the playlist item ID (i_id) before unlocking.
- * Either way, this will not ensure that the playlist item is not deleted, so
- * the thread must be ready to handle that case later when calling
- * playlist_ItemGetByInput() or playlist_ItemGetById().
- *
- * Furthermore, if ID is used, then the playlist item might be deleted, and
- * another item could be assigned the same ID. To avoid that problem, use
- * the input item instead of the ID.
- */
-VLC_API void playlist_Unlock( playlist_t * );
-
-VLC_API bool playlist_Locked( const playlist_t * );
-#define playlist_AssertLocked(pl) (assert(playlist_Locked(pl)), pl)
-
-VLC_API void playlist_Deactivate( playlist_t * );
-
-/**
- * Do a playlist action.
- * If there is something in the playlist then you can do playlist actions.
- * Possible queries are listed in vlc_common.h
- * \param p_playlist the playlist to do the command on
- * \param i_query the command to do
- * \param b_locked TRUE if playlist is locked when entering this function
- * \param variable number of arguments
- */
-VLC_API void playlist_Control( playlist_t *p_playlist, int i_query, int b_locked, ...  );
-
-static inline void playlist_ViewPlay(playlist_t *pl, playlist_item_t *node,
-                                     playlist_item_t *item)
-{
-    playlist_Control(pl, PLAYLIST_VIEWPLAY, pl_Locked, node, item);
-}
-
-/** Get current playing input. The object is retained.
- */
-VLC_API input_thread_t * playlist_CurrentInput( playlist_t *p_playlist ) VLC_USED;
-VLC_API input_thread_t *playlist_CurrentInputLocked( playlist_t *p_playlist ) VLC_USED;
-
-/** Get the duration of all items in a node.
- */
-VLC_API vlc_tick_t playlist_GetNodeDuration( playlist_item_t * );
-
-/** Clear the playlist
- * \param b_locked TRUE if playlist is locked when entering this function
- */
-VLC_API void playlist_Clear( playlist_t *, bool );
-
-/* Playlist sorting */
-VLC_API int playlist_TreeMove( playlist_t *, playlist_item_t *, playlist_item_t *, int );
-VLC_API int playlist_TreeMoveMany( playlist_t *, int, playlist_item_t **, playlist_item_t *, int );
-VLC_API int playlist_RecursiveNodeSort( playlist_t *, playlist_item_t *,int, int );
-
-VLC_API playlist_item_t * playlist_CurrentPlayingItem( playlist_t * ) VLC_USED;
-VLC_API int playlist_Status( playlist_t * );
-
-/**
- * Export a node of the playlist to a certain type of playlistfile
- * \param psz_filename the location where the exported file will be saved
- * \param psz_type the type of playlist file to create (m3u, pls, ..)
- * \return VLC_SUCCESS on success
- */
-VLC_API int playlist_Export( playlist_t *p_playlist, const char *psz_name,
-                             const char *psz_type );
-
-/**
- * Open a playlist file, add its content to the current playlist
- */
-VLC_API int playlist_Import( playlist_t *p_playlist, const char *psz_file );
-
-/********************** Services discovery ***********************/
-
-/** Add a service discovery module */
-VLC_API int playlist_ServicesDiscoveryAdd(playlist_t *, const char *);
-/** Remove a services discovery module by name */
-VLC_API int playlist_ServicesDiscoveryRemove(playlist_t *, const char *);
-/** Check whether a given SD is loaded */
-VLC_API bool playlist_IsServicesDiscoveryLoaded( playlist_t *,const char *) VLC_DEPRECATED;
-/** Query a services discovery */
-VLC_API int playlist_ServicesDiscoveryControl( playlist_t *, const char *, int, ... );
-
-/********************** Renderer ***********************/
-/**
- * Sets a renderer or remove the current one
- * @param p_item    The renderer item to be used, or NULL to disable the current
- *                  one. If a renderer is provided, its reference count will be
- *                  incremented.
- */
-VLC_API int playlist_SetRenderer( playlist_t* p_pl, vlc_renderer_item_t* p_item );
-
-
-/********************************************************
- * Item management
- ********************************************************/
-
-/******************** Item addition ********************/
-VLC_API int playlist_Add( playlist_t *, const char *, bool );
-VLC_API int playlist_AddExt( playlist_t *, const char *, const char *, bool, int, const char *const *, unsigned );
-VLC_API int playlist_AddInput( playlist_t *, input_item_t *, bool );
-VLC_API playlist_item_t * playlist_NodeAddInput( playlist_t *, input_item_t *, playlist_item_t *, int );
-VLC_API int playlist_NodeAddCopy( playlist_t *, playlist_item_t *, playlist_item_t *, int );
-
-/********************************** Item search *************************/
-VLC_API playlist_item_t * playlist_ItemGetById(playlist_t *, int ) VLC_USED;
-VLC_API playlist_item_t *playlist_ItemGetByInput(playlist_t *,
-                                                 const input_item_t * )
-VLC_USED;
-
-VLC_API int playlist_LiveSearchUpdate(playlist_t *, playlist_item_t *, const char *, bool );
-
-/********************************************************
- * Tree management
- ********************************************************/
-/* Node management */
-VLC_API playlist_item_t * playlist_NodeCreate( playlist_t *, const char *, playlist_item_t * p_parent, int i_pos, int i_flags );
-VLC_API playlist_item_t * playlist_ChildSearchName(playlist_item_t*, const char* ) VLC_USED;
-VLC_API void playlist_NodeDelete( playlist_t *, playlist_item_t * );
-
-/**************************
- * Audio output management
- **************************/
-
-VLC_API struct audio_output *playlist_GetAout( playlist_t * );
-
-VLC_API float playlist_VolumeGet( playlist_t * );
-VLC_API int playlist_VolumeSet( playlist_t *, float );
-VLC_API int playlist_VolumeUp( playlist_t *, int, float * );
-#define playlist_VolumeDown(a, b, c) playlist_VolumeUp(a, -(b), c)
-VLC_API int playlist_MuteSet( playlist_t *, bool );
-VLC_API int playlist_MuteGet( playlist_t * );
-
-static inline int playlist_MuteToggle( playlist_t *pl )
-{
-    int val = playlist_MuteGet( pl );
-    if (val >= 0)
-        val = playlist_MuteSet( pl, !val );
-    return val;
-}
-
-VLC_API void playlist_EnableAudioFilter( playlist_t *, const char *, bool );
-
-/** Tell if the playlist is empty */
-#define playlist_IsEmpty(p_playlist) \
-    (playlist_AssertLocked(p_playlist)->items.i_size == 0)
-
-/** Tell the number of items in the current playing context */
-#define playlist_CurrentSize(p_playlist) \
-    (playlist_AssertLocked(p_playlist)->current.i_size)
-
-/** @} */
-# ifdef __cplusplus
-}
-# endif
-
-#endif
diff --git a/lib/media.c b/lib/media.c
index 90d9007ead..c7febc3548 100644
--- a/lib/media.c
+++ b/lib/media.c
@@ -36,7 +36,6 @@
 #include <vlc_common.h>
 #include <vlc_input.h>
 #include <vlc_meta.h>
-#include <vlc_playlist_legacy.h> /* For the preparser */
 #include <vlc_url.h>
 #include <vlc_thumbnailer.h>
 
diff --git a/lib/playlist.c b/lib/playlist.c
index 2034ac3b84..92fca47e02 100644
--- a/lib/playlist.c
+++ b/lib/playlist.c
@@ -29,8 +29,6 @@
 
 #include <vlc/vlc.h>
 
-#include <vlc_playlist_legacy.h>
-
 #include <assert.h>
 
 void libvlc_playlist_play( libvlc_instance_t *p_instance )
diff --git a/modules/gui/qt/dialogs/epg.cpp b/modules/gui/qt/dialogs/epg.cpp
index e8d50341ce..0439271556 100644
--- a/modules/gui/qt/dialogs/epg.cpp
+++ b/modules/gui/qt/dialogs/epg.cpp
@@ -28,7 +28,6 @@
 
 #include "components/epg/EPGWidget.hpp"
 #include "components/epg/EPGItem.hpp"
-#include <vlc_playlist_legacy.h>
 
 #include <QVBoxLayout>
 #include <QSplitter>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5a1ef31f25..8b78ef669e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -35,7 +35,6 @@ include/vlc_tick.h
 include/vlc_network.h
 include/vlc_objects.h
 include/vlc_pgpkey.h
-include/vlc_playlist_legacy.h
 include/vlc_plugin.h
 include/vlc_rand.h
 include/vlc_services_discovery.h
@@ -123,15 +122,6 @@ src/network/rootbind.c
 src/network/tcp.c
 src/network/tls.c
 src/network/udp.c
-src/playlist_legacy/control.c
-src/playlist_legacy/engine.c
-src/playlist_legacy/item.c
-src/playlist_legacy/loadsave.c
-src/playlist_legacy/playlist_internal.h
-src/playlist_legacy/search.c
-src/playlist_legacy/sort.c
-src/playlist_legacy/thread.c
-src/playlist_legacy/tree.c
 src/stream_output/sap.c
 src/stream_output/sdp.c
 src/stream_output/stream_output.c
diff --git a/src/Makefile.am b/src/Makefile.am
index e243f6473d..bc826dfefe 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -77,7 +77,6 @@ pluginsinclude_HEADERS = \
 	../include/vlc_picture.h \
 	../include/vlc_picture_fifo.h \
 	../include/vlc_picture_pool.h \
-	../include/vlc_playlist_legacy.h \
 	../include/vlc_player.h \
 	../include/vlc_playlist.h \
 	../include/vlc_playlist_export.h \
@@ -222,18 +221,6 @@ libvlccore_la_SOURCES = \
 	modules/textdomain.c \
 	interface/dialog.c \
 	interface/interface.c \
-	playlist_legacy/playlist_internal.h \
-	playlist_legacy/aout.c \
-	playlist_legacy/thread.c \
-	playlist_legacy/control.c \
-	playlist_legacy/engine.c \
-	playlist_legacy/sort.c \
-	playlist_legacy/loadsave.c \
-	playlist_legacy/tree.c \
-	playlist_legacy/item.c \
-	playlist_legacy/search.c \
-	playlist_legacy/services_discovery.c \
-	playlist_legacy/renderer.c \
 	playlist/content.c \
 	playlist/content.h \
 	playlist/control.c \
diff --git a/src/check_symbols b/src/check_symbols
index 5b92baa335..3c57036474 100755
--- a/src/check_symbols
+++ b/src/check_symbols
@@ -24,7 +24,6 @@ cat libvlccore.sym | grep -v \
 	-e '^us_' -e '^utf8_' -e '^xml_' -e '^GetLang_' \
 	-e '^m\(date\|sleep\|wait\)$' -e '^[A-Z][a-z]*Charset$' -e 'MD5$' \
 	-e '^NTPtime64$' -e '^secstotimestr$' \
-	-e '^pl_Get' \
 		&& exit 1
 
 echo "None found."
diff --git a/src/input/meta.c b/src/input/meta.c
index a06fbabda3..e5d829222f 100644
--- a/src/input/meta.c
+++ b/src/input/meta.c
@@ -28,7 +28,6 @@
 #include <assert.h>
 
 #include <vlc_common.h>
-#include <vlc_playlist_legacy.h>
 #include <vlc_url.h>
 #include <vlc_arrays.h>
 #include <vlc_modules.h>
diff --git a/src/interface/interface.c b/src/interface/interface.c
index ad817f19c7..ddb63e840f 100644
--- a/src/interface/interface.c
+++ b/src/interface/interface.c
@@ -41,45 +41,14 @@
 #include <vlc_common.h>
 #include <vlc_modules.h>
 #include <vlc_interface.h>
-#include <vlc_playlist_legacy.h>
 #include <vlc_playlist.h>
 #include "libvlc.h"
-#include "playlist_legacy/playlist_internal.h"
 #include "../lib/libvlc_internal.h"
 #include "input/player.h"
 
 static int AddIntfCallback( vlc_object_t *, char const *,
                             vlc_value_t , vlc_value_t , void * );
 
-/* This lock ensures that the playlist is created only once (per instance). It
- * also protects the list of running interfaces against concurrent access,
- * either to add or remove an interface.
- *
- * However, it does NOT protect from destruction of the playlist by
- * intf_DestroyAll(). Instead, care must be taken that intf_Create() and any
- * other function that depends on the playlist is only called BEFORE
- * intf_DestroyAll() has the possibility to destroy all interfaces.
- */
-static vlc_mutex_t old_playlist_lock = VLC_STATIC_MUTEX;
-static playlist_t *old_playlist = NULL;
-
-/**
- * Creates the playlist if necessary, and return a pointer to it.
- * @note The playlist is not reference-counted. So the pointer is only valid
- * until intf_DestroyAll() destroys interfaces.
- */
-playlist_t *pl_Get( struct intf_thread_t *intf )
-{
-    assert( intf );
-
-    vlc_mutex_lock(&old_playlist_lock);
-    if (old_playlist == NULL)
-        old_playlist = playlist_Create(VLC_OBJECT(intf));
-    vlc_mutex_unlock(&old_playlist_lock);
-
-    return old_playlist;
-}
-
 static void
 PlaylistConfigureFromVariables(vlc_playlist_t *playlist, vlc_object_t *obj)
 {
@@ -325,11 +294,6 @@ void intf_DestroyAll(libvlc_int_t *libvlc)
         vlc_mutex_lock(&priv->lock);
     }
     vlc_mutex_unlock(&priv->lock);
-
-    vlc_mutex_lock(&old_playlist_lock);
-    if (old_playlist)
-        playlist_Destroy(old_playlist);
-    vlc_mutex_unlock(&old_playlist_lock);
 }
 
 /* Following functions are local */
diff --git a/src/libvlc-module.c b/src/libvlc-module.c
index 958fb4014c..aeddd1844b 100644
--- a/src/libvlc-module.c
+++ b/src/libvlc-module.c
@@ -35,7 +35,6 @@
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 #include <vlc_cpu.h>
-#include <vlc_playlist_legacy.h>
 #include "libvlc.h"
 #include "modules/modules.h"
 
diff --git a/src/libvlc.c b/src/libvlc.c
index 3c18c12da6..4210acaacd 100644
--- a/src/libvlc.c
+++ b/src/libvlc.c
@@ -51,7 +51,6 @@
 
 #include "config/vlc_getopt.h"
 
-#include <vlc_playlist_legacy.h>
 #include <vlc_playlist.h>
 #include <vlc_interface.h>
 
@@ -67,7 +66,6 @@
 #include <vlc_thumbnailer.h>
 
 #include "libvlc.h"
-#include "playlist_legacy/playlist_internal.h"
 
 #include <vlc_vlm.h>
 
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index fc09ce6c37..2126d2004f 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -335,7 +335,6 @@ picture_pool_Wait
 picture_Reset
 picture_Setup
 plane_CopyPixels
-pl_Get
 playlist_Add
 playlist_AddExt
 playlist_AddInput
diff --git a/src/playlist_legacy/aout.c b/src/playlist_legacy/aout.c
deleted file mode 100644
index 5a0af675eb..0000000000
--- a/src/playlist_legacy/aout.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*****************************************************************************
- * aout.c: audio output controls for the VLC playlist
- *****************************************************************************
- * Copyright (C) 2002-2012 VLC authors and VideoLAN
- *
- * Authors: Christophe Massiot <massiot at via.ecp.fr>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <math.h>
-
-#include <vlc_common.h>
-#include <vlc_aout.h>
-#include <vlc_playlist_legacy.h>
-
-#include "../audio_output/aout_internal.h"
-#include "playlist_internal.h"
-
-audio_output_t *playlist_GetAout(playlist_t *pl)
-{
-    /* NOTE: it is assumed that the input resource exists. In practice,
-     * the playlist must have been activated. This is automatic when calling
-     * pl_Get(). FIXME: input resources are deleted at deactivation, this can
-     * be too early. */
-    playlist_private_t *sys = pl_priv(pl);
-    return input_resource_HoldAout(sys->p_input_resource);
-}
-
-float playlist_VolumeGet (playlist_t *pl)
-{
-    float volume = -1.f;
-
-    audio_output_t *aout = playlist_GetAout (pl);
-    if (aout != NULL)
-    {
-        volume = aout_VolumeGet (aout);
-        aout_Release(aout);
-    }
-    return volume;
-}
-
-int playlist_VolumeSet (playlist_t *pl, float vol)
-{
-    int ret = -1;
-
-    audio_output_t *aout = playlist_GetAout (pl);
-    if (aout != NULL)
-    {
-        ret = aout_VolumeSet (aout, vol);
-        aout_Release(aout);
-    }
-    return ret;
-}
-
-/**
- * Raises the volume.
- * \param value how much to increase (> 0) or decrease (< 0) the volume
- * \param volp if non-NULL, will contain contain the resulting volume
- */
-int playlist_VolumeUp (playlist_t *pl, int value, float *volp)
-{
-    int ret = -1;
-
-    audio_output_t *aout = playlist_GetAout (pl);
-    if (aout != NULL)
-    {
-        ret = aout_VolumeUpdate (aout, value, volp);
-        aout_Release(aout);
-    }
-    return ret;
-}
-
-int playlist_MuteGet (playlist_t *pl)
-{
-    int mute = -1;
-
-    audio_output_t *aout = playlist_GetAout (pl);
-    if (aout != NULL)
-    {
-        mute = aout_MuteGet (aout);
-        aout_Release(aout);
-    }
-    return mute;
-}
-
-int playlist_MuteSet (playlist_t *pl, bool mute)
-{
-    int ret = -1;
-
-    audio_output_t *aout = playlist_GetAout (pl);
-    if (aout != NULL)
-    {
-        ret = aout_MuteSet (aout, mute);
-        aout_Release(aout);
-    }
-    return ret;
-}
-
-void playlist_EnableAudioFilter (playlist_t *pl, const char *name, bool add)
-{
-    audio_output_t *aout = playlist_GetAout (pl);
-    if (aout)
-    {
-        aout_EnableFilter(aout, name, add);
-        aout_Release(aout);
-    }
-}
diff --git a/src/playlist_legacy/control.c b/src/playlist_legacy/control.c
deleted file mode 100644
index b1e8448436..0000000000
--- a/src/playlist_legacy/control.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*****************************************************************************
- * control.c : Handle control of the playlist & running through it
- *****************************************************************************
- * Copyright (C) 1999-2004 VLC authors and VideoLAN
- *
- * Authors: Samuel Hocevar <sam at zoy.org>
- *          Clément Stenac <zorglub at videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <vlc_common.h>
-#include "vlc_playlist_legacy.h"
-#include "playlist_internal.h"
-#include <assert.h>
-
-/*****************************************************************************
- * Playlist control
- *****************************************************************************/
-
-void playlist_Lock( playlist_t *pl )
-{
-    vlc_mutex_lock( &pl_priv(pl)->lock );
-}
-
-void playlist_Unlock( playlist_t *pl )
-{
-    vlc_mutex_unlock( &pl_priv(pl)->lock );
-}
-
-bool playlist_Locked( const playlist_t *pl )
-{
-    return vlc_mutex_marked( &pl_priv(pl)->lock );
-}
-
-static void playlist_vaControl( playlist_t *p_playlist, int i_query,
-                                bool locked, va_list args )
-{
-    PL_LOCK_IF( !locked );
-
-    if( pl_priv(p_playlist)->killed )
-        ;
-    else
-    switch( i_query )
-    {
-    case PLAYLIST_STOP:
-        pl_priv(p_playlist)->request.b_request = true;
-        pl_priv(p_playlist)->request.p_item = NULL;
-        pl_priv(p_playlist)->request.p_node = NULL;
-        break;
-
-    // Node can be null, it will keep the same. Use with care ...
-    // Item null = take the first child of node
-    case PLAYLIST_VIEWPLAY:
-    {
-        playlist_item_t *p_node = va_arg( args, playlist_item_t * );
-        playlist_item_t *p_item = va_arg( args, playlist_item_t * );
-
-        assert( locked || (p_item == NULL && p_node == NULL) );
-
-        if ( p_node == NULL )
-        {
-            p_node = get_current_status_node( p_playlist );
-            assert( p_node );
-        }
-        pl_priv(p_playlist)->request.i_skip = 0;
-        pl_priv(p_playlist)->request.b_request = true;
-        pl_priv(p_playlist)->request.p_node = p_node;
-        pl_priv(p_playlist)->request.p_item = p_item;
-        if( p_item && var_GetBool( p_playlist, "random" ) )
-            pl_priv(p_playlist)->b_reset_currently_playing = true;
-        break;
-    }
-
-    case PLAYLIST_PLAY:
-        if( pl_priv(p_playlist)->p_input == NULL )
-        {
-            pl_priv(p_playlist)->request.b_request = true;
-            pl_priv(p_playlist)->request.p_node = get_current_status_node( p_playlist );
-            pl_priv(p_playlist)->request.p_item = get_current_status_item( p_playlist );
-            pl_priv(p_playlist)->request.i_skip = 0;
-        }
-        else
-            var_SetInteger( pl_priv(p_playlist)->p_input, "state", PLAYING_S );
-        break;
-
-    case PLAYLIST_TOGGLE_PAUSE:
-        if( pl_priv(p_playlist)->p_input == NULL )
-        {
-            pl_priv(p_playlist)->request.b_request = true;
-            pl_priv(p_playlist)->request.p_node = get_current_status_node( p_playlist );
-            pl_priv(p_playlist)->request.p_item = get_current_status_item( p_playlist );
-            pl_priv(p_playlist)->request.i_skip = 0;
-        }
-        else
-        if( var_GetInteger( pl_priv(p_playlist)->p_input, "state" ) == PAUSE_S )
-            var_SetInteger( pl_priv(p_playlist)->p_input, "state", PLAYING_S );
-        else
-            var_SetInteger( pl_priv(p_playlist)->p_input, "state", PAUSE_S );
-        break;
-
-    case PLAYLIST_SKIP:
-        pl_priv(p_playlist)->request.p_node = get_current_status_node( p_playlist );
-        pl_priv(p_playlist)->request.p_item = get_current_status_item( p_playlist );
-        pl_priv(p_playlist)->request.i_skip = va_arg( args, int );
-        pl_priv(p_playlist)->request.b_request = true;
-        break;
-
-    case PLAYLIST_PAUSE:
-        if( pl_priv(p_playlist)->p_input == NULL )
-            break;
-        var_SetInteger( pl_priv(p_playlist)->p_input, "state", PAUSE_S );
-        break;
-
-    case PLAYLIST_RESUME:
-        if( pl_priv(p_playlist)->p_input == NULL )
-            break;
-        var_SetInteger( pl_priv(p_playlist)->p_input, "state", PLAYING_S );
-        break;
-    }
-    vlc_cond_signal( &pl_priv(p_playlist)->signal );
-    PL_UNLOCK_IF( !locked );
-}
-
-void playlist_Control( playlist_t *p_playlist, int query, int locked, ... )
-{
-    va_list args;
-
-    va_start( args, locked );
-    playlist_vaControl( p_playlist, query, (bool)locked, args );
-    va_end( args );
-}
diff --git a/src/playlist_legacy/engine.c b/src/playlist_legacy/engine.c
deleted file mode 100644
index c68502c1a2..0000000000
--- a/src/playlist_legacy/engine.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/*****************************************************************************
- * engine.c : Run the playlist and handle its control
- *****************************************************************************
- * Copyright (C) 1999-2008 VLC authors and VideoLAN
- *
- * Authors: Samuel Hocevar <sam at zoy.org>
- *          Clément Stenac <zorglub at videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stddef.h>
-#include <assert.h>
-
-#include <vlc_common.h>
-#include <vlc_arrays.h>
-#include <vlc_sout.h>
-#include <vlc_playlist_legacy.h>
-#include <vlc_interface.h>
-#include <vlc_http.h>
-#include <vlc_renderer_discovery.h>
-#include "playlist_internal.h"
-#include "input/resource.h"
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static void VariablesInit( playlist_t *p_playlist );
-
-static int RandomCallback( vlc_object_t *p_this, char const *psz_cmd,
-                           vlc_value_t oldval, vlc_value_t newval, void *a )
-{
-    (void)psz_cmd; (void)oldval; (void)newval; (void)a;
-    playlist_t *p_playlist = (playlist_t*)p_this;
-    bool random = newval.b_bool;
-
-    PL_LOCK;
-
-    if( !random ) {
-        pl_priv(p_playlist)->b_reset_currently_playing = true;
-        vlc_cond_signal( &pl_priv(p_playlist)->signal );
-    } else {
-        /* Shuffle and sync the playlist on activation of random mode.
-         * This preserves the current playing item, so that the user
-         * can return to it if needed. (See #4472)
-         */
-        playlist_private_t *p_sys = pl_priv(p_playlist);
-        playlist_item_t *p_new = p_sys->status.p_item;
-        ResetCurrentlyPlaying( p_playlist, NULL );
-        if( p_new )
-            ResyncCurrentIndex( p_playlist, p_new );
-    }
-
-    PL_UNLOCK;
-    return VLC_SUCCESS;
-}
-
-/**
- * When there are one or more pending corks, playback should be paused.
- * This is used for audio policy.
- * \warning Always add and remove a cork with var_IncInteger() and var_DecInteger().
- * var_Get() and var_Set() are prone to race conditions.
- */
-static int CorksCallback( vlc_object_t *obj, char const *var,
-                          vlc_value_t old, vlc_value_t cur, void *dummy )
-{
-    playlist_t *pl = (playlist_t *)obj;
-
-    msg_Dbg( obj, "corks count: %"PRId64" -> %"PRId64, old.i_int, cur.i_int );
-    if( !old.i_int == !cur.i_int )
-        return VLC_SUCCESS; /* nothing to do */
-
-    if( !var_InheritBool( obj, "playlist-cork" ) )
-        return VLC_SUCCESS;
-
-    playlist_Lock(pl);
-
-    if( cur.i_int )
-    {
-        bool effective = playlist_Status(pl) == PLAYLIST_RUNNING;
-
-        msg_Dbg(obj, "corked (%seffective)", effective ? "" : "in");
-        pl_priv(pl)->cork_effective = effective;
-        playlist_Control(pl, PLAYLIST_PAUSE, pl_Locked);
-    }
-    else
-    {
-        bool effective = pl_priv(pl)->cork_effective;
-
-        msg_Dbg(obj, "uncorked (%seffective)", effective ? "" : "in");
-
-        if (effective)
-            playlist_Control(pl, PLAYLIST_RESUME, pl_Locked);
-    }
-
-    playlist_Unlock(pl);
-    (void) var; (void) dummy;
-    return VLC_SUCCESS;
-}
-
-static int RateCallback( vlc_object_t *p_this, char const *psz_cmd,
-                         vlc_value_t oldval, vlc_value_t newval, void *p )
-{
-    (void)psz_cmd; (void)oldval;(void)p;
-    playlist_t *p_playlist = (playlist_t*)p_this;
-
-    PL_LOCK;
-
-    if( pl_priv(p_playlist)->p_input )
-        var_SetFloat( pl_priv( p_playlist )->p_input, "rate", newval.f_float );
-
-    PL_UNLOCK;
-    return VLC_SUCCESS;
-}
-
-static int RateOffsetCallback( vlc_object_t *obj, char const *psz_cmd,
-                               vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
-    playlist_t *p_playlist = (playlist_t *)obj;
-    VLC_UNUSED(oldval); VLC_UNUSED(p_data); VLC_UNUSED(newval);
-
-    static const float rates[] = {
-        1.0/64, 1.0/32, 1.0/16, 1.0/8, 1.0/4, 1.0/3, 1.0/2, 2.0/3,
-        1.0/1,
-        3.0/2, 2.0/1, 3.0/1, 4.0/1, 8.0/1, 16.0/1, 32.0/1, 64.0/1,
-    };
-
-    PL_LOCK;
-    input_thread_t *input = pl_priv( p_playlist )->p_input;
-    float current_rate = var_GetFloat( input ? VLC_OBJECT( input ) : obj, "rate" );
-    PL_UNLOCK;
-
-    const bool faster = !strcmp( psz_cmd, "rate-faster" );
-    float rate = current_rate * ( faster ? 1.1f : 0.9f );
-
-    /* find closest rate (if any) in the desired direction */
-    for( size_t i = 0; i < ARRAY_SIZE( rates ); ++i )
-    {
-        if( ( faster && rates[i] > rate ) ||
-            (!faster && rates[i] >= rate && i ) )
-        {
-            rate = faster ? rates[i] : rates[i-1];
-            break;
-        }
-    }
-
-    msg_Dbg( p_playlist, "adjusting rate from %f to %f (%s)",
-        current_rate, rate, faster ? "faster" : "slower" );
-
-    return var_SetFloat( p_playlist, "rate", rate );
-}
-
-static int VideoSplitterCallback( vlc_object_t *p_this, char const *psz_cmd,
-                                  vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
-    playlist_t *p_playlist = (playlist_t*)p_this;
-    VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_data); VLC_UNUSED(newval);
-
-    PL_LOCK;
-
-    /* Force the input to restart the video ES to force a vout recreation */
-    input_thread_t *p_input = pl_priv( p_playlist )->p_input;
-    if( p_input )
-    {
-        const double f_position = var_GetFloat( p_input, "position" );
-        input_Control( p_input, INPUT_RESTART_ES_BY_ID, -VIDEO_ES );
-        var_SetFloat( p_input, "position", f_position );
-    }
-
-    PL_UNLOCK;
-    return VLC_SUCCESS;
-}
-
-/**
- * Create playlist
- *
- * Create a playlist structure.
- * \param p_parent the vlc object that is to be the parent of this playlist
- * \return a pointer to the created playlist, or NULL on error
- */
-playlist_t *playlist_Create( vlc_object_t *p_parent )
-{
-    playlist_t *p_playlist;
-    playlist_private_t *p;
-
-    /* Allocate structure */
-    p = vlc_custom_create( p_parent, sizeof( *p ), "playlist" );
-    if( !p )
-        return NULL;
-
-    p_playlist = &p->public_data;
-
-    p->input_tree = NULL;
-    p->id_tree = NULL;
-
-    vlc_list_init(&p->sds);
-
-    VariablesInit( p_playlist );
-    vlc_mutex_init( &p->lock );
-    vlc_cond_init( &p->signal );
-    p->killed = false;
-
-    /* Initialise data structures */
-    pl_priv(p_playlist)->i_last_playlist_id = 0;
-    pl_priv(p_playlist)->p_input = NULL;
-
-    ARRAY_INIT( p_playlist->items );
-    ARRAY_INIT( p_playlist->current );
-
-    p_playlist->i_current_index = 0;
-    pl_priv(p_playlist)->b_reset_currently_playing = true;
-
-    pl_priv(p_playlist)->b_tree = var_InheritBool( p_parent, "playlist-tree" );
-    pl_priv(p_playlist)->b_preparse = var_InheritBool( p_parent, "auto-preparse" );
-
-    p_playlist->root.p_input = NULL;
-    p_playlist->root.pp_children = NULL;
-    p_playlist->root.i_children = 0;
-    p_playlist->root.i_nb_played = 0;
-    p_playlist->root.i_id = 0;
-    p_playlist->root.i_flags = 0;
-
-    /* Create the root, playing items nodes */
-    playlist_item_t *playing;
-
-    PL_LOCK;
-    playing = playlist_NodeCreate( p_playlist, _( "Playlist" ),
-                                   &p_playlist->root, PLAYLIST_END,
-                                   PLAYLIST_RO_FLAG|PLAYLIST_NO_INHERIT_FLAG );
-    PL_UNLOCK;
-
-    if( unlikely(playing == NULL) )
-        abort();
-
-    p_playlist->p_playing = playing;
-
-    /* Initial status */
-    pl_priv(p_playlist)->status.p_item = NULL;
-    pl_priv(p_playlist)->status.p_node = p_playlist->p_playing;
-    pl_priv(p_playlist)->request.b_request = false;
-    p->request.input_dead = false;
-
-    /* Input resources */
-    p->p_input_resource = input_resource_New( VLC_OBJECT( p_playlist ) );
-    if( unlikely(p->p_input_resource == NULL) )
-        abort();
-
-    /* Audio output (needed for volume and device controls). */
-    audio_output_t *aout = input_resource_GetAout( p->p_input_resource );
-    if( aout != NULL )
-        input_resource_PutAout( p->p_input_resource, aout );
-
-    /* Initialize the shared HTTP cookie jar */
-    vlc_value_t cookies;
-    cookies.p_address = vlc_http_cookies_new();
-    if ( likely(cookies.p_address) )
-    {
-        var_Create( p_playlist, "http-cookies", VLC_VAR_ADDRESS );
-        var_SetChecked( p_playlist, "http-cookies", VLC_VAR_ADDRESS, cookies );
-    }
-
-    /* Thread */
-    playlist_Activate (p_playlist);
-
-    /* Add service discovery modules */
-    char *mods = var_InheritString( p_playlist, "services-discovery" );
-    if( mods != NULL )
-    {
-        char *s = mods, *m;
-        while( (m = strsep( &s, " :," )) != NULL )
-            playlist_ServicesDiscoveryAdd( p_playlist, m );
-        free( mods );
-    }
-
-    return p_playlist;
-}
-
-/**
- * Destroy playlist.
- * This is not thread-safe. Any reference to the playlist is assumed gone.
- * (In particular, all interface and services threads must have been joined).
- *
- * \param p_playlist the playlist object
- */
-void playlist_Destroy( playlist_t *p_playlist )
-{
-    playlist_private_t *p_sys = pl_priv(p_playlist);
-
-    /* Remove all services discovery */
-    playlist_ServicesDiscoveryKillAll( p_playlist );
-
-    msg_Dbg( p_playlist, "destroying" );
-
-    playlist_Deactivate( p_playlist );
-
-    /* Release input resources */
-    assert( p_sys->p_input == NULL );
-    input_resource_Release( p_sys->p_input_resource );
-    if( p_sys->p_renderer )
-        vlc_renderer_item_release( p_sys->p_renderer );
-
-    PL_LOCK;
-    /* Release the current node */
-    set_current_status_node( p_playlist, NULL );
-    /* Release the current item */
-    set_current_status_item( p_playlist, NULL );
-
-    /* Destroy arrays completely - faster than one item at a time */
-    ARRAY_RESET( p_playlist->items );
-    ARRAY_RESET( p_playlist->current );
-
-    /* Remove all remaining items */
-    playlist_NodeDeleteExplicit( p_playlist, p_playlist->p_playing,
-        PLAYLIST_DELETE_FORCE );
-
-    assert( p_playlist->root.i_children <= 0 );
-    PL_UNLOCK;
-
-    vlc_cond_destroy( &p_sys->signal );
-    vlc_mutex_destroy( &p_sys->lock );
-
-    vlc_http_cookie_jar_t *cookies = var_GetAddress( p_playlist, "http-cookies" );
-    if ( cookies )
-    {
-        var_Destroy( p_playlist, "http-cookies" );
-        vlc_http_cookies_destroy( cookies );
-    }
-
-    vlc_object_delete(p_playlist);
-}
-
-/** Get current playing input.
- */
-input_thread_t *playlist_CurrentInputLocked( playlist_t *p_playlist )
-{
-    PL_ASSERT_LOCKED;
-
-    input_thread_t *p_input = pl_priv(p_playlist)->p_input;
-    if( p_input != NULL )
-        input_Hold( p_input );
-    return p_input;
-}
-
-
-/** Get current playing input.
- */
-input_thread_t * playlist_CurrentInput( playlist_t * p_playlist )
-{
-    input_thread_t * p_input;
-    PL_LOCK;
-    p_input = playlist_CurrentInputLocked( p_playlist );
-    PL_UNLOCK;
-    return p_input;
-}
-
-/**
- * @}
- */
-
-/** Accessor for status item and status nodes.
- */
-playlist_item_t * get_current_status_item( playlist_t * p_playlist )
-{
-    PL_ASSERT_LOCKED;
-
-    return pl_priv(p_playlist)->status.p_item;
-}
-
-playlist_item_t * get_current_status_node( playlist_t * p_playlist )
-{
-    PL_ASSERT_LOCKED;
-
-    return pl_priv(p_playlist)->status.p_node;
-}
-
-void set_current_status_item( playlist_t * p_playlist,
-    playlist_item_t * p_item )
-{
-    PL_ASSERT_LOCKED;
-
-    pl_priv(p_playlist)->status.p_item = p_item;
-}
-
-void set_current_status_node( playlist_t * p_playlist,
-    playlist_item_t * p_node )
-{
-    PL_ASSERT_LOCKED;
-
-    pl_priv(p_playlist)->status.p_node = p_node;
-}
-
-static void VariablesInit( playlist_t *p_playlist )
-{
-    /* These variables control updates */
-    var_Create( p_playlist, "item-change", VLC_VAR_ADDRESS );
-    var_Create( p_playlist, "leaf-to-parent", VLC_VAR_INTEGER );
-
-    var_Create( p_playlist, "playlist-item-append", VLC_VAR_ADDRESS );
-    var_Create( p_playlist, "playlist-item-deleted", VLC_VAR_ADDRESS );
-
-    var_Create( p_playlist, "input-current", VLC_VAR_ADDRESS );
-
-    /* Variables to control playback */
-    var_Create( p_playlist, "playlist-autostart", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-    var_Create( p_playlist, "random", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-    var_AddCallback( p_playlist, "random", RandomCallback, NULL );
-    var_Create( p_playlist, "repeat", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-    var_Create( p_playlist, "loop", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-    var_Create( p_playlist, "corks", VLC_VAR_INTEGER );
-    var_AddCallback( p_playlist, "corks", CorksCallback, NULL );
-
-    var_Create( p_playlist, "rate", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
-    var_AddCallback( p_playlist, "rate", RateCallback, NULL );
-    var_Create( p_playlist, "rate-slower", VLC_VAR_VOID );
-    var_AddCallback( p_playlist, "rate-slower", RateOffsetCallback, NULL );
-    var_Create( p_playlist, "rate-faster", VLC_VAR_VOID );
-    var_AddCallback( p_playlist, "rate-faster", RateOffsetCallback, NULL );
-
-    if (config_GetType("video-splitter"))
-    {
-        var_Create( p_playlist, "video-splitter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
-        var_AddCallback( p_playlist, "video-splitter", VideoSplitterCallback, NULL );
-    }
-
-    var_Create( p_playlist, "video-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
-    var_Create( p_playlist, "sub-source", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
-    var_Create( p_playlist, "sub-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
-
-    /* sout variables */
-    var_Create( p_playlist, "sout", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
-    var_Create( p_playlist, "demux-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
-
-    /* */
-    var_Create( p_playlist, "metadata-network-access", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-
-    /* Variables to preserve video output parameters */
-    var_Create( p_playlist, "fullscreen", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-    var_Create( p_playlist, "video-on-top", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-    var_Create( p_playlist, "video-wallpaper", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-
-    /* Audio output parameters */
-    var_Create( p_playlist, "audio-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
-    var_Create( p_playlist, "audio-device", VLC_VAR_STRING );
-    var_Create( p_playlist, "mute", VLC_VAR_BOOL );
-    var_Create( p_playlist, "volume", VLC_VAR_FLOAT );
-    var_SetFloat( p_playlist, "volume", -1.f );
-
-    var_Create( p_playlist, "sub-text-scale",
-               VLC_VAR_INTEGER | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND );
-
-    /* Callbacks between interfaces */
-
-    /* Create a variable for showing the right click menu */
-    var_Create( p_playlist, "intf-popupmenu", VLC_VAR_BOOL );
-
-    /* Create a variable for showing the fullscreen interface */
-    var_Create( p_playlist, "intf-toggle-fscontrol", VLC_VAR_VOID );
-
-    /* Create a variable for the Boss Key */
-    var_Create( p_playlist, "intf-boss", VLC_VAR_VOID );
-
-    /* Create a variable for showing the main interface */
-    var_Create( p_playlist, "intf-show", VLC_VAR_VOID );
-}
-
-playlist_item_t * playlist_CurrentPlayingItem( playlist_t * p_playlist )
-{
-    PL_ASSERT_LOCKED;
-
-    return pl_priv(p_playlist)->status.p_item;
-}
-
-int playlist_Status( playlist_t * p_playlist )
-{
-    input_thread_t *p_input = pl_priv(p_playlist)->p_input;
-
-    PL_ASSERT_LOCKED;
-
-    if( p_input == NULL )
-        return PLAYLIST_STOPPED;
-    if( var_GetInteger( p_input, "state" ) == PAUSE_S )
-        return PLAYLIST_PAUSED;
-    return PLAYLIST_RUNNING;
-}
-
diff --git a/src/playlist_legacy/item.c b/src/playlist_legacy/item.c
deleted file mode 100644
index 688a497337..0000000000
--- a/src/playlist_legacy/item.c
+++ /dev/null
@@ -1,883 +0,0 @@
-/*****************************************************************************
- * item.c : Playlist item creation/deletion/add/removal functions
- *****************************************************************************
- * Copyright (C) 1999-2007 VLC authors and VideoLAN
- *
- * Authors: Samuel Hocevar <sam at zoy.org>
- *          Clément Stenac <zorglub at videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <assert.h>
-#include <limits.h>
-#ifdef HAVE_SEARCH_H
-# include <search.h>
-#endif
-
-#include <vlc_common.h>
-#include <vlc_playlist_legacy.h>
-#include <vlc_rand.h>
-#include "playlist_internal.h"
-#include "libvlc.h"
-
-static void playlist_Preparse( playlist_t *, playlist_item_t * );
-
-static int RecursiveAddIntoParent (
-                playlist_t *p_playlist, playlist_item_t *p_parent,
-                input_item_node_t *p_node, int i_pos, bool b_flat,
-                playlist_item_t **pp_first_leaf );
-static int RecursiveInsertCopy (
-                playlist_t *p_playlist, playlist_item_t *p_item,
-                playlist_item_t *p_parent, int i_pos, bool b_flat );
-
-/*****************************************************************************
- * An input item has gained subitems (Event Callback)
- *****************************************************************************/
-
-static void input_item_subtree_added(input_item_t *p_input,
-                                     input_item_node_t *subtree,
-                                     void *user_data)
-{
-    playlist_t *playlist = user_data;
-    playlist_AddSubtree(playlist, p_input, subtree);
-}
-
-void playlist_AddSubtree(playlist_t *p_playlist,
-                         input_item_t *p_input, input_item_node_t *subtree)
-{
-    playlist_private_t *p_sys = pl_priv( p_playlist );
-    input_item_node_t *p_new_root = subtree;
-
-    PL_LOCK;
-
-    playlist_item_t *p_item =
-        playlist_ItemGetByInput( p_playlist, p_input );
-
-    assert( p_item != NULL );
-
-    bool b_current = get_current_status_item( p_playlist ) == p_item;
-    bool b_autostart = var_GetBool( p_playlist, "playlist-autostart" );
-    bool b_stop = p_item->i_flags & PLAYLIST_SUBITEM_STOP_FLAG;
-    bool b_flat = false;
-
-    p_item->i_flags &= ~PLAYLIST_SUBITEM_STOP_FLAG;
-
-    /* We will have to flatten the tree out if we are in "the playlist" node and
-    the user setting demands flat playlist */
-
-    if( !pl_priv(p_playlist)->b_tree ) {
-        playlist_item_t *p_up = p_item;
-        while( p_up->p_parent )
-        {
-            if( p_up->p_parent == p_playlist->p_playing )
-            {
-                b_flat = true;
-                break;
-            }
-            p_up = p_up->p_parent;
-        }
-    }
-
-    int pos = 0;
-
-    /* If we have to flatten out, then take the item's position in the parent as
-    insertion point and delete the item */
-
-    bool b_redirect_request = false;
-
-    if( b_flat )
-    {
-        playlist_item_t *p_parent = p_item->p_parent;
-        assert( p_parent != NULL );
-
-        int i;
-        for( i = 0; i < p_parent->i_children; i++ )
-        {
-            if( p_parent->pp_children[i] == p_item )
-            {
-                pos = i;
-                break;
-            }
-        }
-        assert( i < p_parent->i_children );
-
-        playlist_NodeDeleteExplicit( p_playlist, p_item, 0 );
-
-        /* If there is a pending request referring to the item we just deleted
-         * it needs to be updated so that we do not try to play an entity that
-         * is no longer part of the playlist. */
-
-        if( p_sys->request.b_request &&
-            ( p_sys->request.p_item == p_item ||
-              p_sys->request.p_node == p_item ) )
-        {
-            b_redirect_request = true;
-        }
-
-        p_item = p_parent;
-    }
-    else
-    {
-        pos = p_item->i_children >= 0 ? p_item->i_children : 0;
-    }
-
-    /* At this point:
-    "p_item" is the node where sub-items should be inserted,
-    "pos" is the insertion position in that node */
-
-    int last_pos = playlist_InsertInputItemTree( p_playlist,
-                                                 p_item,
-                                                 p_new_root,
-                                                 pos,
-                                                 b_flat );
-    if( b_redirect_request )
-    {
-        /* a redirect of the pending request is required, as such we update the
-         * request to refer to the item that would have been the next in line
-         * (if any). */
-
-        assert( b_flat );
-
-        playlist_item_t* p_redirect = NULL;
-
-        if( p_item->i_children > pos )
-            p_redirect = p_item->pp_children[pos];
-
-        p_sys->request.p_item = p_redirect;
-        p_sys->request.p_node = NULL;
-    }
-
-    if( !b_flat ) var_SetInteger( p_playlist, "leaf-to-parent", p_item->i_id );
-
-    //control playback only if it was the current playing item that got subitems
-    if( b_current )
-    {
-        if( ( b_stop && !b_flat ) || !b_autostart )
-        {
-            playlist_Control( p_playlist, PLAYLIST_STOP, pl_Locked );
-        }
-        else if( last_pos != pos ) /* any children? */
-        {
-            /* Continue to play, either random or the first new item */
-            playlist_item_t *p_play_item;
-
-            if( var_GetBool( p_playlist, "random" ) )
-            {
-                p_play_item = NULL;
-            }
-            else
-            {
-                p_play_item = p_item->pp_children[pos];
-                /* NOTE: this is a work around the general bug:
-                if node-to-be-played contains sub-nodes, then second instead
-                of first leaf starts playing (only in case the leafs have just
-                been instered and playlist has not yet been rebuilt.)
-                */
-                while( p_play_item->i_children > 0 )
-                    p_play_item = p_play_item->pp_children[0];
-            }
-
-            playlist_ViewPlay( p_playlist, NULL, p_play_item );
-        }
-        else if( b_flat && p_playlist->current.i_size > 0 )
-        {
-            /* If the playlist is flat, empty nodes are automatically deleted;
-             * meaning that moving from the current index (the index of a now
-             * removed node) to the next would result in a skip of one entry
-             * (as the empty node is deleted, the logical next item would be
-             * the one that now resides in its place).
-             *
-             * Imagine [ A, B, C, D ], where B (at index 1) is currently being
-             * played and deleted. C is the logically next item, but since the
-             * list now looks like [ A, C, D ], advancing to index 2 would mean
-             * D is played - and not C.
-             *
-             * By positioning the playlist-head at index 0 (A), when the
-             * playlist advance to the next item, C will correctly be played.
-             *
-             * Note: Of course, if the deleted item is at index 0, we should
-             * play whatever item is at position 0 since we cannot advance to
-             * index -1 (as there cannot possibly be any item there).
-             **/
-
-            if( last_pos )
-                ResetCurrentlyPlaying( p_playlist,
-                    ARRAY_VAL( p_playlist->current, last_pos - 1 ) );
-            else
-                playlist_ViewPlay( p_playlist, NULL,
-                    ARRAY_VAL( p_playlist->current, 0 ) );
-        }
-    }
-
-    PL_UNLOCK;
-}
-/*****************************************************************************
- * An input item's meta or duration has changed (Event Callback)
- *****************************************************************************/
-static void input_item_changed( const vlc_event_t * p_event,
-                                void * user_data )
-{
-    playlist_t *p_playlist = user_data;
-
-    var_SetAddress( p_playlist, "item-change", p_event->p_obj );
-}
-
-static int playlist_ItemCmpId( const void *a, const void *b )
-{
-    const playlist_item_t *pa = a, *pb = b;
-
-    /* ID are between 1 and INT_MAX, this cannot overflow. */
-    return pa->i_id - pb->i_id;
-}
-
-static int playlist_ItemCmpInput( const void *a, const void *b )
-{
-    const playlist_item_t *pa = a, *pb = b;
-
-    if( pa->p_input == pb->p_input )
-        return 0;
-    return (((uintptr_t)pa->p_input) > ((uintptr_t)pb->p_input))
-        ? +1 : -1;
-}
-
-/*****************************************************************************
- * Playlist item creation
- *****************************************************************************/
-playlist_item_t *playlist_ItemNewFromInput( playlist_t *p_playlist,
-                                              input_item_t *p_input )
-{
-    playlist_private_t *p = pl_priv(p_playlist);
-    playlist_item_t **pp, *p_item;
-
-    p_item = malloc( sizeof( playlist_item_t ) );
-    if( unlikely(p_item == NULL) )
-        return NULL;
-
-    assert( p_input );
-
-    p_item->p_input = p_input;
-    p_item->i_id = p->i_last_playlist_id;
-    p_item->p_parent = NULL;
-    p_item->i_children = (p_input->i_type == ITEM_TYPE_NODE) ? 0 : -1;
-    p_item->pp_children = NULL;
-    p_item->i_nb_played = 0;
-    p_item->i_flags = 0;
-
-    PL_ASSERT_LOCKED;
-
-    do  /* Find an unused ID for the item */
-    {
-        if( unlikely(p_item->i_id == INT_MAX) )
-            p_item->i_id = 0;
-
-        p_item->i_id++;
-
-        if( unlikely(p_item->i_id == p->i_last_playlist_id) )
-            goto error; /* All IDs taken */
-
-        pp = tsearch( p_item, &p->id_tree, playlist_ItemCmpId );
-        if( unlikely(pp == NULL) )
-            goto error;
-
-        assert( (*pp)->i_id == p_item->i_id );
-        assert( (*pp) == p_item || (*pp)->p_input != p_input );
-    }
-    while( p_item != *pp );
-
-    pp = tsearch( p_item, &p->input_tree, playlist_ItemCmpInput );
-    if( unlikely(pp == NULL) )
-    {
-        tdelete( p_item, &p->id_tree, playlist_ItemCmpId );
-        goto error;
-    }
-    /* Same input item cannot be inserted twice. */
-    assert( p_item == *pp );
-
-    p->i_last_playlist_id = p_item->i_id;
-    input_item_Hold( p_item->p_input );
-
-    vlc_event_manager_t *p_em = &p_item->p_input->event_manager;
-
-    vlc_event_attach( p_em, vlc_InputItemDurationChanged,
-                      input_item_changed, p_playlist );
-    vlc_event_attach( p_em, vlc_InputItemMetaChanged,
-                      input_item_changed, p_playlist );
-    vlc_event_attach( p_em, vlc_InputItemNameChanged,
-                      input_item_changed, p_playlist );
-    vlc_event_attach( p_em, vlc_InputItemInfoChanged,
-                      input_item_changed, p_playlist );
-    vlc_event_attach( p_em, vlc_InputItemErrorWhenReadingChanged,
-                      input_item_changed, p_playlist );
-
-    return p_item;
-
-error:
-    free( p_item );
-    return NULL;
-}
-
-/***************************************************************************
- * Playlist item destruction
- ***************************************************************************/
-
-/**
- * Release an item
- *
- * \param p_item item to delete
-*/
-void playlist_ItemRelease( playlist_t *p_playlist, playlist_item_t *p_item )
-{
-    playlist_private_t *p = pl_priv(p_playlist);
-
-    PL_ASSERT_LOCKED;
-
-    vlc_event_manager_t *p_em = &p_item->p_input->event_manager;
-
-    vlc_event_detach( p_em, vlc_InputItemMetaChanged,
-                      input_item_changed, p_playlist );
-    vlc_event_detach( p_em, vlc_InputItemDurationChanged,
-                      input_item_changed, p_playlist );
-    vlc_event_detach( p_em, vlc_InputItemNameChanged,
-                      input_item_changed, p_playlist );
-    vlc_event_detach( p_em, vlc_InputItemInfoChanged,
-                      input_item_changed, p_playlist );
-    vlc_event_detach( p_em, vlc_InputItemErrorWhenReadingChanged,
-                      input_item_changed, p_playlist );
-
-    input_item_Release( p_item->p_input );
-
-    tdelete( p_item, &p->input_tree, playlist_ItemCmpInput );
-    tdelete( p_item, &p->id_tree, playlist_ItemCmpId );
-    free( p_item->pp_children );
-    free( p_item );
-}
-
-/**
- * Finds a playlist item by ID.
- *
- * Searches for a playlist item with the given ID.
- *
- * \note The playlist must be locked, and the result is only valid until the
- * playlist is unlocked.
- *
- * \warning If an item with the given ID is deleted, it is unlikely but
- * possible that another item will get the same ID. This can result in
- * mismatches.
- * Where holding a reference to an input item is a viable option, then
- * playlist_ItemGetByInput() should be used instead - to avoid this issue.
- *
- * @param p_playlist the playlist
- * @param id ID to look for
- * @return the matching item or NULL if not found
- */
-playlist_item_t *playlist_ItemGetById( playlist_t *p_playlist , int id )
-{
-    playlist_private_t *p = pl_priv(p_playlist);
-    playlist_item_t key, **pp;
-
-    PL_ASSERT_LOCKED;
-    key.i_id = id;
-    pp = tfind( &key, &p->id_tree, playlist_ItemCmpId );
-    return (pp != NULL) ? *pp : NULL;
-}
-
-/**
- * Finds a playlist item by input item.
- *
- * Searches for a playlist item for the given input item.
- *
- * \note The playlist must be locked, and the result is only valid until the
- * playlist is unlocked.
- *
- * \param p_playlist the playlist
- * \param item input item to look for
- * \return the playlist item or NULL on failure
- */
-playlist_item_t *playlist_ItemGetByInput( playlist_t * p_playlist,
-                                          const input_item_t *item )
-{
-    playlist_private_t *p = pl_priv(p_playlist);
-    playlist_item_t key, **pp;
-
-    PL_ASSERT_LOCKED;
-    key.p_input = (input_item_t *)item;
-    pp = tfind( &key, &p->input_tree, playlist_ItemCmpInput );
-    return (pp != NULL) ? *pp : NULL;
-}
-
-/**
- * Clear the playlist
- *
- * \param p_playlist playlist object
- * \param b_locked TRUE if the playlist is locked
- * \return nothing
- */
-void playlist_Clear( playlist_t * p_playlist, bool b_locked )
-{
-    playlist_item_t *p_root = p_playlist->p_playing;
-
-    PL_LOCK_IF( !b_locked );
-
-    for( int i = p_root->i_children - 1; i >= 0 ;i-- )
-        playlist_NodeDelete( p_playlist, p_root->pp_children[i] );
-
-    PL_UNLOCK_IF( !b_locked );
-}
-
-/***************************************************************************
- * Playlist item addition
- ***************************************************************************/
-/**
- * Playlist add
- *
- * Add an item to the playlist
- * \param p_playlist the playlist to add into
- * \param psz_uri the mrl to add to the playlist
- * \param play_now whether to start playing immediately or not
- * \return VLC_SUCCESS or a VLC error code
- */
-int playlist_Add( playlist_t *p_playlist, const char *psz_uri, bool play_now )
-{
-    return playlist_AddExt( p_playlist, psz_uri, NULL, play_now,
-                            0, NULL, 0 );
-}
-
-/**
- * Add a MRL into the playlist or the media library, duration and options given
- *
- * \param p_playlist the playlist to add into
- * \param psz_uri the mrl to add to the playlist
- * \param psz_name a text giving a name or description of this item
- * \param play_now whether to start playing immediately or not
- * \param i_options the number of options
- * \param ppsz_options an array of options
- * \param i_option_flags options flags
- * \return VLC_SUCCESS or a VLC error code
-*/
-int playlist_AddExt( playlist_t *p_playlist, const char * psz_uri,
-                     const char *psz_name, bool play_now,
-                     int i_options, const char *const *ppsz_options,
-                     unsigned i_option_flags )
-{
-    input_item_t *p_input = input_item_New( psz_uri, psz_name );
-    if( !p_input )
-        return VLC_ENOMEM;
-    input_item_AddOptions( p_input, i_options, ppsz_options, i_option_flags );
-    int i_ret = playlist_AddInput( p_playlist, p_input, play_now );
-    input_item_Release( p_input );
-    return i_ret;
-}
-
-/**
- * Add an input item to the playlist node
- *
- * \param p_playlist the playlist to add into
- * \param p_input the input item to add
- * \param i_mode the mode used when adding
- * \param b_playlist TRUE for playlist, FALSE for media library
- * \return VLC_SUCCESS or VLC_ENOMEM or VLC_EGENERIC
-*/
-int playlist_AddInput( playlist_t* p_playlist, input_item_t *p_input,
-                       bool play_now)
-{
-    PL_LOCK;
-    playlist_item_t *item = p_playlist->p_playing;
-
-    item = playlist_NodeAddInput( p_playlist, p_input, item, PLAYLIST_END );
-
-    if( likely(item != NULL) && play_now )
-        playlist_ViewPlay( p_playlist, NULL, item );
-    PL_UNLOCK;
-    return (item != NULL) ? VLC_SUCCESS : VLC_ENOMEM;
-}
-
-/**
- * Add an input item to a given node
- *
- * \param p_playlist the playlist to add into
- * \param p_input the input item to add
- * \param p_parent the parent item to add into
- * \param i_pos the position in the playlist where to add. If this is
- *        PLAYLIST_END the item will be added at the end of the playlist
- *        regardless of its size
- * \return the new playlist item
- */
-playlist_item_t * playlist_NodeAddInput( playlist_t *p_playlist,
-                                         input_item_t *p_input,
-                                         playlist_item_t *p_parent, int i_pos )
-{
-    PL_ASSERT_LOCKED;
-
-    assert( p_input );
-    assert( p_parent && p_parent->i_children != -1 );
-
-    playlist_item_t *p_item = playlist_ItemNewFromInput( p_playlist, p_input );
-    if( unlikely(p_item == NULL) )
-        return NULL;
-
-    if( p_input->i_type != ITEM_TYPE_NODE )
-        ARRAY_APPEND(p_playlist->items, p_item);
-
-    playlist_NodeInsert( p_parent, p_item, i_pos );
-    playlist_SendAddNotify( p_playlist, p_item );
-    playlist_Preparse( p_playlist, p_item );
-
-    return p_item;
-}
-
-/**
- * Copy an item (and all its children, if any) into another node
- *
- * \param p_playlist the playlist to operate on
- * \param p_item the playlist item to copy
- * \param p_parent the parent item to copy into
- * \param i_pos the position in the parent item for the new copy;
- *              if this is PLAYLIST_END, the copy is appended after all
- *              parent's children
- * \return the position in parent item just behind the last new item inserted
- */
-int playlist_NodeAddCopy( playlist_t *p_playlist, playlist_item_t *p_item,
-    playlist_item_t *p_parent, int i_pos )
-{
-    PL_ASSERT_LOCKED;
-    assert( p_parent != NULL && p_item != NULL );
-    assert( p_parent->i_children > -1 );
-
-    if( i_pos == PLAYLIST_END )
-        i_pos = p_parent->i_children;
-
-    bool b_flat = false;
-
-    for( playlist_item_t* p_up = p_parent; p_up; p_up = p_up->p_parent )
-    {
-        if( p_up == p_playlist->p_playing && !pl_priv(p_playlist)->b_tree )
-            b_flat = true;
-
-        if( p_up == p_item )
-            /* TODO: We don't support copying a node into itself (yet),
-            because we insert items as we copy. Instead, we should copy
-            all items first and then insert. */
-            return i_pos;
-    }
-
-    return RecursiveInsertCopy( p_playlist, p_item, p_parent, i_pos, b_flat );
-}
-
-/**
- * Insert a tree of input items into a given playlist node
- *
- * \param p_playlist the playlist to insert into
- * \param p_parent the receiving playlist node (can be an item)
- * \param p_node the root of input item tree,
-          only it's contents will be inserted
- * \param i_pos the position in the playlist where to insert. If this is
- *        PLAYLIST_END the items will be added at the end of the playlist
- *        regardless of its size
- * \param b_flat TRUE if the new tree contents should be flattened into a list
- * \return the first new leaf inserted (in playing order)
- */
-int playlist_InsertInputItemTree (
-    playlist_t *p_playlist, playlist_item_t *p_parent,
-    input_item_node_t *p_node, int i_pos, bool b_flat )
-{
-    return RecursiveAddIntoParent( p_playlist, p_parent, p_node, i_pos, b_flat,
-                                   &(playlist_item_t*){ NULL } );
-}
-
-
-/*****************************************************************************
- * Playlist item misc operations
- *****************************************************************************/
-
-static int ItemIndex ( playlist_item_t *p_item )
-{
-    int idx;
-
-    TAB_FIND( p_item->p_parent->i_children,
-              p_item->p_parent->pp_children,
-              p_item,
-              idx );
-
-    return idx;
-}
-
-/**
- * Moves an item
- *
- * This function must be entered with the playlist lock
- *
- * \param p_playlist the playlist
- * \param p_item the item to move
- * \param p_node the new parent of the item
- * \param i_newpos the new position under this new parent
- * \return VLC_SUCCESS or an error
- */
-int playlist_TreeMove( playlist_t * p_playlist, playlist_item_t *p_item,
-                       playlist_item_t *p_node, int i_newpos )
-{
-    PL_ASSERT_LOCKED;
-
-    if( p_node->i_children == -1 ) return VLC_EGENERIC;
-
-    playlist_item_t *p_detach = p_item->p_parent;
-    int i_index = ItemIndex( p_item );
-
-    TAB_ERASE(p_detach->i_children, p_detach->pp_children, i_index);
-
-    if( p_detach == p_node && i_index < i_newpos )
-        i_newpos--;
-
-    TAB_INSERT(p_node->i_children, p_node->pp_children, p_item, i_newpos);
-    p_item->p_parent = p_node;
-
-    pl_priv( p_playlist )->b_reset_currently_playing = true;
-    vlc_cond_signal( &pl_priv( p_playlist )->signal );
-    return VLC_SUCCESS;
-}
-
-/**
- * Moves an array of items
- *
- * This function must be entered with the playlist lock
- *
- * \param p_playlist the playlist
- * \param i_items the number of indexes to move
- * \param pp_items the array of indexes to move
- * \param p_node the target node
- * \param i_newpos the target position under this node
- * \return VLC_SUCCESS or an error
- */
-int playlist_TreeMoveMany( playlist_t *p_playlist,
-                            int i_items, playlist_item_t **pp_items,
-                            playlist_item_t *p_node, int i_newpos )
-{
-    PL_ASSERT_LOCKED;
-
-    if ( p_node->i_children == -1 ) return VLC_EGENERIC;
-
-    for( int i = 0; i < i_items; i++ )
-    {
-        playlist_item_t *p_item = pp_items[i];
-        int i_index = ItemIndex( p_item );
-        playlist_item_t *p_parent = p_item->p_parent;
-        TAB_ERASE(p_parent->i_children, p_parent->pp_children, i_index);
-        if ( p_parent == p_node && i_index < i_newpos ) i_newpos--;
-    }
-    for( int i = i_items - 1; i >= 0; i-- )
-    {
-        playlist_item_t *p_item = pp_items[i];
-        TAB_INSERT(p_node->i_children, p_node->pp_children, p_item, i_newpos);
-        p_item->p_parent = p_node;
-    }
-
-    pl_priv( p_playlist )->b_reset_currently_playing = true;
-    vlc_cond_signal( &pl_priv( p_playlist )->signal );
-    return VLC_SUCCESS;
-}
-
-/**
- * Send a notification that an item has been added to a node
- *
- * \param p_playlist the playlist object
- * \param i_item_id id of the item added
- * \param i_node_id id of the node in which the item was added
- * \return nothing
- */
-void playlist_SendAddNotify( playlist_t *p_playlist, playlist_item_t *item )
-{
-    playlist_private_t *p_sys = pl_priv(p_playlist);
-    PL_ASSERT_LOCKED;
-
-    p_sys->b_reset_currently_playing = true;
-    vlc_cond_signal( &p_sys->signal );
-
-    var_SetAddress( p_playlist, "playlist-item-append", item );
-}
-
-/**
- * Get the duration of all items in a node.
- */
-vlc_tick_t playlist_GetNodeDuration( playlist_item_t* node )
-{
-    vlc_tick_t duration = input_item_GetDuration( node->p_input );
-    if( duration == INPUT_DURATION_UNSET )
-        duration = 0;
-
-    for( int i = 0; i < node->i_children; i++ )
-        duration += playlist_GetNodeDuration( node->pp_children[i] );
-
-    return duration;
-}
-
-static const input_preparser_callbacks_t input_preparser_callbacks = {
-    .on_subtree_added = input_item_subtree_added,
-};
-
-/***************************************************************************
- * The following functions are local
- ***************************************************************************/
-
-/* Enqueue an item for preparsing */
-static void playlist_Preparse( playlist_t *p_playlist,
-                               playlist_item_t *p_item )
-{
-    playlist_private_t *sys = pl_priv(p_playlist);
-    input_item_t *input = p_item->p_input;
-
-    PL_ASSERT_LOCKED;
-    /* Preparse if no artist/album info, and hasn't been preparsed already
-       and if user has some preparsing option (auto-preparse variable)
-       enabled*/
-    char *psz_artist = input_item_GetArtist( input );
-    char *psz_album = input_item_GetAlbum( input );
-
-    if( sys->b_preparse && !input_item_IsPreparsed( input )
-     && (EMPTY_STR(psz_artist) || EMPTY_STR(psz_album)) )
-        vlc_MetadataRequest( vlc_object_instance(p_playlist), input, 0,
-                             &input_preparser_callbacks, p_playlist,
-                             -1, p_item );
-    free( psz_artist );
-    free( psz_album );
-}
-
-/* Actually convert an item to a node */
-static void ChangeToNode( playlist_t *p_playlist, playlist_item_t *p_item )
-{
-    int i;
-    if( p_item->i_children != -1 ) return;
-
-    p_item->i_children = 0;
-
-    input_item_t *p_input = p_item->p_input;
-    vlc_mutex_lock( &p_input->lock );
-    p_input->i_type = ITEM_TYPE_NODE;
-    vlc_mutex_unlock( &p_input->lock );
-
-    var_SetAddress( p_playlist, "item-change", p_item->p_input );
-
-    /* Remove it from the array of available items */
-    ARRAY_BSEARCH( p_playlist->items,->i_id, int, p_item->i_id, i );
-    if( i != -1 )
-        ARRAY_REMOVE( p_playlist->items, i );
-}
-
-static int RecursiveAddIntoParent (
-    playlist_t *p_playlist, playlist_item_t *p_parent,
-    input_item_node_t *p_node, int i_pos, bool b_flat,
-    playlist_item_t **pp_first_leaf )
-{
-    *pp_first_leaf = NULL;
-
-    if( p_parent->i_children == -1 ) ChangeToNode( p_playlist, p_parent );
-
-    if( i_pos == PLAYLIST_END ) i_pos = p_parent->i_children;
-
-    for( int i = 0; i < p_node->i_children; i++ )
-    {
-        input_item_node_t *p_child_node = p_node->pp_children[i];
-
-        playlist_item_t *p_new_item = NULL;
-        bool b_children = p_child_node->i_children > 0;
-
-        //Create the playlist item represented by input node, if allowed.
-        if( !(b_flat && b_children) )
-        {
-            p_new_item = playlist_NodeAddInput( p_playlist,
-                                                p_child_node->p_item,
-                                                p_parent, i_pos );
-            if( !p_new_item ) return i_pos;
-
-            i_pos++;
-        }
-        //Recurse if any children
-        if( b_children )
-        {
-            //Substitute p_new_item for first child leaf
-            //(If flat, continue counting from current position)
-            int i_last_pos = RecursiveAddIntoParent(
-                    p_playlist,
-                    p_new_item ? p_new_item : p_parent,
-                    p_child_node,
-                    ( b_flat ? i_pos : 0 ),
-                    b_flat,
-                    &p_new_item );
-            //If flat, take position after recursion as current position
-            if( b_flat ) i_pos = i_last_pos;
-        }
-
-        assert( p_new_item != NULL );
-        if( i == 0 ) *pp_first_leaf = p_new_item;
-    }
-    return i_pos;
-}
-
-static int RecursiveInsertCopy (
-    playlist_t *p_playlist, playlist_item_t *p_item,
-    playlist_item_t *p_parent, int i_pos, bool b_flat )
-{
-    PL_ASSERT_LOCKED;
-    assert( p_parent != NULL && p_item != NULL );
-
-    if( p_item == p_parent ) return i_pos;
-
-    input_item_t *p_input = p_item->p_input;
-
-    if( p_item->i_children == -1 || !b_flat )
-    {
-        playlist_item_t *p_new_item = NULL;
-
-        if( p_item->i_children == -1 )
-        {
-            input_item_t *p_new_input = input_item_Copy( p_input );
-
-            if( likely(p_new_input != NULL) )
-            {
-                p_new_item = playlist_NodeAddInput( p_playlist, p_new_input,
-                                                    p_parent, i_pos );
-                input_item_Release( p_new_input );
-            }
-        }
-        else
-        {
-            vlc_mutex_lock( &p_input->lock );
-            p_new_item = playlist_NodeCreate( p_playlist, p_input->psz_name,
-                                              p_parent, i_pos, 0 );
-            vlc_mutex_unlock( &p_input->lock );
-        }
-        if( unlikely(p_new_item == NULL) )
-            return i_pos;
-
-        i_pos++;
-
-        if( p_new_item->i_children != -1 )
-            p_parent = p_new_item;
-    }
-
-    for( int i = 0; i < p_item->i_children; i++ )
-    {
-        if( b_flat )
-            i_pos = RecursiveInsertCopy( p_playlist, p_item->pp_children[i],
-                                         p_parent, i_pos, true );
-        else
-            RecursiveInsertCopy( p_playlist, p_item->pp_children[i],
-                                 p_parent, p_parent->i_children, false );
-    }
-
-    return i_pos;
-}
diff --git a/src/playlist_legacy/loadsave.c b/src/playlist_legacy/loadsave.c
deleted file mode 100644
index cdfa7a77bf..0000000000
--- a/src/playlist_legacy/loadsave.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*****************************************************************************
- * loadsave.c : Playlist loading / saving functions
- *****************************************************************************
- * Copyright (C) 1999-2004 VLC authors and VideoLAN
- *
- * Authors: Samuel Hocevar <sam at zoy.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <vlc_common.h>
-#include <vlc_playlist_legacy.h>
-#include <vlc_events.h>
-#include "playlist_internal.h"
-#include "config/configuration.h"
-#include <vlc_fs.h>
-#include <vlc_url.h>
-#include <vlc_modules.h>
-
-int playlist_Export( playlist_t * p_playlist, const char *psz_filename,
-                     const char *psz_type )
-{
-    (void) p_playlist; (void) psz_filename; (void) psz_type;
-    return VLC_EGENERIC;
-}
-
-int playlist_Import( playlist_t *p_playlist, const char *psz_file )
-{
-    input_item_t *p_input;
-    char *psz_uri = vlc_path2uri( psz_file, NULL );
-
-    if( psz_uri == NULL )
-        return VLC_EGENERIC;
-
-    p_input = input_item_New( psz_uri, psz_file );
-    free( psz_uri );
-
-    playlist_AddInput( p_playlist, p_input, false );
-
-    vlc_object_t *dummy = vlc_object_create( p_playlist, sizeof (*dummy) );
-    var_Create( dummy, "meta-file", VLC_VAR_VOID );
-
-    int ret = input_Read( dummy, p_input, NULL, NULL );
-
-    vlc_object_delete(dummy);
-    return ret;
-}
diff --git a/src/playlist_legacy/playlist_internal.h b/src/playlist_legacy/playlist_internal.h
deleted file mode 100644
index 81c69d8450..0000000000
--- a/src/playlist_legacy/playlist_internal.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*****************************************************************************
- * playlist_internal.h : Playlist internals
- *****************************************************************************
- * Copyright (C) 1999-2008 VLC authors and VideoLAN
- *
- * Authors: Samuel Hocevar <sam at zoy.org>
- *          Clément Stenac <zorglub at videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifndef __LIBVLC_PLAYLIST_INTERNAL_H
-# define __LIBVLC_PLAYLIST_INTERNAL_H 1
-
-/**
- * \defgroup playlist_internals VLC playlist internals
- * \ingroup playlist_legacy
- *
- * @{
- * \file
- * VLC playlist internal interface
- */
-
-#include "input/input_interface.h"
-#include <assert.h>
-
-#include "preparser/preparser.h"
-
-void playlist_ServicesDiscoveryKillAll( playlist_t *p_playlist );
-
-typedef struct playlist_private_t
-{
-    playlist_t           public_data;
-
-    void *input_tree; /**< Search tree for input item
-                           to playlist item mapping */
-    void *id_tree; /**< Search tree for item ID to item mapping */
-
-    struct vlc_list       sds;
-    input_thread_t *      p_input;  /**< the input thread associated
-                                     * with the current item */
-    input_resource_t *   p_input_resource; /**< input resources */
-    vlc_renderer_item_t *p_renderer;
-    struct {
-        /* Current status. These fields are readonly, only the playlist
-         * main loop can touch it*/
-        playlist_item_t *   p_item; /**< Currently playing/active item */
-        playlist_item_t *   p_node; /**< Current node to play from */
-    } status;
-
-    struct {
-        /* Request. Use this to give orders to the playlist main loop  */
-        playlist_item_t *   p_node;   /**< requested node to play from */
-        playlist_item_t *   p_item;   /**< requested item to play in the node */
-
-        int                 i_skip;   /**< Number of items to skip */
-
-        bool          b_request;/**< Set to true by the requester
-                                           The playlist sets it back to false
-                                           when processing the request */
-        bool input_dead; /**< Set when input has finished. */
-    } request;
-
-    vlc_thread_t thread; /**< engine thread */
-    vlc_mutex_t lock; /**< dah big playlist global lock */
-    vlc_cond_t signal; /**< wakes up the playlist engine thread */
-    bool     killed; /**< playlist is shutting down */
-    bool     cork_effective; /**< Corked while actively playing */
-
-    int      i_last_playlist_id; /**< Last id to an item */
-    bool     b_reset_currently_playing; /** Reset current item array */
-
-    bool     b_tree; /**< Display as a tree */
-    bool     b_preparse; /**< Preparse items */
-} playlist_private_t;
-
-#define pl_priv( pl ) container_of(pl, playlist_private_t, public_data)
-
-/*****************************************************************************
- * Prototypes
- *****************************************************************************/
-
-/* Creation/Deletion */
-playlist_t *playlist_Create( vlc_object_t * );
-void playlist_Destroy( playlist_t * );
-void playlist_Activate( playlist_t * );
-
-/* */
-playlist_item_t *playlist_ItemNewFromInput( playlist_t *p_playlist,
-                                            input_item_t *p_input );
-
-/* Engine */
-playlist_item_t * get_current_status_item( playlist_t * p_playlist);
-playlist_item_t * get_current_status_node( playlist_t * p_playlist );
-void set_current_status_item( playlist_t *, playlist_item_t * );
-void set_current_status_node( playlist_t *, playlist_item_t * );
-
-/**********************************************************************
- * Item management
- **********************************************************************/
-
-void playlist_SendAddNotify( playlist_t *p_playlist, playlist_item_t *item );
-
-int playlist_InsertInputItemTree ( playlist_t *,
-        playlist_item_t *, input_item_node_t *, int, bool );
-
-void playlist_AddSubtree(playlist_t *, input_item_t *, input_item_node_t *);
-
-/* Tree walking */
-int playlist_NodeInsert(playlist_item_t*, playlist_item_t *, int);
-
-/**
- * Flags for playlist_NodeDeleteExplicit
- * \defgroup playlist_NodeDeleteExplicit_flags
- * @{
- **/
-#define PLAYLIST_DELETE_FORCE 0x01 /**< delete node even if read-only */
-#define PLAYLIST_DELETE_STOP_IF_CURRENT 0x02 /**< stop playlist playback if
-                                                  node is currently the one
-                                                  played */
-/** @} */
-
-/**
- * Delete a node with explicit semantics
- *
- * This function acts like \ref playlist_NodeDelete with the advantage of the
- * caller being able control some of the semantics of the function.
- *
- * \ref p_playlist the playlist where the node is to be deleted
- * \ref p_node the node to delete
- * \ref flags a bitfield consisting of \ref playlist_NodeDeleteExplicit_flags
- **/
-void playlist_NodeDeleteExplicit(playlist_t*, playlist_item_t*,
-    int flags);
-
-void playlist_ItemRelease( playlist_t *, playlist_item_t * );
-
-void ResetCurrentlyPlaying( playlist_t *p_playlist, playlist_item_t *p_cur );
-void ResyncCurrentIndex( playlist_t *p_playlist, playlist_item_t *p_cur );
-
-playlist_item_t * playlist_GetNextLeaf( playlist_t *, playlist_item_t *p_root,
-    playlist_item_t *p_item, bool b_ena, bool b_unplayed ) VLC_USED;
-
-#define PLAYLIST_DEBUG 1
-//#undef PLAYLIST_DEBUG2
-
-#ifdef PLAYLIST_DEBUG
- #define PL_DEBUG( ... ) msg_Dbg( p_playlist, __VA_ARGS__ )
- #ifdef PLAYLIST_DEBUG2
-  #define PL_DEBUG2( msg, ... ) msg_Dbg( p_playlist, __VA_ARGS__ )
- #else
-  #define PL_DEBUG2( msg, ... ) {}
- #endif
-#else
- #define PL_DEBUG( msg, ... ) {}
- #define PL_DEBUG2( msg, ... ) {}
-#endif
-
-#define PLI_NAME( p ) p && p->p_input ? p->p_input->psz_name : "null"
-
-#define PL_LOCK_IF( cond ) pl_lock_if( p_playlist, cond )
-static inline void pl_lock_if( playlist_t * p_playlist, bool cond )
-{
-    if( cond ) PL_LOCK; else PL_ASSERT_LOCKED;
-}
-
-#define PL_UNLOCK_IF( cond ) pl_unlock_if( p_playlist, cond )
-static inline void pl_unlock_if( playlist_t * p_playlist, bool cond )
-{
-    if( cond ) PL_UNLOCK;
-}
-
-/** @} */
-#endif /* !__LIBVLC_PLAYLIST_INTERNAL_H */
diff --git a/src/playlist_legacy/renderer.c b/src/playlist_legacy/renderer.c
deleted file mode 100644
index fe5c5bde8b..0000000000
--- a/src/playlist_legacy/renderer.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*****************************************************************************
- * renderer.c : Manage renderer modules
- *****************************************************************************
- * Copyright (C) 1999-2017 VLC authors, VideoLAN and VideoLabs
- *
- * Authors: Hugo Beauzée-Luyssen <hugo at beauzee.fr>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <vlc_common.h>
-#include <vlc_playlist_legacy.h>
-#include <vlc_renderer_discovery.h>
-
-#include "playlist_internal.h"
-
-int playlist_SetRenderer( playlist_t* p_playlist, vlc_renderer_item_t* p_item )
-{
-    if( p_item )
-        vlc_renderer_item_hold( p_item );
-
-    PL_LOCK;
-
-    playlist_private_t *p_priv = pl_priv( p_playlist );
-    vlc_renderer_item_t *p_prev_renderer = p_priv->p_renderer;
-    p_priv->p_renderer = p_item;
-    if( p_priv->p_input )
-        input_Control( p_priv->p_input, INPUT_SET_RENDERER, p_item );
-
-    PL_UNLOCK;
-
-    if( p_prev_renderer )
-        vlc_renderer_item_release( p_prev_renderer );
-    return VLC_SUCCESS;
-}
diff --git a/src/playlist_legacy/search.c b/src/playlist_legacy/search.c
deleted file mode 100644
index 38c68dd5c8..0000000000
--- a/src/playlist_legacy/search.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/*****************************************************************************
- * search.c : Search functions
- *****************************************************************************
- * Copyright (C) 1999-2009 VLC authors and VideoLAN
- *
- * Authors: Clément Stenac <zorglub at videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-#include <assert.h>
-
-#include <vlc_common.h>
-#include <vlc_playlist_legacy.h>
-#include <vlc_charset.h>
-#include "playlist_internal.h"
-
-/***************************************************************************
- * Item search functions
- ***************************************************************************/
-
-/***************************************************************************
- * Live search handling
- ***************************************************************************/
-
-/**
- * Enable all items in the playlist
- * @param p_root: the current root item
- */
-static void playlist_LiveSearchClean( playlist_item_t *p_root )
-{
-    for( int i = 0; i < p_root->i_children; i++ )
-    {
-        playlist_item_t *p_item = p_root->pp_children[i];
-        if( p_item->i_children >= 0 )
-            playlist_LiveSearchClean( p_item );
-        p_item->i_flags &= ~PLAYLIST_DBL_FLAG;
-    }
-}
-
-
-/**
- * Enable/Disable items in the playlist according to the search argument
- * @param p_root: the current root item
- * @param psz_string: the string to search
- * @return true if an item match
- */
-static bool playlist_LiveSearchUpdateInternal( playlist_item_t *p_root,
-                                               const char *psz_string, bool b_recursive )
-{
-    int i;
-    bool b_match = false;
-    for( i = 0 ; i < p_root->i_children ; i ++ )
-    {
-        bool b_enable = false;
-        playlist_item_t *p_item = p_root->pp_children[i];
-        // Go recurssively if their is some children
-        if( b_recursive && p_item->i_children >= 0 &&
-            playlist_LiveSearchUpdateInternal( p_item, psz_string, true ) )
-        {
-            b_enable = true;
-        }
-
-        if( !b_enable )
-        {
-            vlc_mutex_lock( &p_item->p_input->lock );
-            // Do we have some meta ?
-            if( p_item->p_input->p_meta )
-            {
-                // Use Title or fall back to psz_name
-                const char *psz_title = vlc_meta_Get( p_item->p_input->p_meta, vlc_meta_Title );
-                if( !psz_title )
-                    psz_title = p_item->p_input->psz_name;
-                const char *psz_album = vlc_meta_Get( p_item->p_input->p_meta, vlc_meta_Album );
-                const char *psz_artist = vlc_meta_Get( p_item->p_input->p_meta, vlc_meta_Artist );
-                b_enable = ( psz_title && vlc_strcasestr( psz_title, psz_string ) ) ||
-                           ( psz_album && vlc_strcasestr( psz_album, psz_string ) ) ||
-                           ( psz_artist && vlc_strcasestr( psz_artist, psz_string ) );
-            }
-            else
-                b_enable = p_item->p_input->psz_name && vlc_strcasestr( p_item->p_input->psz_name, psz_string );
-            vlc_mutex_unlock( &p_item->p_input->lock );
-        }
-
-        if( b_enable )
-            p_item->i_flags &= ~PLAYLIST_DBL_FLAG;
-        else
-            p_item->i_flags |= PLAYLIST_DBL_FLAG;
-
-        b_match |= b_enable;
-   }
-   return b_match;
-}
-
-
-
-/**
- * Launch the recursive search in the playlist
- * @param p_playlist: the playlist
- * @param p_root: the current root item
- * @param psz_string: the string to find
- * @return VLC_SUCCESS
- */
-int playlist_LiveSearchUpdate( playlist_t *p_playlist, playlist_item_t *p_root,
-                               const char *psz_string, bool b_recursive )
-{
-    PL_ASSERT_LOCKED;
-    pl_priv(p_playlist)->b_reset_currently_playing = true;
-    if( *psz_string )
-        playlist_LiveSearchUpdateInternal( p_root, psz_string, b_recursive );
-    else
-        playlist_LiveSearchClean( p_root );
-    vlc_cond_signal( &pl_priv(p_playlist)->signal );
-    return VLC_SUCCESS;
-}
-
diff --git a/src/playlist_legacy/services_discovery.c b/src/playlist_legacy/services_discovery.c
deleted file mode 100644
index 0b9546af7b..0000000000
--- a/src/playlist_legacy/services_discovery.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*****************************************************************************
- * services_discovery.c : Manage playlist services_discovery modules
- *****************************************************************************
- * Copyright (C) 1999-2004 VLC authors and VideoLAN
- *
- * Authors: Clément Stenac <zorglub at videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-#include <assert.h>
-
-#include <vlc_common.h>
-#include <vlc_playlist_legacy.h>
-#include <vlc_services_discovery.h>
-#include "playlist_internal.h"
-
-typedef struct vlc_sd_internal_t
-{
-    /* the playlist items for category and onelevel */
-    playlist_item_t      *node;
-    services_discovery_t *sd; /**< Loaded service discovery modules */
-    struct vlc_list       siblings;
-    char name[];
-} vlc_sd_internal_t;
-
- /* A new item has been added to a certain sd */
-static void playlist_sd_item_added(services_discovery_t *sd,
-                                   input_item_t *parent, input_item_t *p_input,
-                                   const char *psz_cat)
-{
-    assert(parent == NULL || psz_cat == NULL);
-
-    vlc_sd_internal_t *sds = sd->owner.sys;
-    playlist_t *playlist = (playlist_t *)vlc_object_parent(sd);
-    playlist_item_t *node;
-    const char *longname = (sd->description != NULL) ? sd->description : "?";
-
-    msg_Dbg(sd, "adding: %s", p_input->psz_name ? p_input->psz_name : "(null)");
-
-    playlist_Lock(playlist);
-    if (sds->node == NULL)
-        sds->node = playlist_NodeCreate(playlist, longname, &playlist->root,
-                                        PLAYLIST_END, PLAYLIST_RO_FLAG);
-
-    if (parent != NULL)
-        node = playlist_ItemGetByInput(playlist, parent);
-    else
-    if (psz_cat == NULL)
-        node = sds->node;
-    else
-    {   /* Parent is NULL (root) and category is specified.
-         * This is clearly a hack. TODO: remove this. */
-        node = playlist_ChildSearchName(sds->node, psz_cat);
-        if (node == NULL)
-            node = playlist_NodeCreate(playlist, psz_cat, sds->node,
-                                       PLAYLIST_END, PLAYLIST_RO_FLAG);
-    }
-
-    playlist_NodeAddInput(playlist, p_input, node, PLAYLIST_END);
-    playlist_Unlock(playlist);
-}
-
- /* A new item has been removed from a certain sd */
-static void playlist_sd_item_removed(services_discovery_t *sd,
-                                     input_item_t *p_input)
-{
-    vlc_sd_internal_t *sds = sd->owner.sys;
-    playlist_t *playlist = (playlist_t *)vlc_object_parent(sd);
-    playlist_item_t *node, *item;
-
-    msg_Dbg(sd, "removing: %s", p_input->psz_name ? p_input->psz_name : "(null)");
-
-    playlist_Lock(playlist);
-    item = playlist_ItemGetByInput(playlist, p_input);
-    if (unlikely(item == NULL))
-    {
-        msg_Err(sd, "removing item not added"); /* SD plugin bug */
-        playlist_Unlock(playlist);
-        return;
-    }
-
-#ifndef NDEBUG
-    /* Check that the item belonged to the SD */
-    for (playlist_item_t *i = item->p_parent; i != sds->node; i = i->p_parent)
-        assert(i != NULL);
-#endif
-
-    node = item->p_parent;
-    /* if the item was added under a category and the category node
-       becomes empty, delete that node as well */
-    if (node != sds->node && node->i_children == 1)
-        item = node;
-    playlist_NodeDeleteExplicit(playlist, item,
-        PLAYLIST_DELETE_FORCE | PLAYLIST_DELETE_STOP_IF_CURRENT );
-    playlist_Unlock(playlist);
-}
-
-static const struct services_discovery_callbacks playlist_sd_cbs = {
-    .item_added = playlist_sd_item_added,
-    .item_removed = playlist_sd_item_removed,
-};
-
-int playlist_ServicesDiscoveryAdd(playlist_t *playlist, const char *chain)
-{
-    vlc_sd_internal_t *sds = malloc(sizeof (*sds) + strlen(chain) + 1);
-    if (unlikely(sds == NULL))
-        return VLC_ENOMEM;
-
-    sds->node = NULL;
-
-    struct services_discovery_owner_t owner = {
-        &playlist_sd_cbs,
-        sds,
-    };
-
-    /* Perform the addition */
-    sds->sd = vlc_sd_Create(VLC_OBJECT(playlist), chain, &owner);
-    if (unlikely(sds->sd == NULL))
-    {
-        free(sds);
-        return VLC_ENOMEM;
-    }
-
-    strcpy(sds->name, chain);
-
-    playlist_Lock(playlist);
-    /* Backward compatibility with Qt UI: create the node even if the SD
-     * has not discovered any item. */
-    if (sds->node == NULL && sds->sd->description != NULL)
-        sds->node = playlist_NodeCreate(playlist, sds->sd->description,
-                                        &playlist->root, PLAYLIST_END,
-                                        PLAYLIST_RO_FLAG);
-
-    vlc_list_append(&sds->siblings, &pl_priv(playlist)->sds);
-    playlist_Unlock(playlist);
-    return VLC_SUCCESS;
-}
-
-static void playlist_ServicesDiscoveryInternalRemove(playlist_t *playlist,
-                                                     vlc_sd_internal_t *sds)
-{
-    assert(sds->sd != NULL);
-    vlc_sd_Destroy(sds->sd);
-
-    /* Remove the sd playlist node if it exists */
-    playlist_Lock(playlist);
-    if (sds->node != NULL)
-        playlist_NodeDeleteExplicit(playlist, sds->node,
-            PLAYLIST_DELETE_FORCE | PLAYLIST_DELETE_STOP_IF_CURRENT );
-    playlist_Unlock(playlist);
-
-    free(sds);
-}
-
-
-int playlist_ServicesDiscoveryRemove(playlist_t *playlist, const char *name)
-{
-    playlist_private_t *priv = pl_priv(playlist);
-    vlc_sd_internal_t *sds = NULL, *entry;
-
-    playlist_Lock(playlist);
-    vlc_list_foreach(entry, &priv->sds, siblings)
-        if (!strcmp(name, entry->name))
-        {
-            sds = entry;
-            vlc_list_remove(&sds->siblings);
-            break;
-        }
-    playlist_Unlock(playlist);
-
-    if (sds == NULL)
-    {
-        msg_Warn(playlist, "discovery %s is not loaded", name);
-        return VLC_EGENERIC;
-    }
-
-    playlist_ServicesDiscoveryInternalRemove(playlist, sds);
-    return VLC_SUCCESS;
-}
-
-bool playlist_IsServicesDiscoveryLoaded( playlist_t * playlist,
-                                         const char *psz_name )
-{
-    playlist_private_t *priv = pl_priv( playlist );
-    vlc_sd_internal_t *sds;
-    bool found = false;
-
-    playlist_Lock(playlist);
-    vlc_list_foreach(sds, &priv->sds, siblings)
-        if (!strcmp(psz_name, sds->name))
-        {
-            found = true;
-            break;
-        }
-    playlist_Unlock(playlist);
-    return found;
-}
-
-int playlist_ServicesDiscoveryControl( playlist_t *playlist, const char *psz_name, int i_control, ... )
-{
-    playlist_private_t *priv = pl_priv( playlist );
-    vlc_sd_internal_t *sds;
-    int i_ret = VLC_EGENERIC;
-
-    playlist_Lock(playlist);
-    vlc_list_foreach(sds, &priv->sds, siblings)
-        if (!strcmp(psz_name, sds->name))
-        {
-            va_list args;
-            va_start( args, i_control );
-            i_ret = vlc_sd_control(sds->sd, i_control, args );
-            va_end( args );
-            break;
-        }
-    playlist_Unlock(playlist);
-
-    return i_ret;
-}
-
-void playlist_ServicesDiscoveryKillAll(playlist_t *playlist)
-{
-    playlist_private_t *priv = pl_priv(playlist);
-    vlc_sd_internal_t *sds;
-
-    vlc_list_foreach(sds, &priv->sds, siblings)
-        playlist_ServicesDiscoveryInternalRemove(playlist, sds);
-}
diff --git a/src/playlist_legacy/sort.c b/src/playlist_legacy/sort.c
deleted file mode 100644
index 8db7cc65c9..0000000000
--- a/src/playlist_legacy/sort.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*****************************************************************************
- * sort.c : Playlist sorting functions
- *****************************************************************************
- * Copyright (C) 1999-2009 VLC authors and VideoLAN
- *
- * Authors: Clément Stenac <zorglub at videolan.org>
- *          Ilkka Ollakka <ileoo at videolan.org>
- *          Rémi Duraffort <ivoire at videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <vlc_common.h>
-#include <vlc_rand.h>
-#define  VLC_INTERNAL_PLAYLIST_SORT_FUNCTIONS
-#include "vlc_playlist_legacy.h"
-#include "playlist_internal.h"
-
-
-/* General comparison functions */
-/**
- * Compare two items using their title or name
- * @param first: the first item
- * @param second: the second item
- * @return -1, 0 or +1 like strcmp
- */
-static inline int meta_strcasecmp_title( const playlist_item_t *first,
-                              const playlist_item_t *second )
-{
-    int i_ret;
-    char *psz_first = input_item_GetTitleFbName( first->p_input );
-    char *psz_second = input_item_GetTitleFbName( second->p_input );
-
-    if( psz_first && psz_second )
-        i_ret = strcasecmp( psz_first, psz_second );
-    else if( !psz_first && psz_second )
-        i_ret = +1;
-    else if( psz_first && !psz_second )
-        i_ret = -1;
-    else
-        i_ret = 0;
-    free( psz_first );
-    free( psz_second );
-
-    return i_ret;
-}
-
-/**
- * Compare two intems according to the given meta type
- * @param first: the first item
- * @param second: the second item
- * @param meta: the meta type to use to sort the items
- * @param b_integer: true if the meta are integers
- * @return -1, 0 or +1 like strcmp
- */
-static inline int meta_sort( const playlist_item_t *first,
-                             const playlist_item_t *second,
-                             vlc_meta_type_t meta, bool b_integer )
-{
-    int i_ret;
-    char *psz_first = input_item_GetMeta( first->p_input, meta );
-    char *psz_second = input_item_GetMeta( second->p_input, meta );
-
-    /* Nodes go first */
-    if( first->i_children == -1 && second->i_children >= 0 )
-        i_ret = -1;
-    else if( first->i_children >= 0 && second->i_children == -1 )
-        i_ret = +1;
-    /* Both are nodes, sort by name */
-    else if( first->i_children >= 0 && second->i_children >= 0 )
-        i_ret = meta_strcasecmp_title( first, second );
-    /* Both are items */
-    else if( !psz_first && !psz_second )
-        i_ret = 0;
-    else if( !psz_first && psz_second )
-        i_ret = +1;
-    else if( psz_first && !psz_second )
-        i_ret = -1;
-    else
-    {
-        if( b_integer )
-            i_ret = atoi( psz_first ) - atoi( psz_second );
-        else
-            i_ret = strcasecmp( psz_first, psz_second );
-    }
-
-    free( psz_first );
-    free( psz_second );
-    return i_ret;
-}
-
-/* Comparison functions */
-
-/**
- * Return the comparison function appropriate for the SORT_* and ORDER_*
- * arguments given, or NULL for SORT_RANDOM.
- * @param i_mode: a SORT_* enum indicating the field to sort on
- * @param i_type: ORDER_NORMAL or ORDER_REVERSE
- * @return function pointer, or NULL for SORT_RANDOM or invalid input
- */
-typedef int (*sortfn_t)(const void *,const void *);
-static const sortfn_t sorting_fns[NUM_SORT_FNS][2];
-static inline sortfn_t find_sorting_fn( unsigned i_mode, unsigned i_type )
-{
-    if( i_mode>=NUM_SORT_FNS || i_type>1 )
-        return 0;
-    return sorting_fns[i_mode][i_type];
-}
-
-/**
- * Sort an array of items recursively
- * @param i_items: number of items
- * @param pp_items: the array of items
- * @param p_sortfn: the sorting function
- * @return nothing
- */
-static inline
-void playlist_ItemArraySort( unsigned i_items, playlist_item_t **pp_items,
-                             sortfn_t p_sortfn )
-{
-    if( p_sortfn )
-    {
-        qsort( pp_items, i_items, sizeof( pp_items[0] ), p_sortfn );
-    }
-    else /* Randomise */
-    {
-        unsigned i_position;
-        unsigned i_new;
-        playlist_item_t *p_temp;
-
-        for( i_position = i_items - 1; i_position > 0; i_position-- )
-        {
-            i_new = ((unsigned)vlc_mrand48()) % (i_position+1);
-            p_temp = pp_items[i_position];
-            pp_items[i_position] = pp_items[i_new];
-            pp_items[i_new] = p_temp;
-        }
-    }
-}
-
-
-/**
- * Sort a node recursively.
- * This function must be entered with the playlist lock !
- * @param p_playlist the playlist
- * @param p_node the node to sort
- * @param p_sortfn the sorting function
- * @return VLC_SUCCESS on success
- */
-static int recursiveNodeSort( playlist_t *p_playlist, playlist_item_t *p_node,
-                              sortfn_t p_sortfn )
-{
-    int i;
-    playlist_ItemArraySort(p_node->i_children,p_node->pp_children,p_sortfn);
-    for( i = 0 ; i< p_node->i_children; i++ )
-    {
-        if( p_node->pp_children[i]->i_children != -1 )
-        {
-            recursiveNodeSort( p_playlist, p_node->pp_children[i], p_sortfn );
-        }
-    }
-    return VLC_SUCCESS;
-}
-
-/**
- * Sort a node recursively.
- *
- * This function must be entered with the playlist lock !
- *
- * \param p_playlist the playlist
- * \param p_node the node to sort
- * \param i_mode: a SORT_* constant indicating the field to sort on
- * \param i_type: ORDER_NORMAL or ORDER_REVERSE (reversed order)
- * \return VLC_SUCCESS on success
- */
-int playlist_RecursiveNodeSort( playlist_t *p_playlist, playlist_item_t *p_node,
-                                int i_mode, int i_type )
-{
-    PL_ASSERT_LOCKED;
-
-    /* Ask the playlist to reset as we are changing the order */
-    pl_priv(p_playlist)->b_reset_currently_playing = true;
-
-    /* Do the real job recursively */
-    return recursiveNodeSort(p_playlist,p_node,find_sorting_fn(i_mode,i_type));
-}
-
-
-/* This is the stuff the sorting functions are made of. The proto_##
- * functions are wrapped in cmp_a_## and cmp_d_## functions that do
- * void * to const playlist_item_t * casting and dereferencing and
- * cmp_d_## inverts the result, too. proto_## are static inline,
- * cmp_[ad]_## are merely static as they're the target of pointers.
- *
- * In any case, each SORT_## constant (except SORT_RANDOM) must have
- * a matching SORTFN( )-declared function here.
- */
-
-#define SORTFN( SORT, first, second ) static inline int proto_##SORT \
-    ( const playlist_item_t *first, const playlist_item_t *second )
-
-SORTFN( SORT_TRACK_NUMBER, first, second )
-{
-    return meta_sort( first, second, vlc_meta_TrackNumber, true );
-}
-
-SORTFN( SORT_DISC_NUMBER, first, second )
-{
-    int i_ret = meta_sort( first, second, vlc_meta_DiscNumber, true );
-    /* Items came from the same disc: compare the track numbers */
-    if( i_ret == 0 )
-        i_ret = proto_SORT_TRACK_NUMBER( first, second );
-
-    return i_ret;
-}
-
-SORTFN( SORT_ALBUM, first, second )
-{
-    int i_ret = meta_sort( first, second, vlc_meta_Album, false );
-    /* Items came from the same album: compare the disc numbers */
-    if( i_ret == 0 )
-        i_ret = proto_SORT_DISC_NUMBER( first, second );
-
-    return i_ret;
-}
-
-SORTFN( SORT_DATE, first, second )
-{
-    int i_ret = meta_sort( first, second, vlc_meta_Date, true );
-    /* Items came from the same date: compare the albums */
-    if( i_ret == 0 )
-        i_ret = proto_SORT_ALBUM( first, second );
-
-    return i_ret;
-}
-
-SORTFN( SORT_ARTIST, first, second )
-{
-    int i_ret = meta_sort( first, second, vlc_meta_Artist, false );
-    /* Items came from the same artist: compare the dates */
-    if( i_ret == 0 )
-        i_ret = proto_SORT_DATE( first, second );
-
-    return i_ret;
-}
-
-SORTFN( SORT_DESCRIPTION, first, second )
-{
-    return meta_sort( first, second, vlc_meta_Description, false );
-}
-
-SORTFN( SORT_DURATION, first, second )
-{
-    vlc_tick_t time1 = input_item_GetDuration( first->p_input );
-    vlc_tick_t time2 = input_item_GetDuration( second->p_input );
-    int i_ret = time1 > time2 ? +1 :
-                    ( time1 == time2 ? 0 : -1 );
-    return i_ret;
-}
-
-SORTFN( SORT_GENRE, first, second )
-{
-    return meta_sort( first, second, vlc_meta_Genre, false );
-}
-
-SORTFN( SORT_ID, first, second )
-{
-    return first->i_id - second->i_id;
-}
-
-SORTFN( SORT_RATING, first, second )
-{
-    return meta_sort( first, second, vlc_meta_Rating, true );
-}
-
-SORTFN( SORT_TITLE, first, second )
-{
-    return meta_strcasecmp_title( first, second );
-}
-
-SORTFN( SORT_TITLE_NODES_FIRST, first, second )
-{
-    /* If second is a node but not first */
-    if( first->i_children == -1 && second->i_children >= 0 )
-        return -1;
-    /* If first is a node but not second */
-    else if( first->i_children >= 0 && second->i_children == -1 )
-        return +1;
-    /* Both are nodes or both are not nodes */
-    else
-        return meta_strcasecmp_title( first, second );
-}
-
-SORTFN( SORT_TITLE_NUMERIC, first, second )
-{
-    int i_ret;
-    char *psz_first = input_item_GetTitleFbName( first->p_input );
-    char *psz_second = input_item_GetTitleFbName( second->p_input );
-
-    if( psz_first && psz_second )
-        i_ret = atoi( psz_first ) - atoi( psz_second );
-    else if( !psz_first && psz_second )
-        i_ret = +1;
-    else if( psz_first && !psz_second )
-        i_ret = -1;
-    else
-        i_ret = 0;
-
-    free( psz_first );
-    free( psz_second );
-    return i_ret;
-}
-
-SORTFN( SORT_URI, first, second )
-{
-    int i_ret;
-    char *psz_first = input_item_GetURI( first->p_input );
-    char *psz_second = input_item_GetURI( second->p_input );
-
-    if( psz_first && psz_second )
-        i_ret = strcasecmp( psz_first, psz_second );
-    else if( !psz_first && psz_second )
-        i_ret = +1;
-    else if( psz_first && !psz_second )
-        i_ret = -1;
-    else
-        i_ret = 0;
-
-    free( psz_first );
-    free( psz_second );
-    return i_ret;
-}
-
-#undef  SORTFN
-
-/* Generate stubs around the proto_## sorting functions, ascending and
- * descending both. Preprocessor magic up ahead. Brace yourself.
- */
-
-#ifndef VLC_DEFINE_SORT_FUNCTIONS
-#error  Where is VLC_DEFINE_SORT_FUNCTIONS?
-#endif
-
-#define DEF( s ) \
-    static int cmp_a_##s(const void *l,const void *r) \
-    { return proto_##s(*(const playlist_item_t *const *)l, \
-                           *(const playlist_item_t *const *)r); } \
-    static int cmp_d_##s(const void *l,const void *r) \
-    { return -1*proto_##s(*(const playlist_item_t * const *)l, \
-                              *(const playlist_item_t * const *)r); }
-
-    VLC_DEFINE_SORT_FUNCTIONS
-
-#undef  DEF
-
-/* And populate an array with the addresses */
-
-static const sortfn_t sorting_fns[NUM_SORT_FNS][2] =
-#define DEF( a ) { cmp_a_##a, cmp_d_##a },
-{ VLC_DEFINE_SORT_FUNCTIONS };
-#undef  DEF
diff --git a/src/playlist_legacy/thread.c b/src/playlist_legacy/thread.c
deleted file mode 100644
index 6d4cf9ee80..0000000000
--- a/src/playlist_legacy/thread.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*****************************************************************************
- * thread.c : Playlist management functions
- *****************************************************************************
- * Copyright © 1999-2008 VLC authors and VideoLAN
- *
- * Authors: Samuel Hocevar <sam at zoy.org>
- *          Clément Stenac <zorglub at videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <assert.h>
-
-#include <vlc_common.h>
-#include <vlc_es.h>
-#include <vlc_input.h>
-#include <vlc_interface.h>
-#include <vlc_playlist_legacy.h>
-#include <vlc_rand.h>
-#include <vlc_renderer_discovery.h>
-#include "playlist_internal.h"
-#include "../input/input_internal.h"
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static void *Thread   ( void * );
-
-/*****************************************************************************
- * Main functions for the global thread
- *****************************************************************************/
-
-/**
- * Creates the main playlist thread.
- */
-void playlist_Activate( playlist_t *p_playlist )
-{
-    playlist_private_t *p_sys = pl_priv(p_playlist);
-
-    if( vlc_clone( &p_sys->thread, Thread, p_playlist,
-                   VLC_THREAD_PRIORITY_LOW ) )
-    {
-        msg_Err( p_playlist, "cannot spawn playlist thread" );
-        abort();
-    }
-}
-
-/**
- * Stops the playlist forever (but do not destroy it yet).
- * Any input is stopped.
- * \return Nothing but waits for the playlist to be deactivated.
- */
-void playlist_Deactivate( playlist_t *p_playlist )
-{
-    playlist_private_t *p_sys = pl_priv(p_playlist);
-
-    PL_LOCK;
-    /* WARNING: There is a latent bug. It is assumed that only one thread will
-     * be waiting for playlist deactivation at a time. So far, that works
-     * as playlist_Deactivate() is only ever called while closing an
-     * interface and interfaces are shut down serially by intf_DestroyAll(). */
-    if( p_sys->killed )
-    {
-        PL_UNLOCK;
-        return;
-    }
-
-    msg_Dbg( p_playlist, "deactivating the playlist" );
-    p_sys->killed = true;
-    vlc_cond_signal( &p_sys->signal );
-    PL_UNLOCK;
-
-    vlc_join( p_sys->thread, NULL );
-}
-
-/* */
-
-/* Input Callback */
-static int InputEvent( vlc_object_t *p_this, char const *psz_cmd,
-                       vlc_value_t oldval, vlc_value_t newval, void *p_data )
-{
-    VLC_UNUSED(p_this); VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval);
-    playlist_t *p_playlist = p_data;
-
-    if( newval.i_int == INPUT_EVENT_DEAD )
-    {
-        playlist_private_t *sys = pl_priv(p_playlist);
-
-        PL_LOCK;
-        sys->request.input_dead = true;
-        vlc_cond_signal( &sys->signal );
-        PL_UNLOCK;
-    }
-    return VLC_SUCCESS;
-}
-
-/**
- * Synchronise the current index of the playlist
- * to match the index of the current item.
- *
- * \param p_playlist the playlist structure
- * \param p_cur the current playlist item
- * \return nothing
- */
-void ResyncCurrentIndex( playlist_t *p_playlist, playlist_item_t *p_cur )
-{
-    PL_ASSERT_LOCKED;
-
-    PL_DEBUG( "resyncing on %s", PLI_NAME( p_cur ) );
-    /* Simply resync index */
-    int i;
-    p_playlist->i_current_index = -1;
-    for( i = 0 ; i< p_playlist->current.i_size; i++ )
-    {
-        if( ARRAY_VAL( p_playlist->current, i ) == p_cur )
-        {
-            p_playlist->i_current_index = i;
-            break;
-        }
-    }
-    PL_DEBUG( "%s is at %i", PLI_NAME( p_cur ), p_playlist->i_current_index );
-}
-
-/**
- * Reset the currently playing playlist.
- *
- * \param p_playlist the playlist structure
- * \param p_cur the current playlist item
- * \return nothing
- */
-void ResetCurrentlyPlaying( playlist_t *p_playlist,
-                                   playlist_item_t *p_cur )
-{
-    playlist_private_t *p_sys = pl_priv(p_playlist);
-
-    PL_DEBUG( "rebuilding array of current - root %s",
-              PLI_NAME( p_sys->status.p_node ) );
-    ARRAY_RESET( p_playlist->current );
-    p_playlist->i_current_index = -1;
-    for( playlist_item_t *p_next = NULL; ; )
-    {
-        /** FIXME: this is *slow* */
-        p_next = playlist_GetNextLeaf( p_playlist,
-                                       p_sys->status.p_node,
-                                       p_next, true, false );
-        if( !p_next )
-            break;
-
-        if( p_next == p_cur )
-            p_playlist->i_current_index = p_playlist->current.i_size;
-        ARRAY_APPEND( p_playlist->current, p_next);
-    }
-    PL_DEBUG("rebuild done - %i items, index %i", p_playlist->current.i_size,
-                                                  p_playlist->i_current_index);
-
-    if( var_GetBool( p_playlist, "random" ) && ( p_playlist->current.i_size > 0 ) )
-    {
-        /* Shuffle the array */
-        for( unsigned j = p_playlist->current.i_size - 1; j > 0; j-- )
-        {
-            unsigned i = vlc_lrand48() % (j+1); /* between 0 and j */
-            playlist_item_t *p_tmp;
-            /* swap the two items */
-            p_tmp = ARRAY_VAL(p_playlist->current, i);
-            ARRAY_VAL(p_playlist->current,i) = ARRAY_VAL(p_playlist->current,j);
-            ARRAY_VAL(p_playlist->current,j) = p_tmp;
-        }
-    }
-    p_sys->b_reset_currently_playing = false;
-}
-
-static void on_input_event(input_thread_t *input,
-                           const struct vlc_input_event *event, void *userdata)
-{
-    if (event->type == INPUT_EVENT_SUBITEMS)
-    {
-        playlist_t *playlist = userdata;
-        input_item_t *item = input_GetItem(input);
-        playlist_AddSubtree(playlist, item, event->subitems);
-    }
-
-    input_LegacyEvents(input, event, userdata);
-}
-
-/**
- * Start the input for an item
- *
- * \param p_playlist the playlist object
- * \param p_item the item to play
- */
-static bool PlayItem( playlist_t *p_playlist, playlist_item_t *p_item )
-{
-    libvlc_int_t *vlc = vlc_object_instance(p_playlist);
-    playlist_private_t *p_sys = pl_priv(p_playlist);
-    input_item_t *p_input = p_item->p_input;
-    vlc_renderer_item_t *p_renderer;
-
-    PL_ASSERT_LOCKED;
-
-    msg_Dbg( p_playlist, "creating new input thread" );
-
-    p_item->i_nb_played++;
-    set_current_status_item( p_playlist, p_item );
-    p_renderer = p_sys->p_renderer;
-    /* Retain the renderer now to avoid it to be released by
-     * playlist_SetRenderer when we exit the locked scope. If the last reference
-     * was to be released, we would use a dangling pointer */
-    if( p_renderer )
-        vlc_renderer_item_hold( p_renderer );
-    assert( p_sys->p_input == NULL );
-    PL_UNLOCK;
-
-    libvlc_MetadataCancel( vlc, p_item );
-
-    input_thread_t *p_input_thread = input_Create( p_playlist,
-                                                   on_input_event, p_playlist,
-                                                   p_input,
-                                                   p_sys->p_input_resource,
-                                                   p_renderer );
-    if( p_renderer )
-        vlc_renderer_item_release( p_renderer );
-    if( likely(p_input_thread != NULL) )
-    {
-        input_LegacyVarInit( p_input_thread );
-        var_AddCallback( p_input_thread, "intf-event",
-                         InputEvent, p_playlist );
-        if( input_Start( p_input_thread ) )
-        {
-            var_DelCallback( p_input_thread, "intf-event",
-                             InputEvent, p_playlist );
-            input_Close(p_input_thread);
-            p_input_thread = NULL;
-        }
-    }
-
-    /* TODO store art policy in playlist private data */
-    char *psz_arturl = input_item_GetArtURL( p_input );
-    /* p_input->p_meta should not be null after a successful CreateThread */
-    bool b_has_art = !EMPTY_STR( psz_arturl );
-
-    if( !b_has_art || strncmp( psz_arturl, "attachment://", 13 ) )
-    {
-        PL_DEBUG( "requesting art for new input thread" );
-        libvlc_ArtRequest( vlc, p_input, META_REQUEST_OPTION_NONE, NULL, NULL );
-    }
-    free( psz_arturl );
-
-    PL_LOCK;
-    p_sys->p_input = p_input_thread;
-    PL_UNLOCK;
-
-    var_SetAddress( p_playlist, "input-current", p_input_thread );
-
-    PL_LOCK;
-    return p_input_thread != NULL;
-}
-
-/**
- * Compute the next playlist item depending on
- * the playlist course mode (forward, backward, random, view,...).
- *
- * \param p_playlist the playlist object
- * \return nothing
- */
-static playlist_item_t *NextItem( playlist_t *p_playlist )
-{
-    playlist_private_t *p_sys = pl_priv(p_playlist);
-    playlist_item_t *p_new = NULL;
-    bool requested = p_sys->request.b_request;
-
-    /* Clear the request */
-    p_sys->request.b_request = false;
-
-    /* Handle quickly a few special cases */
-    /* No items to play */
-    if( p_playlist->items.i_size == 0 )
-    {
-        msg_Info( p_playlist, "playlist is empty" );
-        return NULL;
-    }
-
-    /* Start the real work */
-    if( requested )
-    {
-        p_new = p_sys->request.p_item;
-
-        if( p_new == NULL && p_sys->request.p_node == NULL )
-            return NULL; /* Stop request! */
-
-        int i_skip = p_sys->request.i_skip;
-        PL_DEBUG( "processing request item: %s, node: %s, skip: %i",
-                        PLI_NAME( p_sys->request.p_item ),
-                        PLI_NAME( p_sys->request.p_node ), i_skip );
-
-        if( p_sys->request.p_node &&
-            p_sys->request.p_node != get_current_status_node( p_playlist ) )
-        {
-
-            set_current_status_node( p_playlist, p_sys->request.p_node );
-            p_sys->request.p_node = NULL;
-            p_sys->b_reset_currently_playing = true;
-        }
-
-        /* If we are asked for a node, go to it's first child */
-        if( i_skip == 0 && ( p_new == NULL || p_new->i_children != -1 ) )
-        {
-            i_skip++;
-            if( p_new != NULL )
-            {
-                p_new = playlist_GetNextLeaf( p_playlist, p_new, NULL, true, false );
-                for( int i = 0; i < p_playlist->current.i_size; i++ )
-                {
-                    if( p_new == ARRAY_VAL( p_playlist->current, i ) )
-                    {
-                        p_playlist->i_current_index = i;
-                        i_skip = 0;
-                    }
-                }
-            }
-        }
-
-        if( p_sys->b_reset_currently_playing )
-            /* A bit too bad to reset twice ... */
-            ResetCurrentlyPlaying( p_playlist, p_new );
-        else if( p_new )
-            ResyncCurrentIndex( p_playlist, p_new );
-        else
-            p_playlist->i_current_index = -1;
-
-        if( p_playlist->current.i_size && (i_skip > 0) )
-        {
-            if( p_playlist->i_current_index < -1 )
-                p_playlist->i_current_index = -1;
-            for( int i = i_skip; i > 0 ; i-- )
-            {
-                p_playlist->i_current_index++;
-                if( p_playlist->i_current_index >= p_playlist->current.i_size )
-                {
-                    PL_DEBUG( "looping - restarting at beginning of node" );
-                    /* reshuffle playlist when end is reached */
-                    if( var_GetBool( p_playlist, "random" ) ) {
-                        PL_DEBUG( "reshuffle playlist" );
-                        ResetCurrentlyPlaying( p_playlist,
-                                get_current_status_item( p_playlist ) );
-                    }
-                    p_playlist->i_current_index = 0;
-                }
-            }
-            p_new = ARRAY_VAL( p_playlist->current,
-                               p_playlist->i_current_index );
-        }
-        else if( p_playlist->current.i_size && (i_skip < 0) )
-        {
-            for( int i = i_skip; i < 0 ; i++ )
-            {
-                p_playlist->i_current_index--;
-                if( p_playlist->i_current_index <= -1 )
-                {
-                    PL_DEBUG( "looping - restarting at end of node" );
-                    /* reshuffle playlist when beginning is reached */
-                    if( var_GetBool( p_playlist, "random" ) ) {
-                        PL_DEBUG( "reshuffle playlist" );
-                        ResetCurrentlyPlaying( p_playlist,
-                                get_current_status_item( p_playlist ) );
-                    }
-                    p_playlist->i_current_index = p_playlist->current.i_size-1;
-                }
-            }
-            p_new = ARRAY_VAL( p_playlist->current,
-                               p_playlist->i_current_index );
-        }
-    }
-    /* "Automatic" item change ( next ) */
-    else
-    {
-        bool b_loop = var_GetBool( p_playlist, "loop" );
-        bool b_repeat = var_GetBool( p_playlist, "repeat" );
-        bool b_playstop = var_InheritBool( p_playlist, "play-and-stop" );
-
-        /* Repeat and play/stop */
-        if( b_repeat && get_current_status_item( p_playlist ) )
-        {
-            msg_Dbg( p_playlist,"repeating item" );
-            return get_current_status_item( p_playlist );
-        }
-        if( b_playstop && get_current_status_item( p_playlist ) )
-        {
-            msg_Dbg( p_playlist,"stopping (play and stop)" );
-            return NULL;
-        }
-
-        /* */
-
-        PL_DEBUG( "changing item without a request (current %i/%i)",
-                  p_playlist->i_current_index, p_playlist->current.i_size );
-        /* Can't go to next from current item */
-        if( p_sys->b_reset_currently_playing )
-            ResetCurrentlyPlaying( p_playlist,
-                                   get_current_status_item( p_playlist ) );
-
-        p_playlist->i_current_index++;
-        assert( p_playlist->i_current_index <= p_playlist->current.i_size );
-        if( p_playlist->i_current_index == p_playlist->current.i_size )
-        {
-            if( !b_loop || p_playlist->current.i_size == 0 )
-                return NULL;
-            /* reshuffle after last item has been played */
-            if( var_GetBool( p_playlist, "random" ) ) {
-                PL_DEBUG( "reshuffle playlist" );
-                ResetCurrentlyPlaying( p_playlist,
-                                       get_current_status_item( p_playlist ) );
-            }
-            p_playlist->i_current_index = 0;
-        }
-        PL_DEBUG( "using item %i", p_playlist->i_current_index );
-        if ( p_playlist->current.i_size == 0 )
-            return NULL;
-
-        p_new = ARRAY_VAL( p_playlist->current, p_playlist->i_current_index );
-    }
-    return p_new;
-}
-
-static void LoopInput( playlist_t *p_playlist )
-{
-    playlist_private_t *p_sys = pl_priv(p_playlist);
-    input_thread_t *p_input = p_sys->p_input;
-
-    assert( p_input != NULL );
-
-    /* Wait for input to end or be stopped */
-    while( !p_sys->request.input_dead )
-    {
-        if( p_sys->request.b_request || p_sys->killed )
-        {
-            PL_DEBUG( "incoming request - stopping current input" );
-            input_Stop( p_input );
-        }
-        vlc_cond_wait( &p_sys->signal, &p_sys->lock );
-    }
-
-    /* This input is dead. Remove it ! */
-    PL_DEBUG( "dead input" );
-    p_sys->p_input = NULL;
-    p_sys->request.input_dead = false;
-    PL_UNLOCK;
-
-    var_SetAddress( p_playlist, "input-current", NULL );
-
-    /* WARNING: Input resource manipulation and callback deletion are
-     * incompatible with the playlist lock. */
-    if( !var_InheritBool( p_input, "sout-keep" ) )
-        input_resource_TerminateSout( p_sys->p_input_resource );
-    var_DelCallback( p_input, "intf-event", InputEvent, p_playlist );
-    input_Close( p_input );
-    PL_LOCK;
-}
-
-static bool Next( playlist_t *p_playlist )
-{
-    playlist_item_t *p_item = NextItem( p_playlist );
-    if( p_item == NULL )
-        return false;
-
-    msg_Dbg( p_playlist, "starting playback of new item" );
-    ResyncCurrentIndex( p_playlist, p_item );
-    return PlayItem( p_playlist, p_item );
-}
-
-/**
- * Run the main control thread itself
- */
-static void *Thread ( void *data )
-{
-    playlist_t *p_playlist = data;
-    playlist_private_t *p_sys = pl_priv(p_playlist);
-    bool played = false;
-
-    PL_LOCK;
-    while( !p_sys->killed )
-    {
-        /* Playlist in stopped state */
-        assert(p_sys->p_input == NULL);
-
-        if( !p_sys->request.b_request )
-        {
-            vlc_cond_wait( &p_sys->signal, &p_sys->lock );
-            continue;
-        }
-
-        /* Playlist in running state */
-        while( !p_sys->killed && Next( p_playlist ) )
-        {
-            LoopInput( p_playlist );
-            played = true;
-        }
-
-        /* Playlist stopping */
-        msg_Dbg( p_playlist, "nothing to play" );
-        if( played && var_InheritBool( p_playlist, "play-and-exit" ) )
-        {
-            msg_Info( p_playlist, "end of playlist, exiting" );
-            libvlc_Quit( vlc_object_instance(p_playlist) );
-        }
-    }
-    PL_UNLOCK;
-
-    input_resource_Terminate( p_sys->p_input_resource );
-    return NULL;
-}
diff --git a/src/playlist_legacy/tree.c b/src/playlist_legacy/tree.c
deleted file mode 100644
index 97736c45cd..0000000000
--- a/src/playlist_legacy/tree.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/*****************************************************************************
- * tree.c : Playlist tree walking functions
- *****************************************************************************
- * Copyright (C) 1999-2007 VLC authors and VideoLAN
- *
- * Authors: Clément Stenac <zorglub at videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <vlc_common.h>
-#include <assert.h>
-#include "vlc_playlist_legacy.h"
-#include "playlist_internal.h"
-
-/************************************************************************
- * Local prototypes
- ************************************************************************/
-playlist_item_t *GetNextUncle( playlist_t *p_playlist, playlist_item_t *p_item,
-                               playlist_item_t *p_root );
-playlist_item_t *GetPrevUncle( playlist_t *p_playlist, playlist_item_t *p_item,
-                               playlist_item_t *p_root );
-
-playlist_item_t *GetNextItem( playlist_t *p_playlist,
-                              playlist_item_t *p_root,
-                              playlist_item_t *p_item );
-playlist_item_t *GetPrevItem( playlist_t *p_playlist,
-                              playlist_item_t *p_item,
-                              playlist_item_t *p_root );
-
-/**
- * Create a playlist node
- *
- * \param p_playlist the playlist
- * \param psz_name the name of the node
- * \param p_parent the parent node to attach to or NULL if no attach
- * \param i_pos position of the node in the parent, PLAYLIST_END to append to end.
- * \param p_flags miscellaneous flags
- * \param p_input the input_item to attach to or NULL if it has to be created
- * \return the new node
- */
-playlist_item_t * playlist_NodeCreate( playlist_t *p_playlist,
-                                       const char *psz_name,
-                                       playlist_item_t *p_parent, int i_pos,
-                                       int i_flags )
-{
-    input_item_t *p_new_input;
-    playlist_item_t *p_item;
-
-    PL_ASSERT_LOCKED;
-    if( !psz_name ) psz_name = _("Undefined");
-
-    p_new_input = input_item_NewExt( NULL, psz_name, INPUT_DURATION_UNSET, ITEM_TYPE_NODE,
-                                     ITEM_NET_UNKNOWN );
-    if( !p_new_input )
-        return NULL;
-    p_item = playlist_ItemNewFromInput( p_playlist, p_new_input );
-    input_item_Release( p_new_input );
-
-    if( p_item == NULL )  return NULL;
-
-    playlist_NodeInsert( p_parent, p_item, i_pos );
-    playlist_SendAddNotify( p_playlist, p_item );
-
-    p_item->i_flags |= i_flags;
-
-    return p_item;
-}
-
-/**
- * Remove all the children of a node and removes the node
- *
- * \param p_playlist the playlist
- * \param p_root the node
- */
-void playlist_NodeDelete( playlist_t *p_playlist, playlist_item_t *p_root )
-{
-    playlist_NodeDeleteExplicit( p_playlist, p_root,
-        PLAYLIST_DELETE_STOP_IF_CURRENT );
-}
-
-void playlist_NodeDeleteExplicit( playlist_t *p_playlist,
-    playlist_item_t *p_root, int flags )
-{
-    PL_ASSERT_LOCKED;
-
-    /* Delete the node */
-    if( p_root->i_flags & PLAYLIST_RO_FLAG &&
-        !( flags & PLAYLIST_DELETE_FORCE ) )
-        return;
-
-    /* Delete the children */
-    for( int i = p_root->i_children - 1 ; i >= 0; i-- )
-        playlist_NodeDeleteExplicit( p_playlist,
-            p_root->pp_children[i], flags | PLAYLIST_DELETE_FORCE );
-
-    pl_priv(p_playlist)->b_reset_currently_playing = true;
-
-    int i;
-    var_SetAddress( p_playlist, "playlist-item-deleted", p_root );
-
-    if( p_root->i_children == -1 ) {
-        ARRAY_BSEARCH( p_playlist->items,->i_id, int, p_root->i_id, i );
-        if( i != -1 )
-            ARRAY_REMOVE( p_playlist->items, i );
-    }
-
-    if( get_current_status_item( p_playlist ) == p_root )
-    {
-        /* a deleted item cannot be currently playing */
-        set_current_status_item( p_playlist, NULL );
-
-        if( flags & PLAYLIST_DELETE_STOP_IF_CURRENT )
-            playlist_Control( p_playlist, PLAYLIST_STOP, pl_Locked );
-    }
-
-    for( i = 0; i < p_playlist->current.i_size; i++ )
-        if( p_playlist->current.p_elems[i] == p_root )
-            ARRAY_REMOVE( p_playlist->current, i );
-    for( i = 0; i < p_playlist->current.i_size; i++ )
-        assert( p_playlist->current.p_elems[i] != p_root );
-
-    PL_DEBUG( "deleting item `%s'", p_root->p_input->psz_name );
-
-    /* Remove the item from its parent */
-    playlist_item_t *p_parent = p_root->p_parent;
-    if( p_parent != NULL )
-        TAB_REMOVE(p_parent->i_children, p_parent->pp_children, p_root);
-
-    playlist_ItemRelease( p_playlist, p_root );
-}
-
-int playlist_NodeInsert( playlist_item_t *p_parent, playlist_item_t *p_item,
-                         int i_position )
-{
-    assert( p_parent && p_parent->i_children != -1 );
-    if( i_position == -1 ) i_position = p_parent->i_children ;
-    assert( i_position <= p_parent->i_children);
-
-    TAB_INSERT(p_parent->i_children, p_parent->pp_children,
-               p_item, i_position);
-    p_item->p_parent = p_parent;
-
-    /* Inherit special flags from parent (sd cases) */
-    if( ( p_parent->i_flags & PLAYLIST_NO_INHERIT_FLAG ) == 0 )
-        p_item->i_flags |= (p_parent->i_flags & PLAYLIST_RO_FLAG);
-
-    return VLC_SUCCESS;
-}
-
-/**
- * Search a child of a node by its name
- *
- * \note The playlist must be locked, and the result is only valid until the
- * playlist is unlocked.
- *
- * \param p_node the node
- * \param psz_search the name of the child to search
- * \return the child item or NULL if not found or error
- */
-playlist_item_t *playlist_ChildSearchName( playlist_item_t *p_node,
-                                           const char *psz_search )
-{
-    int i;
-
-    if( p_node->i_children < 0 )
-    {
-         return NULL;
-    }
-    for( i = 0 ; i< p_node->i_children; i++ )
-    {
-        if( !strcmp( p_node->pp_children[i]->p_input->psz_name, psz_search ) )
-        {
-            return p_node->pp_children[i];
-        }
-    }
-    return NULL;
-}
-
-/**********************************************************************
- * Tree walking functions
- **********************************************************************/
-/**
- * Finds the next item to play
- *
- * \param p_playlist the playlist
- * \param p_root the root node
- * \param p_item the previous item  (NULL if none )
- * \return the next item to play, or NULL if none found
- */
-playlist_item_t *playlist_GetNextLeaf( playlist_t *p_playlist,
-                                       playlist_item_t *p_root,
-                                       playlist_item_t *p_item,
-                                       bool b_ena, bool b_unplayed )
-{
-    PL_ASSERT_LOCKED;
-    playlist_item_t *p_next;
-
-    assert( p_root && p_root->i_children != -1 );
-
-    PL_DEBUG2( "finding next of %s within %s",
-               PLI_NAME( p_item ), PLI_NAME( p_root ) );
-
-    /* Now, walk the tree until we find a suitable next item */
-    p_next = p_item;
-    while( 1 )
-    {
-        bool b_ena_ok = true, b_unplayed_ok = true;
-        p_next = GetNextItem( p_playlist, p_root, p_next );
-        if( !p_next || p_next == p_root )
-            break;
-        if( p_next->i_children == -1 )
-        {
-            if( b_ena && p_next->i_flags & PLAYLIST_DBL_FLAG )
-                b_ena_ok = false;
-            if( b_unplayed && p_next->i_nb_played != 0 )
-                b_unplayed_ok = false;
-            if( b_ena_ok && b_unplayed_ok ) break;
-        }
-    }
-    if( p_next == NULL ) PL_DEBUG2( "at end of node" );
-    return p_next;
-}
-
-/************************************************************************
- * Following functions are local
- ***********************************************************************/
-
-/**
- * Get the next item in the tree
- * If p_item is NULL, return the first child of root
- **/
-playlist_item_t *GetNextItem( playlist_t *p_playlist,
-                              playlist_item_t *p_root,
-                              playlist_item_t *p_item )
-{
-    /* If the item is NULL, return the firt child of root */
-    if( p_item == NULL )
-    {
-        if( p_root->i_children > 0 )
-            return p_root->pp_children[0];
-        else
-            return NULL;
-    }
-
-    /* Node with children, get the first one */
-    if( p_item->i_children > 0 )
-        return p_item->pp_children[0];
-
-    playlist_item_t* p_parent = p_item->p_parent;
-    for( int i = 0 ; i < p_parent->i_children ; i++ )
-    {
-        if( p_parent->pp_children[i] == p_item )
-        {
-            // Return the next children
-            if( i + 1 < p_parent->i_children )
-                return p_parent->pp_children[i+1];
-            // We are the least one, so try to have uncles
-            else
-            {
-                PL_DEBUG2( "Current item is the last of the node,"
-                           "looking for uncle from %s",
-                            p_parent->p_input->psz_name );
-                if( p_parent == p_root )
-                {
-                    PL_DEBUG2( "already at root" );
-                    return NULL;
-                }
-                else
-                    return GetNextUncle( p_playlist, p_item, p_root );
-            }
-        }
-    }
-    return NULL;
-}
-
-playlist_item_t *GetNextUncle( playlist_t *p_playlist, playlist_item_t *p_item,
-                               playlist_item_t *p_root )
-{
-    playlist_item_t *p_parent = p_item->p_parent;
-    playlist_item_t *p_grandparent;
-    bool b_found = false;
-
-    (void)p_playlist;
-
-    if( p_parent != NULL )
-    {
-        p_grandparent = p_parent->p_parent;
-        while( p_grandparent )
-        {
-            int i;
-            for( i = 0 ; i< p_grandparent->i_children ; i++ )
-            {
-                if( p_parent == p_grandparent->pp_children[i] )
-                {
-                    PL_DEBUG2( "parent %s found as child %i of grandparent %s",
-                               p_parent->p_input->psz_name, i,
-                               p_grandparent->p_input->psz_name );
-                    b_found = true;
-                    break;
-                }
-            }
-            if( b_found && i + 1 < p_grandparent->i_children )
-            {
-                    return p_grandparent->pp_children[i+1];
-            }
-            /* Not found at root */
-            if( p_grandparent == p_root )
-            {
-                return NULL;
-            }
-            else
-            {
-                p_parent = p_grandparent;
-                p_grandparent = p_parent->p_parent;
-            }
-        }
-    }
-    /* We reached root */
-    return NULL;
-}
-
-playlist_item_t *GetPrevUncle( playlist_t *p_playlist, playlist_item_t *p_item,
-                               playlist_item_t *p_root )
-{
-    playlist_item_t *p_parent = p_item->p_parent;
-    playlist_item_t *p_grandparent;
-    bool b_found = false;
-
-    (void)p_playlist;
-
-    if( p_parent != NULL )
-    {
-        p_grandparent = p_parent->p_parent;
-        while( 1 )
-        {
-            int i;
-            for( i = p_grandparent->i_children -1 ; i >= 0; i-- )
-            {
-                if( p_parent == p_grandparent->pp_children[i] )
-                {
-                    b_found = true;
-                    break;
-                }
-            }
-            if( b_found && i - 1 > 0 )
-            {
-                return p_grandparent->pp_children[i-1];
-            }
-            /* Not found at root */
-            if( p_grandparent == p_root )
-            {
-                return NULL;
-            }
-            else
-            {
-                p_parent = p_grandparent;
-                p_grandparent = p_parent->p_parent;
-            }
-        }
-    }
-    /* We reached root */
-    return NULL;
-}
-
-
-/* Recursively search the tree for previous item */
-playlist_item_t *GetPrevItem( playlist_t *p_playlist,
-                              playlist_item_t *p_root,
-                              playlist_item_t *p_item )
-{
-    playlist_item_t *p_parent;
-    int i;
-
-    /* Node with children, get the last one */
-    if( p_item && p_item->i_children > 0 )
-        return p_item->pp_children[p_item->i_children - 1];
-
-    /* Last child of its parent ? */
-    if( p_item != NULL )
-        p_parent = p_item->p_parent;
-    else
-    {
-        msg_Err( p_playlist, "Get the last one" );
-        abort();
-    };
-
-    for( i = p_parent->i_children -1 ; i >= 0 ;  i-- )
-    {
-        if( p_parent->pp_children[i] == p_item )
-        {
-            if( i-1 < 0 )
-            {
-               /* Was already the first sibling. Look for uncles */
-                PL_DEBUG2( "current item is the first of its node,"
-                           "looking for uncle from %s",
-                           p_parent->p_input->psz_name );
-                if( p_parent == p_root )
-                {
-                    PL_DEBUG2( "already at root" );
-                    return NULL;
-                }
-                return GetPrevUncle( p_playlist, p_item, p_root );
-            }
-            else
-            {
-                return p_parent->pp_children[i-1];
-            }
-        }
-    }
-    return NULL;
-}
-- 
2.20.1



More information about the vlc-devel mailing list