+ assert( p_toplay );
+ p_playlist->request.b_request = true;
+ p_playlist->request.i_skip = 0;
+ p_playlist->request.p_item = p_toplay;
+ if( p_playlist->p_input )
+ input_StopThread( p_playlist->p_input );
+ p_playlist->request.i_status = PLAYLIST_RUNNING;
+ vlc_cond_signal( &p_playlist->object_wait );
+ }
+ /* Preparse if PREPARSE or SPREPARSE & not enough meta */
+ char *psz_artist = input_item_GetArtist( p_item_cat->p_input );
+ char *psz_album = input_item_GetAlbum( p_item_cat->p_input );
+ if( p_playlist->b_auto_preparse &&
+ (i_mode & PLAYLIST_PREPARSE ||
+ ( i_mode & PLAYLIST_SPREPARSE &&
+ ( EMPTY_STR( psz_artist ) || ( EMPTY_STR( psz_album ) ) )
+ ) ) )
+ playlist_PreparseEnqueue( p_playlist, p_item_cat->p_input );
+ /* If we already have it, signal it */
+ else if( !EMPTY_STR( psz_artist ) && !EMPTY_STR( psz_album ) )
+ input_item_SetPreparsed( p_item_cat->p_input, true );
+ free( psz_artist );
+ free( psz_album );
+}
+
+/* Add the playlist item to the requested node and fire a notification */
+static void AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
+ playlist_item_t *p_node, int i_mode, int i_pos )
+{
+ ARRAY_APPEND(p_playlist->items, p_item);
+ ARRAY_APPEND(p_playlist->all_items, p_item);
+
+ if( i_pos == PLAYLIST_END )
+ playlist_NodeAppend( p_playlist, p_item, p_node );
+ else
+ playlist_NodeInsert( p_playlist, p_item, p_node, i_pos );
+
+ if( !p_playlist->b_doing_ml )
+ playlist_SendAddNotify( p_playlist, p_item->i_id, p_node->i_id,
+ !( i_mode & PLAYLIST_NO_REBUILD ) );
+}
+
+/* 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 )
+ p_item->i_children = 0;
+
+ /* 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 );
+}
+
+/* Do the actual removal */
+static int DeleteInner( playlist_t * p_playlist, playlist_item_t *p_item,
+ bool b_stop )
+{
+ int i;
+ int i_id = p_item->i_id;
+ bool b_delay_deletion = false;
+
+ if( p_item->i_children > -1 )
+ {
+ return playlist_NodeDelete( p_playlist, p_item, true, false );
+ }
+ p_playlist->b_reset_currently_playing = true;
+ var_SetInteger( p_playlist, "item-deleted", i_id );
+
+ /* Remove the item from the bank */
+ ARRAY_BSEARCH( p_playlist->all_items,->i_id, int, i_id, i );
+ if( i != -1 )
+ ARRAY_REMOVE( p_playlist->all_items, i );
+
+ ARRAY_BSEARCH( p_playlist->items,->i_id, int, i_id, i );
+ if( i != -1 )
+ ARRAY_REMOVE( p_playlist->items, i );
+
+ /* Check if it is the current item */
+ if( p_playlist->status.p_item == p_item )
+ {
+ /* Hack we don't call playlist_Control for lock reasons */
+ if( b_stop )
+ {
+ p_playlist->request.i_status = PLAYLIST_STOPPED;
+ p_playlist->request.b_request = true;
+ p_playlist->request.p_item = NULL;
+ msg_Info( p_playlist, "stopping playback" );
+ vlc_cond_signal( &p_playlist->object_wait );
+ }
+ b_delay_deletion = true;