* playlist.c : Playlist management functions
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: playlist.c,v 1.8 2002/06/07 19:54:37 sam Exp $
+ * $Id: playlist.c,v 1.23 2002/11/21 15:51:57 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
#include <stdlib.h> /* free(), strtol() */
#include <stdio.h> /* sprintf() */
#include <string.h> /* strerror() */
-#include <errno.h> /* ENOMEM */
#include <vlc/vlc.h>
#include "stream_control.h"
#include "input_ext-intf.h"
-#include "playlist.h"
+#include "vlc_playlist.h"
#define PLAYLIST_STOPPED 0
#define PLAYLIST_RUNNING 1
}
p_playlist->p_input = NULL;
- p_playlist->i_status = PLAYLIST_RUNNING;
+ p_playlist->i_status = PLAYLIST_STOPPED;
p_playlist->i_index = -1;
p_playlist->i_size = 0;
p_playlist->pp_items = NULL;
- if( vlc_thread_create( p_playlist, "playlist", RunThread, VLC_TRUE ) )
+ if( vlc_thread_create( p_playlist, "playlist", RunThread,
+ VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
{
msg_Err( p_playlist, "cannot spawn playlist thread" );
vlc_object_destroy( p_playlist );
{
playlist_item_t *p_item;
- msg_Warn( p_playlist, "adding playlist item « %s »", psz_target );
+ msg_Dbg( p_playlist, "adding playlist item « %s »", psz_target );
/* Create the new playlist item */
p_item = malloc( sizeof( playlist_item_t ) );
p_item->psz_name = strdup( psz_target );
p_item->i_type = 0;
p_item->i_status = 0;
+ p_item->b_autodeletion = VLC_FALSE;
vlc_mutex_lock( &p_playlist->object_lock );
if( !(i_mode & PLAYLIST_REPLACE)
|| i_pos < 0 || i_pos >= p_playlist->i_size )
{
- int i_index;
-
- p_playlist->i_size++;
- p_playlist->pp_items = realloc( p_playlist->pp_items,
- p_playlist->i_size * sizeof(void*) );
- if( p_playlist->pp_items == NULL )
- {
- msg_Err( p_playlist, "out of memory" );
- free( p_item->psz_name );
- free( p_item );
- vlc_mutex_unlock( &p_playlist->object_lock );
- return -1;
- }
-
/* Additional boundary checks */
if( i_mode & PLAYLIST_APPEND )
{
{
i_pos = 0;
}
- else if( i_pos > p_playlist->i_size - 1 )
+ else if( i_pos > p_playlist->i_size )
{
- i_pos = p_playlist->i_size - 1;
+ i_pos = p_playlist->i_size;
}
- /* Now we know exactly where it goes. Just renumber the playlist */
- for( i_index = p_playlist->i_size - 1; i_index > i_pos ; i_index-- )
- {
- p_playlist->pp_items[i_index] = p_playlist->pp_items[i_index - 1];
- }
+ INSERT_ELEM( p_playlist->pp_items,
+ p_playlist->i_size,
+ i_pos,
+ p_item );
if( p_playlist->i_index >= i_pos )
{
{
/* i_mode == PLAYLIST_REPLACE and 0 <= i_pos < p_playlist->i_size */
free( p_playlist->pp_items[i_pos]->psz_name );
- free( p_playlist->pp_items[i_pos] );
/* XXX: what if the item is still in use? */
+ free( p_playlist->pp_items[i_pos] );
+ p_playlist->pp_items[i_pos] = p_item;
}
- p_playlist->pp_items[i_pos] = p_item;
-
if( i_mode & PLAYLIST_GO )
{
p_playlist->i_index = i_pos;
*****************************************************************************/
int playlist_Delete( playlist_t * p_playlist, int i_pos )
{
- int i_index;
-
vlc_mutex_lock( &p_playlist->object_lock );
if( i_pos >= 0 && i_pos < p_playlist->i_size )
{
- msg_Warn( p_playlist, "deleting playlist item « %s »",
- p_playlist->pp_items[i_pos]->psz_name );
+ msg_Dbg( p_playlist, "deleting playlist item « %s »",
+ p_playlist->pp_items[i_pos]->psz_name );
free( p_playlist->pp_items[i_pos]->psz_name );
- free( p_playlist->pp_items[i_pos] );
/* XXX: what if the item is still in use? */
+ free( p_playlist->pp_items[i_pos] );
- if( i_pos < p_playlist->i_index )
+ if( i_pos <= p_playlist->i_index )
{
p_playlist->i_index--;
}
/* Renumber the playlist */
- for( i_index = i_pos + 1; i_index < p_playlist->i_size; i_index++ )
- {
- p_playlist->pp_items[i_index - 1] = p_playlist->pp_items[i_index];
- }
-
- p_playlist->i_size--;
- if( p_playlist->i_size )
- {
- p_playlist->pp_items = realloc( p_playlist->pp_items,
- p_playlist->i_size * sizeof(void*) );
- }
- else
- {
- free( p_playlist->pp_items );
- p_playlist->pp_items = NULL;
- }
+ REMOVE_ELEM( p_playlist->pp_items,
+ p_playlist->i_size,
+ i_pos );
}
vlc_mutex_unlock( &p_playlist->object_lock );
/* Unlink current input */
p_input = p_playlist->p_input;
p_playlist->p_input = NULL;
- vlc_object_detach_all( p_input );
+ vlc_object_detach( p_input );
/* Release the playlist lock, because we may get stuck
* in input_DestroyThread() for some time. */
else if( p_playlist->p_input->b_error
|| p_playlist->p_input->b_eof )
{
+ /* Check for autodeletion */
+ if( p_playlist->pp_items[p_playlist->i_index]->b_autodeletion )
+ {
+ vlc_mutex_unlock( &p_playlist->object_lock );
+ playlist_Delete( p_playlist, p_playlist->i_index );
+ vlc_mutex_lock( &p_playlist->object_lock );
+ }
+
/* Select the next playlist item */
SkipItem( p_playlist, 1 );
/* Unlink current input */
p_input = p_playlist->p_input;
p_playlist->p_input = NULL;
- vlc_object_detach_all( p_input );
+ vlc_object_detach( p_input );
vlc_mutex_unlock( &p_playlist->object_lock );
/* Destroy input */
static void SkipItem( playlist_t *p_playlist, int i_arg )
{
int i_oldindex = p_playlist->i_index;
+ vlc_bool_t b_random;
/* If the playlist is empty, there is no current item */
if( p_playlist->i_size == 0 )
return;
}
+ b_random = config_GetInt( p_playlist, "random" );
+
/* Increment */
+ if( b_random )
+ {
+ srand( (unsigned int)mdate() );
+
+ /* Simple random stuff - we cheat a bit to minimize the chances to
+ * get the same index again. */
+ i_arg = (int)((float)p_playlist->i_size * rand() / (RAND_MAX+1.0));
+ if( i_arg == 0 )
+ {
+ i_arg = (int)((float)p_playlist->i_size * rand() / (RAND_MAX+1.0));
+ }
+ }
+
p_playlist->i_index += i_arg;
/* Boundary check */
if( p_playlist->i_index >= p_playlist->i_size )
{
if( p_playlist->i_status == PLAYLIST_STOPPED
+ || b_random
|| config_GetInt( p_playlist, "loop" ) )
{
- p_playlist->i_index = 0;
+ p_playlist->i_index -= p_playlist->i_size
+ * ( p_playlist->i_index / p_playlist->i_size );
}
else
{