}
case PLAYLIST_PLAY:
- if( pl_priv(p_playlist)->p_input )
- {
- pl_priv(p_playlist)->status.i_status = PLAYLIST_RUNNING;
- var_SetInteger( pl_priv(p_playlist)->p_input, "state", PLAYING_S );
- break;
- }
- else
+ 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 )
- { /* FIXME: is this really useful without input? */
- pl_priv(p_playlist)->status.i_status = PLAYLIST_PAUSED;
- /* return without notifying the playlist thread as there is nothing to do */
- return;
+ 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 )
- {
- pl_priv(p_playlist)->status.i_status = PLAYLIST_RUNNING;
var_SetInteger( pl_priv(p_playlist)->p_input, "state", PLAYING_S );
- }
else
- {
- pl_priv(p_playlist)->status.i_status = PLAYLIST_PAUSED;
var_SetInteger( pl_priv(p_playlist)->p_input, "state", PAUSE_S );
- }
break;
case PLAYLIST_SKIP:
*
* \param p_playlist the playlist object
* \param p_item the item to play
- * \return nothing
*/
-static void PlayItem( playlist_t *p_playlist, playlist_item_t *p_item )
+static bool PlayItem( playlist_t *p_playlist, playlist_item_t *p_item )
{
playlist_private_t *p_sys = pl_priv(p_playlist);
input_item_t *p_input = p_item->p_input;
p_item->i_nb_played++;
set_current_status_item( p_playlist, p_item );
-
- p_sys->status.i_status = PLAYLIST_RUNNING;
-
assert( p_sys->p_input == NULL );
PL_UNLOCK;
PL_LOCK;
p_sys->p_input = p_input_thread;
+ return p_input_thread != NULL;
}
/**
/* Start the real work */
if( p_sys->request.b_request )
{
+ /* Clear the request */
+ p_sys->request.b_request = false;
+
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 ),
p_new = ARRAY_VAL( p_playlist->current,
p_playlist->i_current_index );
}
- /* Clear the request */
- p_sys->request.b_request = false;
}
/* "Automatic" item change ( next ) */
else
vlc_cond_wait( &p_sys->signal, &p_sys->lock );
}
-static void LoopRequest( playlist_t *p_playlist, int i_status )
+static bool Next( playlist_t *p_playlist )
{
- playlist_private_t *p_sys = pl_priv(p_playlist);
- assert( !p_sys->p_input );
-
- /* No input. Several cases
- * - No request, running status -> start new item
- * - No request, stopped status -> collect garbage
- * - Request, running requested -> start new item
- * - Request, stopped requested -> collect garbage
- */
- if( i_status == PLAYLIST_STOPPED )
- {
- p_sys->status.i_status = PLAYLIST_STOPPED;
- vlc_cond_wait( &p_sys->signal, &p_sys->lock );
- return;
- }
-
playlist_item_t *p_item = NextItem( p_playlist );
- if( p_item )
- {
- msg_Dbg( p_playlist, "starting playback of the new playlist item" );
- ResyncCurrentIndex( p_playlist, p_item );
- PlayItem( p_playlist, p_item );
- return;
- }
-
- msg_Dbg( p_playlist, "nothing to play" );
- p_sys->status.i_status = PLAYLIST_STOPPED;
+ if( p_item == NULL )
+ return false;
- if( var_InheritBool( p_playlist, "play-and-exit" ) )
- {
- msg_Info( p_playlist, "end of playlist, exiting" );
- libvlc_Quit( p_playlist->p_libvlc );
- }
+ msg_Dbg( p_playlist, "starting playback of new item" );
+ ResyncCurrentIndex( p_playlist, p_item );
+ return PlayItem( p_playlist, p_item );
}
/**
playlist_private_t *p_sys = pl_priv(p_playlist);
PL_LOCK;
- for( ;; )
+ while( !p_sys->killed )
{
- while( p_sys->p_input != NULL )
- LoopInput( p_playlist );
+ /* 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;
+ }
- if( p_sys->killed )
- break; /* THE END */
+ while( !p_sys->killed && Next( p_playlist ) )
+ { /* Playlist in running state */
+ assert(p_sys->p_input != NULL);
- int status = p_sys->status.i_status;
- if( p_sys->request.b_request )
- status = (p_sys->request.p_item || p_sys->request.p_node)
- ? PLAYLIST_RUNNING : PLAYLIST_STOPPED;
+ do
+ LoopInput( p_playlist );
+ while( p_sys->p_input != NULL );
+ }
- /* Destroy any video display if the playlist is supposed to stop */
- if( status == PLAYLIST_STOPPED
- && input_resource_HasVout( p_sys->p_input_resource ) )
+ msg_Dbg( p_playlist, "nothing to play" );
+ if( var_InheritBool( p_playlist, "play-and-exit" ) )
+ {
+ msg_Info( p_playlist, "end of playlist, exiting" );
+ libvlc_Quit( p_playlist->p_libvlc );
+ }
+
+ /* Destroy any video display now (XXX: ugly hack) */
+ if( input_resource_HasVout( p_sys->p_input_resource ) )
{
PL_UNLOCK; /* Mind: NO LOCKS while manipulating input resources! */
input_resource_TerminateVout( p_sys->p_input_resource );
PL_LOCK;
- continue; /* lost lock = lost state */
}
-
- LoopRequest( p_playlist, status );
}
- p_sys->status.i_status = PLAYLIST_STOPPED;
PL_UNLOCK;
input_resource_Terminate( p_sys->p_input_resource );