/*****************************************************************************
* item.c : Playlist item creation/deletion/add/removal functions
*****************************************************************************
- * Copyright (C) 1999-2004 the VideoLAN team
+ * Copyright (C) 1999-2007 the VideoLAN team
* $Id$
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include <vlc/vlc.h>
-#include <vlc/input.h>
#include <assert.h>
#include <vlc_playlist.h>
#include "playlist_internal.h"
-void AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
- playlist_item_t *p_node, int i_pos );
-void GoAndPreparse( playlist_t *p_playlist, int i_mode,
- playlist_item_t *, playlist_item_t * );
-void ChangeToNode( playlist_t *p_playlist, playlist_item_t *p_item );
-int DeleteInner( playlist_t * p_playlist, playlist_item_t *p_item,
- vlc_bool_t b_stop );
+static void AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
+ playlist_item_t *p_node, int i_mode, int i_pos );
+static void GoAndPreparse( playlist_t *p_playlist, int i_mode,
+ playlist_item_t *, playlist_item_t * );
+static void ChangeToNode( playlist_t *p_playlist, playlist_item_t *p_item );
+static int DeleteInner( playlist_t * p_playlist, playlist_item_t *p_item,
+ vlc_bool_t b_stop );
/*****************************************************************************
* Playlist item creation
int playlist_DeleteFromInput( playlist_t *p_playlist, int i_input_id,
vlc_bool_t b_locked )
{
+ int i_ret1, i_ret2;
if( !b_locked ) PL_LOCK;
- DeleteFromInput( p_playlist, i_input_id,
- p_playlist->p_root_category, VLC_TRUE );
- DeleteFromInput( p_playlist, i_input_id,
+ i_ret1 = DeleteFromInput( p_playlist, i_input_id,
+ p_playlist->p_root_category, VLC_TRUE );
+ i_ret2 = DeleteFromInput( p_playlist, i_input_id,
p_playlist->p_root_onelevel, VLC_TRUE );
if( !b_locked ) PL_UNLOCK;
- return VLC_SUCCESS;
+ return ( i_ret1 == VLC_SUCCESS || i_ret2 == VLC_SUCCESS ) ?
+ VLC_SUCCESS : VLC_ENOITEM;
}
-/** Clear the playlist */
void playlist_Clear( playlist_t * p_playlist, vlc_bool_t b_locked )
{
if( !b_locked ) PL_LOCK;
* This function is to be used only by the playlist */
int playlist_DeleteFromItemId( playlist_t *p_playlist, int i_id )
{
- playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id, VLC_TRUE );
+ playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id,
+ VLC_TRUE );
if( !p_item ) return VLC_EGENERIC;
return DeleteInner( p_playlist, p_item, VLC_TRUE );
}
*/
int playlist_Add( playlist_t *p_playlist, const char *psz_uri,
const char *psz_name, int i_mode, int i_pos,
- vlc_bool_t b_playlist )
+ vlc_bool_t b_playlist, vlc_bool_t b_locked )
{
return playlist_AddExt( p_playlist, psz_uri, psz_name,
- i_mode, i_pos, -1, NULL, 0, b_playlist );
+ i_mode, i_pos, -1, NULL, 0, b_playlist, b_locked );
}
/**
int playlist_AddExt( playlist_t *p_playlist, const char * psz_uri,
const char *psz_name, int i_mode, int i_pos,
mtime_t i_duration, const char *const *ppsz_options,
- int i_options, vlc_bool_t b_playlist )
+ int i_options, vlc_bool_t b_playlist, vlc_bool_t b_locked )
{
+ int i_ret;
input_item_t *p_input = input_ItemNewExt( p_playlist, psz_uri, psz_name,
i_options, ppsz_options,
i_duration );
- return playlist_AddInput( p_playlist, p_input, i_mode, i_pos, b_playlist );
+ i_ret = playlist_AddInput( p_playlist, p_input, i_mode, i_pos, b_playlist,
+ b_locked );
+ if( i_ret == VLC_SUCCESS )
+ return p_input->i_id;
+ return -1;
}
/** Add an input item to the playlist node */
int playlist_AddInput( playlist_t* p_playlist, input_item_t *p_input,
- int i_mode, int i_pos, vlc_bool_t b_playlist )
+ int i_mode, int i_pos, vlc_bool_t b_playlist,
+ vlc_bool_t b_locked )
{
playlist_item_t *p_item_cat, *p_item_one;
PL_DEBUG( "adding item `%s' ( %s )", p_input->psz_name,
p_input->psz_uri );
- vlc_mutex_lock( &p_playlist->object_lock );
+ if( !b_locked ) PL_LOCK;
/* Add to ONELEVEL */
p_item_one = playlist_ItemNewFromInput( p_playlist, p_input );
- if( p_item_one == NULL ) return VLC_EGENERIC;
+ if( p_item_one == NULL ) return VLC_ENOMEM;
AddItem( p_playlist, p_item_one,
b_playlist ? p_playlist->p_local_onelevel :
- p_playlist->p_ml_onelevel , i_pos );
+ p_playlist->p_ml_onelevel , i_mode, i_pos );
/* Add to CATEGORY */
p_item_cat = playlist_ItemNewFromInput( p_playlist, p_input );
- if( p_item_cat == NULL ) return VLC_EGENERIC;
+ if( p_item_cat == NULL ) return VLC_ENOMEM;
AddItem( p_playlist, p_item_cat,
b_playlist ? p_playlist->p_local_category :
- p_playlist->p_ml_category , i_pos );
+ p_playlist->p_ml_category , i_mode, i_pos );
GoAndPreparse( p_playlist, i_mode, p_item_cat, p_item_one );
- vlc_mutex_unlock( &p_playlist->object_lock );
+ if( !b_locked ) PL_UNLOCK;
return VLC_SUCCESS;
}
input_item_t *p_input,
playlist_item_t *p_direct_parent,
int i_mode, int i_pos,
- int *i_cat, int *i_one )
+ int *i_cat, int *i_one, vlc_bool_t b_locked )
{
playlist_item_t *p_item_cat, *p_item_one, *p_up;
int i_top;
assert( p_input );
- vlc_mutex_lock( & p_playlist->object_lock );
+ if( !b_locked ) PL_LOCK;
/* Add to category */
p_item_cat = playlist_ItemNewFromInput( p_playlist, p_input );
- if( p_item_cat == NULL ) return VLC_EGENERIC;
- AddItem( p_playlist, p_item_cat, p_direct_parent, i_pos );
+ if( p_item_cat == NULL ) return VLC_ENOMEM;
+ AddItem( p_playlist, p_item_cat, p_direct_parent, i_mode, i_pos );
/* Add to onelevel */
/** \todo make a faster case for ml import */
p_item_one = playlist_ItemNewFromInput( p_playlist, p_input );
- if( p_item_one == NULL ) return VLC_EGENERIC;
+ if( p_item_one == NULL ) return VLC_ENOMEM;
p_up = p_direct_parent;
while( p_up->p_parent != p_playlist->p_root_category )
p_up->p_input->i_id )
{
AddItem( p_playlist, p_item_one,
- p_playlist->p_root_onelevel->pp_children[i_top], i_pos );
+ p_playlist->p_root_onelevel->pp_children[i_top],
+ i_mode, i_pos );
break;
}
}
if( i_cat ) *i_cat = p_item_cat->i_id;
if( i_one ) *i_one = p_item_one->i_id;
- vlc_mutex_unlock( &p_playlist->object_lock );
+ if( !b_locked ) PL_UNLOCK;
return VLC_SUCCESS;
}
playlist_item_t * playlist_NodeAddInput( playlist_t *p_playlist,
input_item_t *p_input,
playlist_item_t *p_parent,
- int i_mode, int i_pos )
+ int i_mode, int i_pos,
+ vlc_bool_t b_locked )
{
playlist_item_t *p_item;
assert( p_input );
assert( p_parent && p_parent->i_children != -1 );
- vlc_mutex_lock( &p_playlist->object_lock );
+ if( !b_locked ) PL_LOCK;
p_item = playlist_ItemNewFromInput( p_playlist, p_input );
if( p_item == NULL ) return NULL;
- AddItem( p_playlist, p_item, p_parent, i_pos );
+ AddItem( p_playlist, p_item, p_parent, i_mode, i_pos );
- vlc_mutex_unlock( &p_playlist->object_lock );
+ if( !b_locked ) PL_UNLOCK;
return p_item;
}
{
int j;
playlist_item_t *p_detach = p_item->p_parent;
+ (void)p_playlist;
+
if( p_node->i_children == -1 ) return VLC_EGENERIC;
for( j = 0; j < p_detach->i_children; j++ )
/** Send a notification that an item has been added to a node */
void playlist_SendAddNotify( playlist_t *p_playlist, int i_item_id,
- int i_node_id )
+ int i_node_id, vlc_bool_t b_signal )
{
vlc_value_t val;
playlist_add_t *p_add = (playlist_add_t *)malloc(sizeof( playlist_add_t));
p_add->i_node = i_node_id;
val.p_address = p_add;
p_playlist->b_reset_currently_playing = VLC_TRUE;
- vlc_cond_signal( &p_playlist->object_wait );
+ if( b_signal )
+ vlc_cond_signal( &p_playlist->object_wait );
var_Set( p_playlist, "item-append", val );
free( p_add );
}
***************************************************************************/
/* Enqueue an item for preparsing, and play it, if needed */
-void GoAndPreparse( playlist_t *p_playlist, int i_mode,
- playlist_item_t *p_item_cat, playlist_item_t *p_item_one )
+static void GoAndPreparse( playlist_t *p_playlist, int i_mode,
+ playlist_item_t *p_item_cat,
+ playlist_item_t *p_item_one )
{
if( (i_mode & PLAYLIST_GO ) )
{
}
/* Add the playlist item to the requested node and fire a notification */
-void AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
- playlist_item_t *p_node, int i_pos )
+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);
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 );
+ playlist_SendAddNotify( p_playlist, p_item->i_id, p_node->i_id,
+ !( i_mode & PLAYLIST_NO_REBUILD ) );
}
/* Actually convert an item to a node */
-void ChangeToNode( playlist_t *p_playlist, playlist_item_t *p_item )
+static void ChangeToNode( playlist_t *p_playlist, playlist_item_t *p_item )
{
int i;
if( p_item->i_children == -1 )
}
/* Do the actual removal */
-int DeleteInner( playlist_t * p_playlist, playlist_item_t *p_item,
- vlc_bool_t b_stop )
+static int DeleteInner( playlist_t * p_playlist, playlist_item_t *p_item,
+ vlc_bool_t b_stop )
{
int i;
int i_id = p_item->i_id;
- vlc_bool_t b_flag = VLC_FALSE;
+ vlc_bool_t b_delay_deletion = VLC_FALSE;
if( p_item->i_children > -1 )
{
msg_Info( p_playlist, "stopping playback" );
vlc_cond_signal( &p_playlist->object_wait );
}
- b_flag = VLC_TRUE;
+ b_delay_deletion = VLC_TRUE;
}
PL_DEBUG( "deleting item `%s'", p_item->p_input->psz_name );
/* Remove the item from its parent */
playlist_NodeRemoveItem( p_playlist, p_item, p_item->p_parent );
- if( b_flag == VLC_FALSE )
+ if( !b_delay_deletion )
playlist_ItemDelete( p_item );
else
{