diff --git a/include/main.h b/include/main.h index df9c78f4cc42da390a400e4a608f59d2f7088c41..914a7514c0f5f2a9639237914aacd33b457f6c91 100644 --- a/include/main.h +++ b/include/main.h @@ -35,7 +35,7 @@ struct libvlc_global_data_t vlc_bool_t b_ready; ///< Initialization boolean uint32_t i_cpu; ///< CPU extensions - + /* Object structure data */ int i_counter; ///< object counter int i_objects; ///< Attached objects count diff --git a/include/vlc_input.h b/include/vlc_input.h index ee120936a3d26c5b0bf62a6d0c47d1512c7f1af8..7e2bd3078936a3c93d7310ecfffc064016a1eafd 100644 --- a/include/vlc_input.h +++ b/include/vlc_input.h @@ -104,9 +104,8 @@ static inline void input_ItemInit( vlc_object_t *p_o, input_item_t *p_i ) p_i->i_type = ITEM_TYPE_UNKNOWN; p_i->b_fixed_name = VLC_TRUE; - p_i->p_stats = (input_stats_t*) malloc( sizeof( input_stats_t ) ); + p_i->p_stats = NULL; p_i->p_meta = NULL; - vlc_mutex_init( p_o, &p_i->p_stats->lock ); vlc_mutex_init( p_o, &p_i->lock ); } @@ -131,11 +130,13 @@ VLC_EXPORT( void, input_ItemAddOptionNoDup,( input_item_t *, const char * ) ); static inline void input_ItemClean( input_item_t *p_i ) { - if( p_i->psz_name ) free( p_i->psz_name ); - if( p_i->psz_uri ) free( p_i->psz_uri ); - if( p_i->p_stats ) free( p_i->p_stats ); - p_i->psz_name = 0; - p_i->psz_uri = 0; + free( p_i->psz_name ); + free( p_i->psz_uri ); + if( p_i->p_stats ) + { + vlc_mutex_destroy( &p_i->p_stats->lock ); + free( p_i->p_stats ); + } if( p_i->p_meta ) vlc_meta_Delete( p_i->p_meta ); diff --git a/include/vlc_playlist.h b/include/vlc_playlist.h index 7069c1454891b8a5bac08abde9a296d7fa52a26e..2b396535e5d3b286d359f50960687fa715eca114 100644 --- a/include/vlc_playlist.h +++ b/include/vlc_playlist.h @@ -173,6 +173,8 @@ struct playlist_t // Playlist-unrelated fields interaction_t *p_interaction; /**< Interaction manager */ + /** The input thread computing stats */ + input_thread_t *p_stats_computer; global_stats_t *p_stats; /**< Global statistics */ /*@}*/ }; diff --git a/src/input/input.c b/src/input/input.c index 658bfdc6cd59cc4665a2fa8600813914bcc2d2f6..6965789770ee5286c741a80f33e4c194deb5c7e7 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -120,6 +120,19 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, msg_Err( p_parent, "out of memory" ); return NULL; } + + /* One "randomly" selected input thread is responsible for computing + * the global stats. Check if there is already someone doing this */ + if( p_input->p_libvlc->p_playlist->p_stats && !b_quick ) + { + vlc_mutex_lock( &p_input->p_libvlc->p_playlist->p_stats->lock ); + if( p_input->p_libvlc->p_playlist->p_stats_computer == NULL ) + { + p_input->p_libvlc->p_playlist->p_stats_computer = p_input; + } + vlc_mutex_unlock( &p_input->p_libvlc->p_playlist->p_stats->lock ); + } + p_input->b_preparsing = b_quick; p_input->psz_header = psz_header ? strdup( psz_header ) : NULL; @@ -157,7 +170,13 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item, if( !p_input->input.p_item->p_meta ) p_input->input.p_item->p_meta = vlc_meta_New(); - stats_ReinitInputStats( p_item->p_stats ); + + if( !p_item->p_stats ) + { + p_item->p_stats = (input_stats_t*)malloc( sizeof( input_stats_t ) ); + vlc_mutex_init( p_input, &p_item->p_stats->lock ); + stats_ReinitInputStats( p_item->p_stats ); + } /* No slave */ p_input->i_slave = 0; @@ -515,6 +534,7 @@ static int RunAndClean( input_thread_t *p_input ) static void MainLoop( input_thread_t *p_input ) { int64_t i_intf_update = 0; + int i_updates = 0; while( !p_input->b_die && !p_input->b_error && !p_input->input.b_eof ) { vlc_bool_t b_force_update = VLC_FALSE; @@ -662,6 +682,17 @@ static void MainLoop( input_thread_t *p_input ) var_SetBool( p_input, "intf-change", VLC_TRUE ); i_intf_update = mdate() + I64C(150000); } + /* 150ms * 8 = ~ 1 second */ + if( ++i_updates % 8 == 0 ) + { + stats_ComputeInputStats( p_input, p_input->input.p_item->p_stats ); + /* Are we the thread responsible for computing global stats ? */ + if( p_input->p_libvlc->p_playlist->p_stats_computer == p_input ) + { + stats_ComputeGlobalStats( p_input->p_libvlc->p_playlist, + p_input->p_libvlc->p_playlist->p_stats ); + } + } } } @@ -1119,6 +1150,14 @@ static void End( input_thread_t * p_input ) #define CL_CO( c ) stats_CounterClean( p_input->counters.p_##c ); p_input->counters.p_##c = NULL; if( p_input->p_libvlc->b_stats ) { + /* make sure we are up to date */ + stats_ComputeInputStats( p_input, p_input->input.p_item->p_stats ); + if( p_input->p_libvlc->p_playlist->p_stats_computer == p_input ) + { + stats_ComputeGlobalStats( p_input->p_libvlc->p_playlist, + p_input->p_libvlc->p_playlist->p_stats ); + p_input->p_libvlc->p_playlist->p_stats_computer = NULL; + } vlc_mutex_lock( &p_input->counters.counters_lock ); CL_CO( read_bytes ); CL_CO( read_packets ); diff --git a/src/playlist/thread.c b/src/playlist/thread.c index 8f7169b2a7421c5a60010310b0610036587fcfcf..a3cc707a6fe2b4dc4279557c824873ef597029c6 100644 --- a/src/playlist/thread.c +++ b/src/playlist/thread.c @@ -40,8 +40,6 @@ static void HandlePlaylist( playlist_t * ); static void EndPlaylist( playlist_t * ); static void DestroyPlaylist( playlist_t * ); -static void HandleStats( playlist_t *, int ); - static void HandleInteraction( playlist_t * ); static void DestroyInteraction( playlist_t * ); @@ -68,6 +66,7 @@ void __playlist_ThreadCreate( vlc_object_t *p_parent ) // Stats p_playlist->p_stats = (global_stats_t *)malloc( sizeof( global_stats_t ) ); vlc_mutex_init( p_playlist, &p_playlist->p_stats->lock ); + p_playlist->p_stats_computer = NULL; // Interaction p_playlist->p_interaction = NULL; @@ -169,7 +168,6 @@ static void RunControlThread ( playlist_t *p_playlist ) i_loops++; HandleInteraction( p_playlist ); - HandleStats( p_playlist, i_loops ); HandlePlaylist( p_playlist ); /* 100 ms is an acceptable delay for playlist operations */ @@ -247,20 +245,3 @@ static void HandleInteraction( playlist_t *p_playlist ) stats_TimerStop( p_playlist, STATS_TIMER_INTERACTION ); } } - - -/***************************************************************************** - * Stats functions - *****************************************************************************/ -static void HandleStats( playlist_t *p_playlist, int i_loops ) -{ - if( i_loops % 5 == 0 && p_playlist->p_stats ) - { - stats_ComputeGlobalStats( p_playlist, p_playlist->p_stats ); - if( p_playlist->p_input ) - { - stats_ComputeInputStats( p_playlist->p_input, - p_playlist->p_input->input.p_item->p_stats ); - } - } -}