📄 playlist.c
字号:
val.i_int = PLAYING_S; var_Set( p_playlist->p_input, "state", val ); break; } /* FIXME : needed ? */ p_playlist->request.b_request = VLC_TRUE; p_playlist->request.i_view = p_playlist->status.i_view; p_playlist->request.p_node = p_playlist->status.p_node; p_playlist->request.p_item = p_playlist->status.p_item; p_playlist->request.i_skip = 0; p_playlist->request.i_goto = -1; break; case PLAYLIST_AUTOPLAY: p_playlist->status.i_status = PLAYLIST_RUNNING; p_playlist->request.b_request = VLC_FALSE; break; case PLAYLIST_PAUSE: val.i_int = 0; if( p_playlist->p_input ) var_Get( p_playlist->p_input, "state", &val ); if( val.i_int == PAUSE_S ) { p_playlist->status.i_status = PLAYLIST_RUNNING; if( p_playlist->p_input ) { val.i_int = PLAYING_S; var_Set( p_playlist->p_input, "state", val ); } } else { p_playlist->status.i_status = PLAYLIST_PAUSED; if( p_playlist->p_input ) { val.i_int = PAUSE_S; var_Set( p_playlist->p_input, "state", val ); } } break; case PLAYLIST_SKIP: if( p_playlist->status.i_view > -1 ) { p_playlist->request.i_view = p_playlist->status.i_view; p_playlist->request.p_node = p_playlist->status.p_node; p_playlist->request.p_item = p_playlist->status.p_item; } p_playlist->request.i_skip = (int) va_arg( args, int ); p_playlist->request.b_request = VLC_TRUE; break; case PLAYLIST_GOTO: p_playlist->status.i_status = PLAYLIST_RUNNING; p_playlist->request.p_node = NULL; p_playlist->request.p_item = NULL; p_playlist->request.i_view = -1; p_playlist->request.i_goto = (int) va_arg( args, int ); p_playlist->request.b_request = VLC_TRUE; break; default: msg_Err( p_playlist, "unimplemented playlist query" ); return VLC_EBADVAR; break; } return VLC_SUCCESS;}int playlist_PreparseEnqueue( playlist_t *p_playlist, input_item_t *p_item ){ vlc_mutex_lock( &p_playlist->p_preparse->object_lock ); INSERT_ELEM( p_playlist->p_preparse->pp_waiting, p_playlist->p_preparse->i_waiting, p_playlist->p_preparse->i_waiting, p_item ); vlc_mutex_unlock( &p_playlist->p_preparse->object_lock ); return VLC_SUCCESS;}/* Destroy remaining objects */static mtime_t ObjectGarbageCollector( playlist_t *p_playlist, int i_type, mtime_t destroy_date ){ vlc_object_t *p_obj; if( destroy_date > mdate() ) return destroy_date; if( destroy_date == 0 ) { /* give a little time */ return mdate() + I64C(1000000); } else { vlc_mutex_lock( &p_playlist->gc_lock ); while( ( p_obj = vlc_object_find( p_playlist, i_type, FIND_CHILD ) ) ) { if( p_obj->p_parent != (vlc_object_t*)p_playlist ) { /* only first child (ie unused) */ vlc_object_release( p_obj ); break; } if( i_type == VLC_OBJECT_VOUT ) { msg_Dbg( p_playlist, "garbage collector destroying 1 vout" ); vlc_object_detach( p_obj ); vlc_object_release( p_obj ); vout_Destroy( (vout_thread_t *)p_obj ); } else if( i_type == VLC_OBJECT_SOUT ) { vlc_object_release( p_obj ); sout_DeleteInstance( (sout_instance_t*)p_obj ); } } vlc_mutex_unlock( &p_playlist->gc_lock ); return 0; }}/***************************************************************************** * RunThread: main playlist thread *****************************************************************************/static void RunThread ( playlist_t *p_playlist ){ vlc_object_t *p_obj; playlist_item_t *p_item = NULL; mtime_t i_vout_destroyed_date = 0; mtime_t i_sout_destroyed_date = 0; playlist_item_t *p_autodelete_item = NULL; /* Tell above that we're ready */ vlc_thread_ready( p_playlist ); while( !p_playlist->b_die ) { vlc_mutex_lock( &p_playlist->object_lock ); /* First, check if we have something to do */ /* FIXME : this can be called several times */ if( p_playlist->request.b_request ) {#ifdef PLAYLIST_PROFILE msg_Dbg(p_playlist, "beginning processing of request, " I64Fi" us ", mdate() - p_playlist->request_date );#endif /* Stop the existing input */ if( p_playlist->p_input ) { input_StopThread( p_playlist->p_input ); } /* The code below will start the next input for us */ if( p_playlist->status.i_status == PLAYLIST_STOPPED ) { p_playlist->request.b_request = VLC_FALSE; } } /* If there is an input, check that it doesn't need to die. */ if( p_playlist->p_input ) { /* This input is dead. Remove it ! */ if( p_playlist->p_input->b_dead ) { input_thread_t *p_input; p_input = p_playlist->p_input; p_playlist->p_input = NULL; /* Release the playlist lock, because we may get stuck * in input_DestroyThread() for some time. */ vlc_mutex_unlock( &p_playlist->object_lock ); /* Destroy input */ input_DestroyThread( p_input ); /* Unlink current input * (_after_ input_DestroyThread for vout garbage collector) */ vlc_object_detach( p_input ); /* Destroy object */ vlc_object_destroy( p_input ); i_vout_destroyed_date = 0; i_sout_destroyed_date = 0; if( p_playlist->status.p_item->i_flags & PLAYLIST_REMOVE_FLAG ) { playlist_ItemDelete( p_item ); p_playlist->status.p_item = NULL; } continue; } /* This input is dying, let him do */ else if( p_playlist->p_input->b_die ) { ; } /* This input has finished, ask him to die ! */ else if( p_playlist->p_input->b_error || p_playlist->p_input->b_eof ) { /* TODO FIXME XXX TODO FIXME XXX */ /* Check for autodeletion */ if( p_playlist->status.p_item->i_flags & PLAYLIST_DEL_FLAG ) { p_autodelete_item = p_playlist->status.p_item; } input_StopThread( p_playlist->p_input ); /* Select the next playlist item */ vlc_mutex_unlock( &p_playlist->object_lock ); continue; } else if( p_playlist->p_input->i_state != INIT_S ) { vlc_mutex_unlock( &p_playlist->object_lock ); i_vout_destroyed_date = ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT, i_vout_destroyed_date ); i_sout_destroyed_date = ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT, i_sout_destroyed_date ); vlc_mutex_lock( &p_playlist->object_lock ); } } else if( p_playlist->status.i_status != PLAYLIST_STOPPED ) { /* Start another input. * Get the next item to play */ p_item = NextItem( p_playlist ); /* We must stop */ if( p_item == NULL ) { if( p_autodelete_item ) { playlist_Delete( p_playlist, p_autodelete_item->input.i_id ); p_autodelete_item = NULL; } p_playlist->status.i_status = PLAYLIST_STOPPED; vlc_mutex_unlock( &p_playlist->object_lock ); continue; } PlayItem( p_playlist, p_item ); if( p_autodelete_item ) { playlist_Delete( p_playlist, p_autodelete_item->input.i_id ); p_autodelete_item = NULL; } } else if( p_playlist->status.i_status == PLAYLIST_STOPPED ) { /* Collect garbage */ vlc_mutex_unlock( &p_playlist->object_lock ); i_sout_destroyed_date = ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT, mdate() ); i_vout_destroyed_date = ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT, mdate() ); vlc_mutex_lock( &p_playlist->object_lock ); } vlc_mutex_unlock( &p_playlist->object_lock ); msleep( INTF_IDLE_SLEEP / 2 ); /* Stop sleeping earlier if we have work */ /* TODO : statistics about this */ if ( p_playlist->request.b_request && p_playlist->status.i_status == PLAYLIST_RUNNING ) { continue; } msleep( INTF_IDLE_SLEEP / 2 ); } /* Playlist dying */ /* If there is an input, kill it */ while( 1 ) { vlc_mutex_lock( &p_playlist->object_lock ); if( p_playlist->p_input == NULL ) { vlc_mutex_unlock( &p_playlist->object_lock ); break; } if( p_playlist->p_input->b_dead ) { input_thread_t *p_input; /* Unlink current input */ p_input = p_playlist->p_input; p_playlist->p_input = NULL; vlc_mutex_unlock( &p_playlist->object_lock ); /* Destroy input */ input_DestroyThread( p_input ); /* Unlink current input (_after_ input_DestroyThread for vout * garbage collector)*/ vlc_object_detach( p_input ); /* Destroy object */ vlc_object_destroy( p_input ); continue; } else if( p_playlist->p_input->b_die ) { /* This input is dying, leave him alone */ ; } else if( p_playlist->p_input->b_error || p_playlist->p_input->b_eof ) { input_StopThread( p_playlist->p_input ); vlc_mutex_unlock( &p_playlist->object_lock ); continue; } else { p_playlist->p_input->b_eof = 1; } vlc_mutex_unlock( &p_playlist->object_lock ); msleep( INTF_IDLE_SLEEP ); } /* close all remaining sout */ while( ( p_obj = vlc_object_find( p_playlist, VLC_OBJECT_SOUT, FIND_CHILD ) ) ) { vlc_object_release( p_obj ); sout_DeleteInstance( (sout_instance_t*)p_obj ); } /* close all remaining vout */ while( ( p_obj = vlc_object_find( p_playlist, VLC_OBJECT_VOUT, FIND_CHILD ) ) ) { vlc_object_detach( p_obj ); vlc_object_release( p_obj ); vout_Destroy( (vout_thread_t *)p_obj ); }}/* Queue for items to preparse */static void RunPreparse ( playlist_preparse_t *p_obj )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -