stats.c
来自「uclinux 下的vlc播放器源代码」· C语言 代码 · 共 721 行 · 第 1/2 页
C
721 行
{ vlc_list_t *p_list; int i_index; if( !p_obj->p_libvlc->b_stats ) return; vlc_mutex_lock( &p_stats->lock ); p_list = vlc_list_find( p_obj, VLC_OBJECT_INPUT, FIND_ANYWHERE ); if( p_list ) { float f_total_in = 0, f_total_out = 0,f_total_demux = 0; for( i_index = 0; i_index < p_list->i_count ; i_index ++ ) { float f_in = 0, f_out = 0, f_demux = 0; p_obj = (vlc_object_t *)p_list->p_values[i_index].p_object; stats_GetFloat( p_obj, p_obj->i_object_id, STATS_INPUT_BITRATE, &f_in ); stats_GetFloat( p_obj, p_obj->i_object_id, STATS_SOUT_SEND_BITRATE, &f_out ); stats_GetFloat( p_obj, p_obj->i_object_id, STATS_DEMUX_BITRATE, &f_demux ); f_total_in += f_in; f_total_out += f_out;f_total_demux += f_demux; } p_stats->f_input_bitrate = f_total_in; p_stats->f_output_bitrate = f_total_out; p_stats->f_demux_bitrate = f_total_demux; vlc_list_release( p_list ); } vlc_mutex_unlock( &p_stats->lock );}void stats_ReinitGlobalStats( global_stats_t *p_stats ){ p_stats->f_input_bitrate = p_stats->f_output_bitrate = 0.0;}void __stats_TimerStart( vlc_object_t *p_obj, const char *psz_name, unsigned int i_id ){ counter_t *p_counter; if( !p_obj->p_libvlc->b_stats ) return; p_counter = stats_CounterGet( p_obj, p_obj->p_vlc->i_object_id, i_id ); if( !p_counter ) { counter_sample_t *p_sample; stats_Create( p_obj->p_vlc, psz_name, i_id, VLC_VAR_TIME, STATS_TIMER ); p_counter = stats_CounterGet( p_obj, p_obj->p_vlc->i_object_id, i_id ); if( !p_counter ) return; /* 1st sample : if started: start_date, else last_time, b_started */ p_sample = (counter_sample_t *)malloc( sizeof( counter_sample_t ) ); INSERT_ELEM( p_counter->pp_samples, p_counter->i_samples, p_counter->i_samples, p_sample ); p_sample->date = 0; p_sample->value.b_bool = 0; /* 2nd sample : global_time, i_samples */ p_sample = (counter_sample_t *)malloc( sizeof( counter_sample_t ) ); INSERT_ELEM( p_counter->pp_samples, p_counter->i_samples, p_counter->i_samples, p_sample ); p_sample->date = 0; p_sample->value.i_int = 0; } if( p_counter->pp_samples[0]->value.b_bool == VLC_TRUE ) { msg_Warn( p_obj, "timer %s was already started !", psz_name ); return; } p_counter->pp_samples[0]->value.b_bool = VLC_TRUE; p_counter->pp_samples[0]->date = mdate();}void __stats_TimerStop( vlc_object_t *p_obj, unsigned int i_id ){ counter_t *p_counter; if( !p_obj->p_libvlc->b_stats ) return; p_counter = stats_CounterGet( p_obj, p_obj->p_vlc->i_object_id, i_id ); if( !p_counter || p_counter->i_samples != 2 ) { msg_Err( p_obj, "Timer does not exist" ); return; } p_counter->pp_samples[0]->value.b_bool = VLC_FALSE; p_counter->pp_samples[1]->value.i_int += 1; p_counter->pp_samples[0]->date = mdate() - p_counter->pp_samples[0]->date; p_counter->pp_samples[1]->date += p_counter->pp_samples[0]->date;}void __stats_TimerDump( vlc_object_t *p_obj, unsigned int i_id ){ counter_t *p_counter; if( !p_obj->p_libvlc->b_stats ) return; p_counter = stats_CounterGet( p_obj, p_obj->p_vlc->i_object_id, i_id ); TimerDump( p_obj, p_counter, VLC_TRUE );}void __stats_TimersDumpAll( vlc_object_t *p_obj ){ int i; stats_handler_t *p_handler = stats_HandlerGet( p_obj ); if( !p_handler ) return; vlc_mutex_lock( &p_handler->object_lock ); for ( i = 0 ; i< p_handler->i_counters; i++ ) { counter_t * p_counter = p_handler->pp_counters[i]; if( p_counter->i_compute_type == STATS_TIMER ) { TimerDump( p_obj, p_counter, VLC_FALSE ); } } vlc_mutex_unlock( &p_handler->object_lock ); vlc_object_release( p_handler );}/******************************************************************** * Following functions are local ********************************************************************//** * Update a statistics counter, according to its type * If needed, perform a bit of computation (derivative, mostly) * This function must be entered with stats handler lock * \param p_handler stats handler singleton * \param p_counter the counter to update * \param val the "new" value * \return an error code */static int stats_CounterUpdate( stats_handler_t *p_handler, counter_t *p_counter, vlc_value_t val, vlc_value_t *new_val ){ switch( p_counter->i_compute_type ) { case STATS_LAST: case STATS_MIN: case STATS_MAX: if( p_counter->i_samples > 1) { msg_Err( p_handler, "LAST counter has several samples !" ); return VLC_EGENERIC; } if( p_counter->i_type != VLC_VAR_FLOAT && p_counter->i_type != VLC_VAR_INTEGER && p_counter->i_compute_type != STATS_LAST ) { msg_Err( p_handler, "unable to compute MIN or MAX for this type"); return VLC_EGENERIC; } if( p_counter->i_samples == 0 ) { counter_sample_t *p_new = (counter_sample_t*)malloc( sizeof( counter_sample_t ) ); p_new->value.psz_string = NULL; INSERT_ELEM( p_counter->pp_samples, p_counter->i_samples, p_counter->i_samples, p_new ); } if( p_counter->i_samples == 1 ) { /* Update if : LAST or (MAX and bigger) or (MIN and bigger) */ if( p_counter->i_compute_type == STATS_LAST || ( p_counter->i_compute_type == STATS_MAX && ( ( p_counter->i_type == VLC_VAR_INTEGER && p_counter->pp_samples[0]->value.i_int > val.i_int ) || ( p_counter->i_type == VLC_VAR_FLOAT && p_counter->pp_samples[0]->value.f_float > val.f_float ) ) ) || ( p_counter->i_compute_type == STATS_MIN && ( ( p_counter->i_type == VLC_VAR_INTEGER && p_counter->pp_samples[0]->value.i_int < val.i_int ) || ( p_counter->i_type == VLC_VAR_FLOAT && p_counter->pp_samples[0]->value.f_float < val.f_float ) ) ) ) { if( p_counter->i_type == VLC_VAR_STRING && p_counter->pp_samples[0]->value.psz_string ) { free( p_counter->pp_samples[0]->value.psz_string ); } p_counter->pp_samples[0]->value = val; *new_val = p_counter->pp_samples[0]->value; } } break; case STATS_DERIVATIVE: { counter_sample_t *p_new, *p_old; if( mdate() - p_counter->last_update < p_counter->update_interval ) { return VLC_EGENERIC; } p_counter->last_update = mdate(); if( p_counter->i_type != VLC_VAR_FLOAT && p_counter->i_type != VLC_VAR_INTEGER ) { msg_Err( p_handler, "Unable to compute DERIVATIVE for this type"); return VLC_EGENERIC; } /* Insert the new one at the beginning */ p_new = (counter_sample_t*)malloc( sizeof( counter_sample_t ) ); p_new->value = val; p_new->date = p_counter->last_update; INSERT_ELEM( p_counter->pp_samples, p_counter->i_samples, 0, p_new ); if( p_counter->i_samples == 3 ) { p_old = p_counter->pp_samples[2]; REMOVE_ELEM( p_counter->pp_samples, p_counter->i_samples, 2 ); free( p_old ); } break; } case STATS_COUNTER: if( p_counter->i_samples > 1) { msg_Err( p_handler, "LAST counter has several samples !" ); return VLC_EGENERIC; } if( p_counter->i_samples == 0 ) { counter_sample_t *p_new = (counter_sample_t*)malloc( sizeof( counter_sample_t ) ); p_new->value.psz_string = NULL; INSERT_ELEM( p_counter->pp_samples, p_counter->i_samples, p_counter->i_samples, p_new ); } if( p_counter->i_samples == 1 ) { switch( p_counter->i_type ) { case VLC_VAR_INTEGER: p_counter->pp_samples[0]->value.i_int += val.i_int; if( new_val ) new_val->i_int = p_counter->pp_samples[0]->value.i_int; break; case VLC_VAR_FLOAT: p_counter->pp_samples[0]->value.f_float += val.f_float; if( new_val ) new_val->f_float = p_counter->pp_samples[0]->value.f_float; default: msg_Err( p_handler, "Trying to increment invalid variable %s", p_counter->psz_name ); return VLC_EGENERIC; } } break; } return VLC_SUCCESS;}static counter_t *GetCounter( stats_handler_t *p_handler, int i_object_id, unsigned int i_counter ){ int i; uint64_t i_index = ((uint64_t) i_object_id << 32 ) + i_counter; for (i = 0 ; i < p_handler->i_counters ; i++ ) { if( i_index == p_handler->pp_counters[i]->i_index ) return p_handler->pp_counters[i]; } return NULL;}static stats_handler_t *stats_HandlerGet( vlc_object_t *p_this ){ stats_handler_t *p_handler = p_this->p_libvlc->p_stats; if( !p_handler ) { p_handler = stats_HandlerCreate( p_this ); if( !p_handler ) { return NULL; } } vlc_object_yield( p_handler ); return p_handler;}/** * Initialize statistics handler * * This function initializes the global statistics handler singleton, * \param p_this the parent VLC object */static stats_handler_t* stats_HandlerCreate( vlc_object_t *p_this ){ stats_handler_t *p_handler; msg_Dbg( p_this, "creating statistics handler" ); p_handler = (stats_handler_t*) vlc_object_create( p_this, VLC_OBJECT_STATS ); if( !p_handler ) { msg_Err( p_this, "out of memory" ); return NULL; } p_handler->i_counters = 0; p_handler->pp_counters = NULL; /// \bug is it p_vlc or p_libvlc ? vlc_object_attach( p_handler, p_this->p_vlc ); p_this->p_libvlc->p_stats = p_handler; return p_handler;}static void TimerDump( vlc_object_t *p_obj, counter_t *p_counter, vlc_bool_t b_total ){ mtime_t last, total; int i_total; if( !p_counter || p_counter->i_samples != 2 ) { msg_Err( p_obj, "Timer %s does not exist", p_counter->psz_name ); return; } i_total = p_counter->pp_samples[1]->value.i_int; total = p_counter->pp_samples[1]->date; if( p_counter->pp_samples[0]->value.b_bool == VLC_TRUE ) { last = mdate() - p_counter->pp_samples[0]->date; i_total += 1; total += last; } else { last = p_counter->pp_samples[0]->date; } if( b_total ) { msg_Dbg( p_obj, "TIMER %s : %.3f ms - Total %.3f ms / %i intvls (Avg %.3f ms)", p_counter->psz_name, (float)last/1000, (float)total/1000, i_total, (float)(total)/(1000*(float)i_total ) ); } else { msg_Dbg( p_obj, "TIMER %s : Total %.3f ms / %i intvls (Avg %.3f ms)", p_counter->psz_name, (float)total/1000, i_total, (float)(total)/(1000*(float)i_total ) ); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?