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 + -
显示快捷键?