/** * 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); PL_LOCK; for( ;; ) { while( p_sys->p_input != NULL ) LoopInput( p_playlist ); if( p_sys->killed ) break; /* THE END */ const int status = p_sys->request.b_request ? p_sys->request.i_status : p_sys->status.i_status; /* Destroy any video display if the playlist is supposed to stop */ if( status == PLAYLIST_STOPPED && 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 ); return NULL; }
static void LoopRequest( 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 */ const int i_status = p_sys->request.b_request ? p_sys->request.i_status : p_sys->status.i_status; if( i_status == PLAYLIST_STOPPED || !vlc_object_alive( p_playlist ) ) { p_sys->status.i_status = PLAYLIST_STOPPED; if( p_sys->p_input_resource && input_resource_HasVout( p_sys->p_input_resource ) ) { /* XXX We can unlock if we don't issue the wait as we will be * call again without anything else done between the calls */ PL_UNLOCK; /* input_resource_t must be manipulated without playlist lock */ input_resource_TerminateVout( p_sys->p_input_resource ); PL_LOCK; } else { if( vlc_object_alive( p_playlist ) ) 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" ); PlayItem( p_playlist, p_item ); return; } msg_Dbg( p_playlist, "nothing to play" ); p_sys->status.i_status = PLAYLIST_STOPPED; if( var_GetBool( p_playlist, "play-and-exit" ) ) { msg_Info( p_playlist, "end of playlist, exiting" ); libvlc_Quit( p_playlist->p_libvlc ); } }
/** * 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); 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; } while( !p_sys->killed && Next( p_playlist ) ) { /* Playlist in running state */ assert(p_sys->p_input != NULL); do LoopInput( p_playlist ); while( p_sys->p_input != NULL ); } 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; } } PL_UNLOCK; input_resource_Terminate( p_sys->p_input_resource ); return NULL; }