This saves a whole lot of float conversion and simplifies the code.
if( p_input != NULL && (i_decoded > 0 || i_lost > 0 || i_played > 0) )
{
vlc_mutex_lock( &p_input->p->counters.counters_lock);
-
- stats_UpdateInteger( p_input->p->counters.p_lost_abuffers,
- i_lost, NULL );
- stats_UpdateInteger( p_input->p->counters.p_played_abuffers,
- i_played, NULL );
- stats_UpdateInteger( p_input->p->counters.p_decoded_audio,
- i_decoded, NULL );
-
+ stats_Update( p_input->p->counters.p_lost_abuffers, i_lost, NULL );
+ stats_Update( p_input->p->counters.p_played_abuffers, i_played, NULL );
+ stats_Update( p_input->p->counters.p_decoded_audio, i_decoded, NULL );
vlc_mutex_unlock( &p_input->p->counters.counters_lock);
}
}
if( p_input != NULL && (i_decoded > 0 || i_lost > 0 || i_displayed > 0) )
{
vlc_mutex_lock( &p_input->p->counters.counters_lock );
-
- stats_UpdateInteger( p_input->p->counters.p_decoded_video,
- i_decoded, NULL );
- stats_UpdateInteger( p_input->p->counters.p_lost_pictures,
- i_lost , NULL);
-
- stats_UpdateInteger( p_input->p->counters.p_displayed_pictures,
- i_displayed, NULL);
-
+ stats_Update( p_input->p->counters.p_decoded_video, i_decoded, NULL );
+ stats_Update( p_input->p->counters.p_lost_pictures, i_lost , NULL);
+ stats_Update( p_input->p->counters.p_displayed_pictures,
+ i_displayed, NULL);
vlc_mutex_unlock( &p_input->p->counters.counters_lock );
}
}
if( p_input != NULL )
{
vlc_mutex_lock( &p_input->p->counters.counters_lock );
- stats_UpdateInteger( p_input->p->counters.p_decoded_sub, 1, NULL );
+ stats_Update( p_input->p->counters.p_decoded_sub, 1, NULL );
vlc_mutex_unlock( &p_input->p->counters.counters_lock );
}
{
es_out_sys_t *p_sys = out->p_sys;
input_thread_t *p_input = p_sys->p_input;
- int i_total = 0;
if( libvlc_stats( p_input ) )
{
+ uint64_t i_total;
+
vlc_mutex_lock( &p_input->p->counters.counters_lock );
- stats_UpdateInteger( p_input->p->counters.p_demux_read,
- p_block->i_buffer, &i_total );
- stats_UpdateFloat( p_input->p->counters.p_demux_bitrate,
- (float)i_total, NULL );
+ stats_Update( p_input->p->counters.p_demux_read,
+ p_block->i_buffer, &i_total );
+ stats_Update( p_input->p->counters.p_demux_bitrate, i_total, NULL );
/* Update number of corrupted data packats */
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{
- stats_UpdateInteger( p_input->p->counters.p_demux_corrupted,
- 1, NULL );
+ stats_Update( p_input->p->counters.p_demux_corrupted, 1, NULL );
}
/* Update number of discontinuities */
if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
{
- stats_UpdateInteger( p_input->p->counters.p_demux_discontinuity,
- 1, NULL );
+ stats_Update( p_input->p->counters.p_demux_discontinuity, 1, NULL );
}
vlc_mutex_unlock( &p_input->p->counters.counters_lock );
}
if( p_input->b_preparsing ) return;
/* Prepare statistics */
-#define INIT_COUNTER( c, type, compute ) p_input->p->counters.p_##c = \
- stats_CounterCreate( VLC_VAR_##type, STATS_##compute);
+#define INIT_COUNTER( c, compute ) p_input->p->counters.p_##c = \
+ stats_CounterCreate( STATS_##compute);
if( libvlc_stats( p_input ) )
{
- INIT_COUNTER( read_bytes, INTEGER, COUNTER );
- INIT_COUNTER( read_packets, INTEGER, COUNTER );
- INIT_COUNTER( demux_read, INTEGER, COUNTER );
- INIT_COUNTER( input_bitrate, FLOAT, DERIVATIVE );
- INIT_COUNTER( demux_bitrate, FLOAT, DERIVATIVE );
- INIT_COUNTER( demux_corrupted, INTEGER, COUNTER );
- INIT_COUNTER( demux_discontinuity, INTEGER, COUNTER );
- INIT_COUNTER( played_abuffers, INTEGER, COUNTER );
- INIT_COUNTER( lost_abuffers, INTEGER, COUNTER );
- INIT_COUNTER( displayed_pictures, INTEGER, COUNTER );
- INIT_COUNTER( lost_pictures, INTEGER, COUNTER );
- INIT_COUNTER( decoded_audio, INTEGER, COUNTER );
- INIT_COUNTER( decoded_video, INTEGER, COUNTER );
- INIT_COUNTER( decoded_sub, INTEGER, COUNTER );
+ INIT_COUNTER( read_bytes, COUNTER );
+ INIT_COUNTER( read_packets, COUNTER );
+ INIT_COUNTER( demux_read, COUNTER );
+ INIT_COUNTER( input_bitrate, DERIVATIVE );
+ INIT_COUNTER( demux_bitrate, DERIVATIVE );
+ INIT_COUNTER( demux_corrupted, COUNTER );
+ INIT_COUNTER( demux_discontinuity, COUNTER );
+ INIT_COUNTER( played_abuffers, COUNTER );
+ INIT_COUNTER( lost_abuffers, COUNTER );
+ INIT_COUNTER( displayed_pictures, COUNTER );
+ INIT_COUNTER( lost_pictures, COUNTER );
+ INIT_COUNTER( decoded_audio, COUNTER );
+ INIT_COUNTER( decoded_video, COUNTER );
+ INIT_COUNTER( decoded_sub, COUNTER );
p_input->p->counters.p_sout_send_bitrate = NULL;
p_input->p->counters.p_sout_sent_packets = NULL;
p_input->p->counters.p_sout_sent_bytes = NULL;
}
if( libvlc_stats( p_input ) )
{
- INIT_COUNTER( sout_sent_packets, INTEGER, COUNTER );
- INIT_COUNTER( sout_sent_bytes, INTEGER, COUNTER );
- INIT_COUNTER( sout_send_bitrate, FLOAT, DERIVATIVE );
+ INIT_COUNTER( sout_sent_packets, COUNTER );
+ INIT_COUNTER( sout_sent_bytes, COUNTER );
+ INIT_COUNTER( sout_send_bitrate, DERIVATIVE );
}
}
else
vlc_mutex_lock( &p_input->p->counters.counters_lock);
switch( i_type )
{
-#define I(c) stats_UpdateInteger( p_input->p->counters.c, i_delta, NULL )
+#define I(c) stats_Update( p_input->p->counters.c, i_delta, NULL )
case INPUT_STATISTIC_DECODED_VIDEO:
I(p_decoded_video);
break;
#undef I
case INPUT_STATISTIC_SENT_BYTE:
{
- int i_bytes; /* That's pretty stupid to define it as an integer, it will overflow
- really fast ... */
- if( !stats_UpdateInteger( p_input->p->counters.p_sout_sent_bytes, i_delta, &i_bytes ) )
- stats_UpdateFloat( p_input->p->counters.p_sout_send_bitrate, i_bytes, NULL );
+ uint64_t bytes;
+
+ stats_Update( p_input->p->counters.p_sout_sent_bytes, i_delta, &bytes );
+ stats_Update( p_input->p->counters.p_sout_send_bitrate, bytes, NULL );
break;
}
default:
access_t *p_access = p_sys->p_access;
input_thread_t *p_input = s->p_input;
int i_read_orig = i_read;
- int i_total = 0;
if( !p_sys->i_list )
{
vlc_object_kill( s );
if( p_input )
{
+ uint64_t total;
+
vlc_mutex_lock( &p_input->p->counters.counters_lock );
- stats_UpdateInteger( p_input->p->counters.p_read_bytes, i_read,
- &i_total );
- stats_UpdateFloat( p_input->p->counters.p_input_bitrate,
- (float)i_total, NULL );
- stats_UpdateInteger( p_input->p->counters.p_read_packets, 1, NULL );
+ stats_Update( p_input->p->counters.p_read_bytes, i_read, &total );
+ stats_Update( p_input->p->counters.p_input_bitrate, total, NULL );
+ stats_Update( p_input->p->counters.p_read_packets, 1, NULL );
vlc_mutex_unlock( &p_input->p->counters.counters_lock );
}
return i_read;
/* Update read bytes in input */
if( p_input )
{
+ uint64_t total;
+
vlc_mutex_lock( &p_input->p->counters.counters_lock );
- stats_UpdateInteger( p_input->p->counters.p_read_bytes, i_read, &i_total );
- stats_UpdateFloat( p_input->p->counters.p_input_bitrate,
- (float)i_total, NULL );
- stats_UpdateInteger( p_input->p->counters.p_read_packets, 1, NULL );
+ stats_Update( p_input->p->counters.p_read_bytes, i_read, &total );
+ stats_Update( p_input->p->counters.p_input_bitrate, total, NULL );
+ stats_Update( p_input->p->counters.p_read_packets, 1, NULL );
vlc_mutex_unlock( &p_input->p->counters.counters_lock );
}
return i_read;
input_thread_t *p_input = s->p_input;
block_t *p_block;
bool b_eof;
- int i_total = 0;
if( !p_sys->i_list )
{
if( pb_eof ) *pb_eof = p_access->info.b_eof;
if( p_input && p_block && libvlc_stats (p_access) )
{
+ uint64_t total;
+
vlc_mutex_lock( &p_input->p->counters.counters_lock );
- stats_UpdateInteger( p_input->p->counters.p_read_bytes,
- p_block->i_buffer, &i_total );
- stats_UpdateFloat( p_input->p->counters.p_input_bitrate,
- (float)i_total, NULL );
- stats_UpdateInteger( p_input->p->counters.p_read_packets, 1, NULL );
+ stats_Update( p_input->p->counters.p_read_bytes,
+ p_block->i_buffer, &total );
+ stats_Update( p_input->p->counters.p_input_bitrate,
+ total, NULL );
+ stats_Update( p_input->p->counters.p_read_packets, 1, NULL );
vlc_mutex_unlock( &p_input->p->counters.counters_lock );
}
return p_block;
{
if( p_input )
{
+ uint64_t total;
+
vlc_mutex_lock( &p_input->p->counters.counters_lock );
- stats_UpdateInteger( p_input->p->counters.p_read_bytes,
- p_block->i_buffer, &i_total );
- stats_UpdateFloat( p_input->p->counters.p_input_bitrate,
- (float)i_total, NULL );
- stats_UpdateInteger( p_input->p->counters.p_read_packets,
- 1 , NULL);
+ stats_Update( p_input->p->counters.p_read_bytes,
+ p_block->i_buffer, &total );
+ stats_Update( p_input->p->counters.p_input_bitrate, total, NULL );
+ stats_Update( p_input->p->counters.p_read_packets, 1 , NULL);
vlc_mutex_unlock( &p_input->p->counters.counters_lock );
}
}
typedef struct counter_sample_t
{
- vlc_value_t value;
- mtime_t date;
+ uint64_t value;
+ mtime_t date;
} counter_sample_t;
typedef struct counter_t
{
- int i_type;
int i_compute_type;
int i_samples;
counter_sample_t ** pp_samples;
STATS_LOST_PICTURES,
};
-int stats_Update (counter_t *, vlc_value_t, vlc_value_t *);
-counter_t * stats_CounterCreate (int, int);
-int stats_Get (counter_t *, vlc_value_t*);
-
+counter_t * stats_CounterCreate (int);
+void stats_Update (counter_t *, uint64_t, uint64_t *);
void stats_CounterClean (counter_t * );
-static inline int stats_GetInteger( counter_t *p_counter, int64_t *value )
-{
- int i_ret;
- vlc_value_t val; val.i_int = 0;
- if( !p_counter ) return VLC_EGENERIC;
- i_ret = stats_Get( p_counter, &val );
- *value = val.i_int;
- return i_ret;
-}
-
-static inline int stats_GetFloat( counter_t *p_counter, float *value )
-{
- int i_ret;
- vlc_value_t val; val.f_float = 0.0;
- if( !p_counter ) return VLC_EGENERIC;
- i_ret = stats_Get( p_counter, &val );
- *value = val.f_float;
- return i_ret;
-}
-
-static inline int stats_UpdateInteger( counter_t *p_co, int i, int *pi_new )
-{
- int i_ret;
- vlc_value_t val;
- vlc_value_t new_val; new_val.i_int = 0;
- if( !p_co ) return VLC_EGENERIC;
- val.i_int = i;
- i_ret = stats_Update( p_co, val, &new_val );
- if( pi_new )
- *pi_new = new_val.i_int;
- return i_ret;
-}
-
-static inline int stats_UpdateFloat( counter_t *p_co, float f, float *pf_new )
-{
- vlc_value_t val;
- int i_ret;
- vlc_value_t new_val;new_val.f_float = 0.0;
- if( !p_co ) return VLC_EGENERIC;
- val.f_float = f;
- i_ret = stats_Update( p_co, val, &new_val );
- if( pf_new )
- *pf_new = new_val.f_float;
- return i_ret;
-}
-
void stats_ComputeInputStats(input_thread_t*, input_stats_t*);
void stats_ReinitInputStats(input_stats_t *);
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
-#include <stdio.h> /* required */
-
#include "input/input_internal.h"
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int CounterUpdate( counter_t *p_counter,
- vlc_value_t val, vlc_value_t * );
-
-/*****************************************************************************
- * Exported functions
- *****************************************************************************/
-
/**
* Create a statistics counter
- * \param i_type the type of stored data. One of VLC_VAR_STRING,
- * VLC_VAR_INTEGER, VLC_VAR_FLOAT
* \param i_compute_type the aggregation type. One of STATS_LAST (always
* keep the last value), STATS_COUNTER (increment by the passed value),
* STATS_MAX (keep the maximum passed value), STATS_MIN, or STATS_DERIVATIVE
* (keep a time derivative of the value)
*/
-counter_t * stats_CounterCreate( int i_type, int i_compute_type )
+counter_t * stats_CounterCreate( int i_compute_type )
{
counter_t *p_counter = (counter_t*) malloc( sizeof( counter_t ) ) ;
if( !p_counter ) return NULL;
p_counter->i_compute_type = i_compute_type;
- p_counter->i_type = i_type;
p_counter->i_samples = 0;
p_counter->pp_samples = NULL;
return p_counter;
}
-/** Update a counter element with new values
- * \param p_counter the counter to update
- * \param val the vlc_value union containing the new value to aggregate. For
- * more information on how data is aggregated, \see stats_Create
- * \param val_new a pointer that will be filled with new data
- */
-int stats_Update( counter_t *p_counter,
- vlc_value_t val, vlc_value_t *val_new )
+static inline int64_t stats_GetTotal(const counter_t *counter)
{
- if( !p_counter ) return VLC_EGENERIC;
- return CounterUpdate( p_counter, val, val_new );
+ if (counter == NULL || counter->i_samples == 0)
+ return 0;
+ return counter->pp_samples[0]->value;
}
-/** Get the aggregated value for a counter
- * \param p_this an object
- * \param p_counter the counter
- * \param val a pointer to an initialized vlc_value union. It will contain the
- * retrieved value
- * \return an error code
- */
-int stats_Get( counter_t *p_counter, vlc_value_t *val )
+static inline float stats_GetRate(const counter_t *counter)
{
- if( !p_counter || p_counter->i_samples == 0 )
- {
- val->i_int = 0;
- return VLC_EGENERIC;
- }
+ if (counter == NULL || counter->i_samples < 2)
+ return 0.;
- switch( p_counter->i_compute_type )
- {
- case STATS_COUNTER:
- *val = p_counter->pp_samples[0]->value;
- break;
- case STATS_DERIVATIVE:
- /* Not ready yet */
- if( p_counter->i_samples < 2 )
- {
- val->i_int = 0;
- return VLC_EGENERIC;
- }
- if( p_counter->i_type == VLC_VAR_INTEGER )
- {
- float f = ( p_counter->pp_samples[0]->value.i_int -
- p_counter->pp_samples[1]->value.i_int ) /
- (float)( p_counter->pp_samples[0]->date -
- p_counter->pp_samples[1]->date );
- val->i_int = (int64_t)f;
- }
- else
- {
- float f = (float)( p_counter->pp_samples[0]->value.f_float -
- p_counter->pp_samples[1]->value.f_float ) /
- (float)( p_counter->pp_samples[0]->date -
- p_counter->pp_samples[1]->date );
- val->f_float = f;
- }
- break;
- }
- return VLC_SUCCESS;;
+ return (counter->pp_samples[0]->value - counter->pp_samples[1]->value)
+ / (float)(counter->pp_samples[0]->date - counter->pp_samples[1]->date);
}
input_stats_t *stats_NewInputStats( input_thread_t *p_input )
return p_stats;
}
-void stats_ComputeInputStats( input_thread_t *p_input, input_stats_t *p_stats )
+void stats_ComputeInputStats(input_thread_t *input, input_stats_t *st)
{
- if( !libvlc_stats (p_input) ) return;
+ if (!libvlc_stats(input))
+ return;
- vlc_mutex_lock( &p_input->p->counters.counters_lock );
- vlc_mutex_lock( &p_stats->lock );
+ vlc_mutex_lock(&input->p->counters.counters_lock);
+ vlc_mutex_lock(&st->lock);
/* Input */
- stats_GetInteger( p_input->p->counters.p_read_packets,
- &p_stats->i_read_packets );
- stats_GetInteger( p_input->p->counters.p_read_bytes,
- &p_stats->i_read_bytes );
- stats_GetFloat( p_input->p->counters.p_input_bitrate,
- &p_stats->f_input_bitrate );
- stats_GetInteger( p_input->p->counters.p_demux_read,
- &p_stats->i_demux_read_bytes );
- stats_GetFloat( p_input->p->counters.p_demux_bitrate,
- &p_stats->f_demux_bitrate );
- stats_GetInteger( p_input->p->counters.p_demux_corrupted,
- &p_stats->i_demux_corrupted );
- stats_GetInteger( p_input->p->counters.p_demux_discontinuity,
- &p_stats->i_demux_discontinuity );
+ st->i_read_packets = stats_GetTotal(input->p->counters.p_read_packets);
+ st->i_read_bytes = stats_GetTotal(input->p->counters.p_read_bytes);
+ st->f_input_bitrate = stats_GetRate(input->p->counters.p_input_bitrate);
+ st->i_demux_read_bytes = stats_GetTotal(input->p->counters.p_demux_read);
+ st->f_demux_bitrate = stats_GetRate(input->p->counters.p_demux_bitrate);
+ st->i_demux_corrupted = stats_GetTotal(input->p->counters.p_demux_corrupted);
+ st->i_demux_discontinuity = stats_GetTotal(input->p->counters.p_demux_discontinuity);
/* Decoders */
- stats_GetInteger( p_input->p->counters.p_decoded_video,
- &p_stats->i_decoded_video );
- stats_GetInteger( p_input->p->counters.p_decoded_audio,
- &p_stats->i_decoded_audio );
+ st->i_decoded_video = stats_GetTotal(input->p->counters.p_decoded_video);
+ st->i_decoded_audio = stats_GetTotal(input->p->counters.p_decoded_audio);
/* Sout */
- if( p_input->p->counters.p_sout_send_bitrate )
+ if (input->p->counters.p_sout_send_bitrate)
{
- stats_GetInteger( p_input->p->counters.p_sout_sent_packets,
- &p_stats->i_sent_packets );
- stats_GetInteger( p_input->p->counters.p_sout_sent_bytes,
- &p_stats->i_sent_bytes );
- stats_GetFloat ( p_input->p->counters.p_sout_send_bitrate,
- &p_stats->f_send_bitrate );
+ st->i_sent_packets = stats_GetTotal(input->p->counters.p_sout_sent_packets);
+ st->i_sent_bytes = stats_GetTotal(input->p->counters.p_sout_sent_bytes);
+ st->f_send_bitrate = stats_GetRate(input->p->counters.p_sout_send_bitrate);
}
/* Aout */
- stats_GetInteger( p_input->p->counters.p_played_abuffers,
- &p_stats->i_played_abuffers );
- stats_GetInteger( p_input->p->counters.p_lost_abuffers,
- &p_stats->i_lost_abuffers );
+ st->i_played_abuffers = stats_GetTotal(input->p->counters.p_played_abuffers);
+ st->i_lost_abuffers = stats_GetTotal(input->p->counters.p_lost_abuffers);
/* Vouts */
- stats_GetInteger( p_input->p->counters.p_displayed_pictures,
- &p_stats->i_displayed_pictures );
- stats_GetInteger( p_input->p->counters.p_lost_pictures,
- &p_stats->i_lost_pictures );
+ st->i_displayed_pictures = stats_GetTotal(input->p->counters.p_displayed_pictures);
+ st->i_lost_pictures = stats_GetTotal(input->p->counters.p_lost_pictures);
- vlc_mutex_unlock( &p_stats->lock );
- vlc_mutex_unlock( &p_input->p->counters.counters_lock );
+ vlc_mutex_unlock(&st->lock);
+ vlc_mutex_unlock(&input->p->counters.counters_lock);
}
void stats_ReinitInputStats( input_stats_t *p_stats )
}
-/********************************************************************
- * 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
+/** Update a counter element with new values
* \param p_counter the counter to update
- * \param val the "new" value
- * \return an error code
+ * \param val the vlc_value union containing the new value to aggregate. For
+ * more information on how data is aggregated, \see stats_Create
+ * \param val_new a pointer that will be filled with new data
*/
-static int CounterUpdate( counter_t *p_counter,
- vlc_value_t val, vlc_value_t *new_val )
+void stats_Update( counter_t *p_counter, uint64_t val, uint64_t *new_val )
{
+ if( !p_counter )
+ return;
+
switch( p_counter->i_compute_type )
{
case STATS_DERIVATIVE:
counter_sample_t *p_new, *p_old;
mtime_t now = mdate();
if( now - p_counter->last_update < CLOCK_FREQ )
- {
- return VLC_EGENERIC;
- }
+ return;
p_counter->last_update = now;
/* Insert the new one at the beginning */
p_new = (counter_sample_t*)malloc( sizeof( counter_sample_t ) );
{
counter_sample_t *p_new = (counter_sample_t*)malloc(
sizeof( counter_sample_t ) );
- p_new->value.i_int = 0;
+ p_new->value = 0;
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;
- }
+ p_counter->pp_samples[0]->value += val;
+ if( new_val )
+ *new_val = p_counter->pp_samples[0]->value;
}
break;
}
- return VLC_SUCCESS;
}