From: Clément Stenac Date: Sat, 21 Oct 2006 16:59:09 +0000 (+0000) Subject: Rebuild the array of currently playing items as a background task. X-Git-Tag: 0.9.0-test0~9843 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=b6d0e5a07a9a32894e31da69e25e81dec0366dc5;p=vlc Rebuild the array of currently playing items as a background task. This array is now usable as a reliable source of data for size Use playlist_CurrentSize(p_playlist) to retrieve the size of the current playset. --- diff --git a/include/vlc_messages.h b/include/vlc_messages.h index 00f4c1dcd5..5a8f659dc1 100644 --- a/include/vlc_messages.h +++ b/include/vlc_messages.h @@ -259,7 +259,7 @@ enum STATS_DISPLAYED_PICTURES, STATS_LOST_PICTURES, - STATS_TIMER_PLAYLIST_WALK, + STATS_TIMER_PLAYLIST_BUILD, STATS_TIMER_ML_LOAD, STATS_TIMER_ML_DUMP, STATS_TIMER_INTERACTION, diff --git a/include/vlc_playlist.h b/include/vlc_playlist.h index 9acba2652d..a8a98aa7b2 100644 --- a/include/vlc_playlist.h +++ b/include/vlc_playlist.h @@ -111,6 +111,7 @@ struct playlist_t int i_current_index; /**< Index in current array */ /** Reset current item ? */ vlc_bool_t b_reset_currently_playing; + mtime_t last_rebuild_date; int i_last_playlist_id; /**< Last id to an item */ int i_last_input_id ; /**< Last id on an input */ @@ -433,6 +434,12 @@ static inline vlc_bool_t playlist_IsEmpty( playlist_t * p_playlist ) return( b_empty ); } +/** Tell the number of items in the current playing context */ +static inline int playlist_CurrentSize( vlc_object_t *p_this ) +{ + return p_this->p_libvlc->p_playlist->current.i_size; +} + /** Ask the playlist to do some work */ static inline void playlist_Signal( playlist_t *p_playlist ) { diff --git a/modules/control/hotkeys.c b/modules/control/hotkeys.c index 8fbe4cd689..00134cfb24 100644 --- a/modules/control/hotkeys.c +++ b/modules/control/hotkeys.c @@ -796,16 +796,14 @@ static void PlayBookmark( intf_thread_t *p_intf, int i_num ) var_Get( p_intf, psz_bookmark_name, &val ); char *psz_bookmark = strdup( val.psz_string ); - for( i = 0; i < p_playlist->items.i_size; i++) - { - if( !strcmp( psz_bookmark, - ARRAY_VAL( p_playlist->items,i )->p_input->psz_uri ) ) + PL_LOCK; + FOREACH_ARRAY( playlist_item_t *p_item, p_playlist->items ) + if( !strcmp( psz_bookmark, p_item->p_input->psz_uri ) ) { - playlist_LockControl( p_playlist, PLAYLIST_VIEWPLAY, NULL, - ARRAY_VAL( p_playlist->items, i ) ); + playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, NULL, p_item ); break; } - } + FOREACH_END(); vlc_object_release( p_playlist ); } diff --git a/modules/gui/beos/InterfaceWindow.cpp b/modules/gui/beos/InterfaceWindow.cpp index b883bfb486..affd801647 100644 --- a/modules/gui/beos/InterfaceWindow.cpp +++ b/modules/gui/beos/InterfaceWindow.cpp @@ -842,7 +842,7 @@ void InterfaceWindow::UpdateInterface() b_playlist_update = false; } #endif - p_mediaControl->SetEnabled( p_playlist->i_size ); + p_mediaControl->SetEnabled( !playlist_IsEmpty( p_playlist ) ); } if( p_input ) diff --git a/modules/gui/beos/ListViews.cpp b/modules/gui/beos/ListViews.cpp index 7b515cb3ff..74f677c9fb 100644 --- a/modules/gui/beos/ListViews.cpp +++ b/modules/gui/beos/ListViews.cpp @@ -988,26 +988,20 @@ PlaylistView::SetPlaying( bool playing ) void PlaylistView::RebuildList() { - playlist_t * p_playlist; - p_playlist = (playlist_t *) vlc_object_find( p_intf, - VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); - - if( !p_playlist ) - { - return; - } + playlist_t * p_playlist = pl_Yield( p_intf ); // remove all items BListItem * item; int32 count = CountItems(); while( ( item = RemoveItem( --count ) ) ) delete item; - + // rebuild listview from VLC's playlist - vlc_mutex_lock( &p_playlist->object_lock ); - for( int i = 0; i < p_playlist->i_size; i++ ) - AddItem( new PlaylistItem( p_playlist->pp_items[i]->input.psz_name ) ); - vlc_mutex_unlock( &p_playlist->object_lock ); + PL_LOCK; + FOREACH_ARRAY( playlist_item_t *p_item, p_playlist->items ) + AddItem( new PlaylistItem( p_item->p_input->psz_name ) ); + FOREACH_END(); + PL_UNLOCK; vlc_object_release( p_playlist ); } diff --git a/modules/gui/macosx/playlist.m b/modules/gui/macosx/playlist.m index c3aba6cb69..5d79a030dd 100644 --- a/modules/gui/macosx/playlist.m +++ b/modules/gui/macosx/playlist.m @@ -464,11 +464,11 @@ NSLog( @"expandable" ); playlist_t *p_playlist = pl_Yield( VLCIntf ); - /** \todo fix i_size use */ - if( p_playlist->items.i_size >= 2 ) + if( playlist_CurrentSize( p_playlist ) >= 2 ) { [o_status_field setStringValue: [NSString stringWithFormat: - _NS("%i items in the playlist"), p_playlist->items.i_size]]; + _NS("%i items in the playlist"), + playlist_CurrentSize( p_playlist )]]; } else { @@ -1365,13 +1365,11 @@ NSLog( @"expandable" ); id o_value = [super outlineView: outlineView child: index ofItem: item]; playlist_t *p_playlist = pl_Yield( VLCIntf ); - /* FIXME: playlist->i_size doesn't provide the correct number of items anymore - * check the playlist API for the fixed function, once zorglub implemented it -- fpk, 9/17/06 */ - /** \todo fix i_size use */ - if( p_playlist->items.i_size >= 2 ) + if( playlist_CurrentSize( p_playlist ) >= 2 ) { [o_status_field setStringValue: [NSString stringWithFormat: - _NS("%i items in the playlist"), p_playlist->items.i_size]]; + _NS("%i items in the playlist"), + playlist_CurrentSize( p_playlist )]]; } else { diff --git a/modules/gui/wxwidgets/dialogs/playlist.cpp b/modules/gui/wxwidgets/dialogs/playlist.cpp index 030fc12705..e9e3375091 100644 --- a/modules/gui/wxwidgets/dialogs/playlist.cpp +++ b/modules/gui/wxwidgets/dialogs/playlist.cpp @@ -938,7 +938,7 @@ void Playlist::OnSave( wxCommandEvent& WXUNUSED(event) ) wxString filter = wxT(""); - if( p_playlist->i_size == 0 ) + if( playlist_IsEmpty( p_playlist ) ) { wxMessageBox( wxU(_("Playlist is empty") ), wxU(_("Can't save")), wxICON_WARNING | wxOK, this ); diff --git a/modules/gui/wxwidgets/dialogs/wizard.cpp b/modules/gui/wxwidgets/dialogs/wizard.cpp index 4181b4d690..6cf4dd3ad3 100644 --- a/modules/gui/wxwidgets/dialogs/wizard.cpp +++ b/modules/gui/wxwidgets/dialogs/wizard.cpp @@ -582,7 +582,7 @@ wizInputPage::wizInputPage( wxWizard *parent, wxWizardPage *prev, intf_thread_t if( p_playlist ) { - if( p_playlist->i_size > 0) + if( !playlist_IsEmpty( p_playlist ) ) { listview = new wxListView( this, ListView_Event, wxDefaultPosition, wxDefaultSize, @@ -591,19 +591,6 @@ wizInputPage::wizInputPage( wxWizard *parent, wxWizardPage *prev, intf_thread_t listview->InsertColumn( 1, wxU(_("URI")) ); listview->SetColumnWidth( 0, 250 ); listview->SetColumnWidth( 1, 100 ); -#if 0 - for( int i=0 ; i < p_playlist->i_size ; i++ ) - { - wxString filename = wxL2U( p_playlist->pp_items[i]->input. - psz_name ); - listview->InsertItem( i, filename ); - listview->SetItem( i, 1, wxL2U( p_playlist->pp_items[i]-> - input.psz_uri) ); - listview->SetItemData( i, - (long)p_playlist->pp_items[i]->input.i_id ); - } - listview->Select( p_playlist->i_index , TRUE); -#endif mainSizer->Add( listview, 1, wxALL|wxEXPAND, 5 ); listview->Hide(); diff --git a/modules/gui/wxwidgets/menus.cpp b/modules/gui/wxwidgets/menus.cpp index cb8b6227de..7a7fa79c9a 100644 --- a/modules/gui/wxwidgets/menus.cpp +++ b/modules/gui/wxwidgets/menus.cpp @@ -271,7 +271,7 @@ int IntfAutoMenuBuilder( intf_thread_t *p_intf, ArrayOfInts &ri_objects, } \ else \ { \ - if( p_playlist && p_playlist->i_size ) \ + if( p_playlist && !playlist_IsEmpty( p_playlist->i_size ) ) \ { \ popupmenu.InsertSeparator( 0 ); \ popupmenu.Insert( 0, Play_Event, wxU(_("Play")) ); \ diff --git a/src/playlist/control.c b/src/playlist/control.c index 735f58db1f..f6703e0297 100644 --- a/src/playlist/control.c +++ b/src/playlist/control.c @@ -278,10 +278,12 @@ static void ResyncCurrentIndex(playlist_t *p_playlist, playlist_item_t *p_cur ) PL_DEBUG("%s is at %i", PLI_NAME(p_cur), p_playlist->i_current_index ); } -static void ResetCurrentlyPlaying( playlist_t *p_playlist, vlc_bool_t b_random, - playlist_item_t *p_cur ) +void ResetCurrentlyPlaying( playlist_t *p_playlist, vlc_bool_t b_random, + playlist_item_t *p_cur ) { playlist_item_t *p_next = NULL; + stats_TimerStart( p_playlist, "Items array build", + STATS_TIMER_PLAYLIST_BUILD ); PL_DEBUG("rebuilding array of current - root %s", PLI_NAME(p_playlist->status.p_node) ); ARRAY_RESET(p_playlist->current); @@ -319,6 +321,7 @@ static void ResetCurrentlyPlaying( playlist_t *p_playlist, vlc_bool_t b_random, } } p_playlist->b_reset_currently_playing = VLC_FALSE; + stats_TimerStop( p_playlist, STATS_TIMER_PLAYLIST_BUILD ); } /** This function calculates the next playlist item, depending @@ -389,6 +392,7 @@ playlist_item_t * playlist_NextItem( playlist_t *p_playlist ) i_skip++; if( p_playlist->b_reset_currently_playing ) + /* A bit too bad to reset twice ... */ ResetCurrentlyPlaying( p_playlist, b_random, p_new ); else if( p_new ) ResyncCurrentIndex( p_playlist, p_new ); diff --git a/src/playlist/engine.c b/src/playlist/engine.c index adc16160f5..86a3c14623 100644 --- a/src/playlist/engine.c +++ b/src/playlist/engine.c @@ -38,6 +38,7 @@ static int RandomCallback( vlc_object_t *p_this, char const *psz_cmd, vlc_value_t oldval, vlc_value_t newval, void *a ) { ((playlist_t*)p_this)->b_reset_currently_playing = VLC_TRUE; + playlist_Signal( ((playlist_t*)p_this) ); return VLC_SUCCESS; } @@ -80,6 +81,7 @@ playlist_t * playlist_Create( vlc_object_t *p_parent ) p_playlist->i_current_index = 0; p_playlist->b_reset_currently_playing = VLC_TRUE; + p_playlist->last_rebuild_date = 0; i_tree = var_CreateGetBool( p_playlist, "playlist-tree" ); p_playlist->b_always_tree = (i_tree == 1); @@ -244,20 +246,24 @@ void playlist_MainLoop( playlist_t *p_playlist ) vlc_bool_t b_playexit = var_GetBool( p_playlist, "play-and-exit" ); PL_LOCK; - /* First, check if we have something to do */ - if( p_playlist->request.b_request ) + if( p_playlist->b_reset_currently_playing && + mdate() - p_playlist->last_rebuild_date > 30000 ) // 30 ms { - /* Stop the existing input */ - if( p_playlist->p_input && !p_playlist->p_input->b_die ) - { - PL_DEBUG( "incoming request - stopping current input" ); - input_StopThread( p_playlist->p_input ); - } + ResetCurrentlyPlaying( p_playlist, var_GetBool( p_playlist, "random"), + p_playlist->status.p_item ); + p_playlist->last_rebuild_date = mdate(); } + check_input: /* If there is an input, check that it doesn't need to die. */ if( p_playlist->p_input ) { + if( p_playlist->request.b_request && !p_playlist->p_input->b_die ) + { + PL_DEBUG( "incoming request - stopping current input" ); + input_StopThread( p_playlist->p_input ); + } + /* This input is dead. Remove it ! */ if( p_playlist->p_input->b_dead ) { @@ -340,10 +346,7 @@ check_input: p_playlist->request.i_status != PLAYLIST_STOPPED ) ) { msg_Dbg( p_playlist, "starting new item" ); - stats_TimerStart( p_playlist, "Playlist walk", - STATS_TIMER_PLAYLIST_WALK ); p_item = playlist_NextItem( p_playlist ); - stats_TimerStop( p_playlist, STATS_TIMER_PLAYLIST_WALK ); if( p_item == NULL ) { diff --git a/src/playlist/item.c b/src/playlist/item.c index 3a610f72bd..eefdf86a45 100644 --- a/src/playlist/item.c +++ b/src/playlist/item.c @@ -404,6 +404,7 @@ playlist_item_t *playlist_ItemToNode( playlist_t *p_playlist, p_playlist->p_root_onelevel, VLC_FALSE ); } p_playlist->b_reset_currently_playing = VLC_TRUE; + vlc_cond_signal( &p_playlist->object_wait ); var_SetInteger( p_playlist, "item-change", p_item_in_category-> p_input->i_id ); return p_item_in_category; @@ -492,6 +493,7 @@ static int TreeMove( playlist_t *p_playlist, playlist_item_t *p_item, int playlist_TreeMove( playlist_t * p_playlist, playlist_item_t *p_item, playlist_item_t *p_node, int i_newpos ) { + int i_ret; /* Drop on a top level node. Move in the two trees */ if( p_node->p_parent == p_playlist->p_root_category || p_node->p_parent == p_playlist->p_root_onelevel ) @@ -529,10 +531,13 @@ int playlist_TreeMove( playlist_t * p_playlist, playlist_item_t *p_item, if( p_node_category && p_item_category ) TreeMove( p_playlist, p_item_category, p_node_category, 0 ); } - return VLC_SUCCESS; + i_ret = VLC_SUCCESS; } else - return TreeMove( p_playlist, p_item, p_node, i_newpos ); + i_ret = TreeMove( p_playlist, p_item, p_node, i_newpos ); + p_playlist->b_reset_currently_playing = VLC_TRUE; + vlc_cond_signal( &p_playlist->object_wait ); + return i_ret; } /** Send a notification that an item has been added to a node */ @@ -545,6 +550,7 @@ void playlist_SendAddNotify( playlist_t *p_playlist, int i_item_id, p_add->i_node = i_node_id; val.p_address = p_add; p_playlist->b_reset_currently_playing = VLC_TRUE; + vlc_cond_signal( &p_playlist->object_wait ); var_Set( p_playlist, "item-append", val ); free( p_add ); } diff --git a/src/playlist/playlist_internal.h b/src/playlist/playlist_internal.h index 63a664e11c..b77a2bf99c 100644 --- a/src/playlist/playlist_internal.h +++ b/src/playlist/playlist_internal.h @@ -67,6 +67,8 @@ void playlist_LastLoop( playlist_t * ); void playlist_PreparseLoop( playlist_preparse_t * ); void playlist_SecondaryPreparseLoop( playlist_secondary_preparse_t * ); +void ResetCurrentlyPlaying( playlist_t *, vlc_bool_t, playlist_item_t * ); + /* Control */ playlist_item_t * playlist_NextItem ( playlist_t * ); int playlist_PlayItem ( playlist_t *, playlist_item_t * ); @@ -98,7 +100,8 @@ playlist_item_t *playlist_GetLastLeaf( playlist_t *p_playlist, * @} */ -#define PLAYLIST_DEBUG 1 +//#define PLAYLIST_DEBUG 1 +#undef PLAYLIST_DEBUG #ifdef PLAYLIST_DEBUG #define PL_DEBUG( msg, args... ) msg_Dbg( p_playlist, msg, ## args ) diff --git a/src/playlist/search.c b/src/playlist/search.c index 00077f44e9..ba7a52c681 100644 --- a/src/playlist/search.c +++ b/src/playlist/search.c @@ -95,5 +95,6 @@ int playlist_LiveSearchUpdate( playlist_t *p_playlist, playlist_item_t *p_root, else p_item->i_flags |= PLAYLIST_DBL_FLAG; } + vlc_cond_signal( &p_playlist->object_wait ); return VLC_SUCCESS; } diff --git a/src/playlist/thread.c b/src/playlist/thread.c index 65759bfcf6..0c08a8bc0c 100644 --- a/src/playlist/thread.c +++ b/src/playlist/thread.c @@ -36,11 +36,9 @@ static void RunPreparse( playlist_preparse_t * ); static void RunSecondaryPreparse( playlist_secondary_preparse_t * ); static playlist_t * CreatePlaylist( vlc_object_t *p_parent ); -static void HandlePlaylist( playlist_t * ); static void EndPlaylist( playlist_t * ); static void DestroyPlaylist( playlist_t * ); -static void HandleInteraction( playlist_t * ); static void DestroyInteraction( playlist_t * ); /***************************************************************************** @@ -174,8 +172,10 @@ static void RunControlThread ( playlist_t *p_playlist ) { i_loops++; - HandleInteraction( p_playlist ); - HandlePlaylist( p_playlist ); + if( p_playlist->p_interaction ) + intf_InteractionManage( p_playlist ); + + playlist_MainLoop( p_playlist ); if( p_playlist->b_cant_sleep ) { /* 100 ms is an acceptable delay for playlist operations */ @@ -206,11 +206,6 @@ static void DestroyPlaylist( playlist_t *p_playlist ) playlist_Destroy( p_playlist ); } -static void HandlePlaylist( playlist_t *p_playlist ) -{ - playlist_MainLoop( p_playlist ); -} - static void EndPlaylist( playlist_t *p_playlist ) { playlist_LastLoop( p_playlist ); @@ -245,14 +240,3 @@ static void DestroyInteraction( playlist_t *p_playlist ) p_playlist->p_interaction = NULL; } } - -static void HandleInteraction( playlist_t *p_playlist ) -{ - if( p_playlist->p_interaction ) - { - stats_TimerStart( p_playlist, "Interaction thread", - STATS_TIMER_INTERACTION ); - intf_InteractionManage( p_playlist ); - stats_TimerStop( p_playlist, STATS_TIMER_INTERACTION ); - } -}