📄 playlist.c
字号:
} /* 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 ){ playlist_t *p_playlist = (playlist_t *)p_obj->p_parent; vlc_bool_t b_sleep; /* Tell above that we're ready */ vlc_thread_ready( p_obj ); while( !p_playlist->b_die ) { vlc_mutex_lock( &p_obj->object_lock ); if( p_obj->i_waiting > 0 ) { int i_current_id = p_obj->pi_waiting[0]; playlist_item_t *p_current; REMOVE_ELEM( p_obj->pi_waiting, p_obj->i_waiting, 0 ); vlc_mutex_unlock( &p_obj->object_lock ); vlc_mutex_lock( &p_playlist->object_lock ); p_current = playlist_ItemGetById( p_playlist, i_current_id ); if( p_current ) { vlc_bool_t b_preparsed = VLC_FALSE; if( strncmp( p_current->input.psz_uri, "http:", 5 ) && strncmp( p_current->input.psz_uri, "rtsp:", 5 ) && strncmp( p_current->input.psz_uri, "udp:", 4 ) && strncmp( p_current->input.psz_uri, "mms:", 4 ) && strncmp( p_current->input.psz_uri, "cdda:", 4 ) && strncmp( p_current->input.psz_uri, "dvd:", 4 ) && strncmp( p_current->input.psz_uri, "v4l:", 4 ) && strncmp( p_current->input.psz_uri, "dshow:", 6 ) ) { b_preparsed = VLC_TRUE; stats_TimerStart( p_playlist, "Preparse run", STATS_TIMER_PREPARSE ); input_Preparse( p_playlist, &p_current->input ); stats_TimerStop( p_playlist, STATS_TIMER_PREPARSE ); } vlc_mutex_unlock( &p_playlist->object_lock ); if( b_preparsed ) { var_SetInteger( p_playlist, "item-change", p_current->input.i_id ); } } else vlc_mutex_unlock( &p_playlist->object_lock ); vlc_mutex_lock( &p_obj->object_lock ); } b_sleep = ( p_obj->i_waiting == 0 ); vlc_mutex_unlock( &p_obj->object_lock ); if( p_obj->i_waiting == 0 ) { msleep( INTF_IDLE_SLEEP ); } }}/***************************************************************************** * NextItem ***************************************************************************** * This function calculates the next playlist item, depending * on the playlist course mode (forward, backward, random, view,...). *****************************************************************************/static playlist_item_t * NextItem( playlist_t *p_playlist ){ playlist_item_t *p_new = NULL; int i_skip,i_goto,i, i_new, i_count ; playlist_view_t *p_view; vlc_bool_t b_loop = var_GetBool( p_playlist, "loop" ); vlc_bool_t b_random = var_GetBool( p_playlist, "random" ); vlc_bool_t b_repeat = var_GetBool( p_playlist, "repeat" ); vlc_bool_t b_playstop = var_GetBool( p_playlist, "play-and-stop" );#ifdef PLAYLIST_PROFILE /* Calculate time needed */ int64_t start = mdate();#endif /* Handle quickly a few special cases */ /* No items to play */ if( p_playlist->i_size == 0 ) { msg_Info( p_playlist, "playlist is empty" ); return NULL; } /* Nothing requested */ if( !p_playlist->request.b_request && p_playlist->status.p_item == NULL ) { msg_Dbg( p_playlist,"nothing requested, starting" ); } /* Repeat and play/stop */ if( !p_playlist->request.b_request && b_repeat == VLC_TRUE && p_playlist->status.p_item ) { msg_Dbg( p_playlist,"repeating item" ); return p_playlist->status.p_item; } if( !p_playlist->request.b_request && b_playstop == VLC_TRUE ) { msg_Dbg( p_playlist,"stopping (play and stop)"); return NULL; } if( !p_playlist->request.b_request && p_playlist->status.p_item && !( p_playlist->status.p_item->i_flags & PLAYLIST_SKIP_FLAG ) ) { msg_Dbg( p_playlist, "no-skip mode, stopping") ; return NULL; } /* TODO: improve this (only use current node) */ /* TODO: use the "shuffled view" internally ? */ /* Random case. This is an exception: if request, but request is skip +- 1 * we don't go to next item but select a new random one. */ if( b_random && ( !p_playlist->request.b_request || ( p_playlist->request.b_request && ( p_playlist->request.p_item == NULL || p_playlist->request.i_skip == 1 || p_playlist->request.i_skip == -1 ) ) ) ) { /* how many items to choose from ? */ i_count = 0; for ( i = 0; i < p_playlist->i_size; i++ ) { if ( p_playlist->pp_items[i]->i_nb_played == 0 ) i_count++; } /* Nothing left? */ if ( i_count == 0 ) { /* Don't loop? Exit! */ if( !b_loop ) return NULL; /* Otherwise reset the counter */ for ( i = 0; i < p_playlist->i_size; i++ ) { p_playlist->pp_items[i]->i_nb_played = 0; } i_count = p_playlist->i_size; } srand( (unsigned int)mdate() ); i = rand() % i_count + 1 ; /* loop thru the list and count down the unplayed items to the selected one */ for ( i_new = 0; i_new < p_playlist->i_size && i > 0; i_new++ ) { if ( p_playlist->pp_items[i_new]->i_nb_played == 0 ) i--; } i_new--; p_playlist->request.i_skip = 0; p_playlist->request.b_request = VLC_FALSE; return p_playlist->pp_items[i_new]; } /* Start the real work */ if( p_playlist->request.b_request ) {#ifdef PLAYLIST_DEBUG msg_Dbg( p_playlist,"processing request" );#endif /* We are not playing from a view */ if( p_playlist->request.i_view == -1 ) {#ifdef PLAYLIST_DEBUG msg_Dbg( p_playlist, "non-view mode request");#endif /* Directly select the item, just like now */ p_new = p_playlist->request.p_item; i_skip = p_playlist->request.i_skip; i_goto = p_playlist->request.i_goto; if( p_playlist->i_index < 0 ) p_playlist->i_index = 0; if ( p_new == NULL ) p_new = p_playlist->pp_items[p_playlist->i_index]; if( i_goto >= 0 && i_goto < p_playlist->i_size ) { p_playlist->i_index = i_goto; p_new = p_playlist->pp_items[p_playlist->i_index]; p_playlist->request.i_goto = -1; } if( i_skip != 0 ) { if( p_playlist->i_index + i_skip < p_playlist->i_size && p_playlist->i_index + i_skip >= 0 ) { p_playlist->i_index += i_skip; p_new = p_playlist->pp_items[p_playlist->i_index]; } p_playlist->request.i_skip = 0; } if( !( p_new->i_flags & PLAYLIST_SKIP_FLAG ) ) { return NULL; } } else {#ifdef PLAYLIST_DEBUG msg_Dbg( p_playlist, "view mode request" );#endif p_new = p_playlist->request.p_item; i_skip = p_playlist->request.i_skip; /* If we are asked for a node, take its first item */ if( p_playlist->request.p_item == NULL && i_skip == 0 ) { i_skip++; } p_view = playlist_ViewFind( p_playlist,p_playlist->request.i_view ); p_playlist->status.p_node = p_playlist->request.p_node; p_playlist->status.i_view = p_playlist->request.i_view; if( !p_view ) { msg_Err( p_playlist, "p_view is NULL and should not! (requested view is %i", p_playlist->request.i_view ); } else if( i_skip > 0 ) { for( i = i_skip; i > 0 ; i-- ) { p_new = playlist_FindNextFromParent( p_playlist, p_playlist->request.i_view, p_view->p_root, p_playlist->request.p_node, p_new ); if( p_new == NULL ) {#ifdef PLAYLIST_DEBUG msg_Dbg( p_playlist, "looping" );#endif p_new = playlist_FindNextFromParent( p_playlist, p_playlist->request.i_view, p_view->p_root, p_view->p_root, NULL ); if( p_new == NULL ) break; } } } else if( i_skip < 0 ) { for( i = i_skip; i < 0 ; i++ ) { p_new = playlist_FindPrevFromParent( p_playlist, p_playlist->request.i_view, p_view->p_root, p_playlist->request.p_node, p_new ); if( p_new == NULL ) { /* We reach the beginning of the playlist. Go back to the last item. */ p_new = playlist_RecursiveFindLast( p_playlist, p_view->p_root ); } if( p_new == NULL ) break; } } } /* Clear the request */ p_playlist->request.b_request = VLC_FALSE; } /* "Automatic" item change ( next ) */ else { p_playlist->request_date = 0; if( p_playlist->status.i_view == -1 ) {#ifdef PLAYLIST_DEBUG msg_Dbg( p_playlist, "no request - old mode" );#endif if( p_playlist->i_index + 1 < p_playlist->i_size ) { p_playlist->i_index++; p_new = p_playlist->pp_items[p_playlist->i_index]; if( !( p_new->i_flags & PLAYLIST_SKIP_FLAG ) ) { return NULL; } } else { if( b_loop && p_playlist->i_size > 0) { p_playlist->i_index = 0; p_new = p_playlist->pp_items[0]; } else p_new = NULL; } } /* We are playing with a view */ else {#ifdef PLAYLIST_DEBUG msg_Dbg( p_playlist,"no request - from a view" );#endif playlist_view_t *p_view = playlist_ViewFind( p_playlist, p_playlist->status.i_view ); if( !p_view ) { msg_Err( p_playlist, "p_view is NULL and should not! (FIXME)" ); } else { p_new = playlist_FindNextFromParent( p_playlist, p_playlist->status.i_view, p_view->p_root, p_playlist->status.p_node, p_playlist->status.p_item ); if( p_new == NULL && b_loop ) {#ifdef PLAYLIST_DEBUG msg_Dbg( p_playlist, "looping" );#endif p_new = playlist_FindNextFromParent( p_playlist, p_playlist->status.i_view, p_view->p_root, p_view->p_root, NULL ); } if( p_new != NULL && !(p_new->i_flags & PLAYLIST_SKIP_FLAG) ) return NULL; } } } /* Reset index */ if( p_playlist->i_index >= 0 && p_new != NULL && p_playlist->pp_items[p_playlist->i_index] != p_new ) { p_playlist->i_index = playlist_GetPositionById( p_playlist, p_new->input.i_id ); }#ifdef PLAYLIST_PROFILE msg_Dbg(p_playlist,"next item found in "I64Fi " us", mdate()-start );#endif if( p_new == NULL ) { msg_Info( p_playlist, "nothing to play" ); } return p_new;}/***************************************************************************** * PlayItem: start the input thread for an item ****************************************************************************/static int PlayItem( playlist_t *p_playlist, playlist_item_t *p_item ){ vlc_value_t val; msg_Dbg( p_playlist, "creating new input thread" ); p_item->i_nb_played++; p_playlist->status.p_item = p_item; p_playlist->i_index = playlist_GetPositionById( p_playlist, p_item->input.i_id );#ifdef PLAYLIST_PROFILE if( p_playlist->request_date != 0 ) { msg_Dbg( p_playlist, "request processed after "I64Fi " us", mdate() - p_playlist->request_date ); }#endif p_playlist->p_input = input_CreateThread( p_playlist, &p_item->input ); val.i_int = p_item->input.i_id; /* unlock the playlist to set the var...mmm */ vlc_mutex_unlock( &p_playlist->object_lock); var_Set( p_playlist, "playlist-current", val); vlc_mutex_lock( &p_playlist->object_lock); return VLC_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -