+ return p_counter;
+}
+
+/** Update a counter element with new values
+ * \param p_this a VLC object
+ * \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( vlc_object_t *p_this, counter_t *p_counter,
+ vlc_value_t val, vlc_value_t *val_new )
+{
+ if( !libvlc_stats (p_this) || !p_counter ) return VLC_EGENERIC;
+ return CounterUpdate( p_this, p_counter, val, val_new );
+}
+
+#undef stats_Get
+/** 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( vlc_object_t *p_this, counter_t *p_counter, vlc_value_t *val )
+{
+ if( !libvlc_stats (p_this) || !p_counter || p_counter->i_samples == 0 )
+ {
+ val->i_int = 0;
+ return VLC_EGENERIC;
+ }
+
+ switch( p_counter->i_compute_type )
+ {
+ case STATS_LAST:
+ case STATS_MIN:
+ case STATS_MAX:
+ 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 = (int)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;;
+}
+
+input_stats_t *stats_NewInputStats( input_thread_t *p_input )
+{
+ (void)p_input;
+ input_stats_t *p_stats = calloc( 1, sizeof(input_stats_t) );
+ if( !p_stats )
+ return NULL;
+
+ vlc_mutex_init( &p_stats->lock );
+ stats_ReinitInputStats( p_stats );
+
+ return p_stats;
+}
+
+void stats_ComputeInputStats( input_thread_t *p_input, input_stats_t *p_stats )
+{
+ if( !libvlc_stats (p_input) ) return;
+
+ vlc_mutex_lock( &p_input->p->counters.counters_lock );
+ vlc_mutex_lock( &p_stats->lock );
+
+ /* Input */
+ stats_GetInteger( p_input, p_input->p->counters.p_read_packets,
+ &p_stats->i_read_packets );
+ stats_GetInteger( p_input, p_input->p->counters.p_read_bytes,
+ &p_stats->i_read_bytes );
+ stats_GetFloat( p_input, p_input->p->counters.p_input_bitrate,
+ &p_stats->f_input_bitrate );
+ stats_GetInteger( p_input, p_input->p->counters.p_demux_read,
+ &p_stats->i_demux_read_bytes );
+ stats_GetFloat( p_input, p_input->p->counters.p_demux_bitrate,
+ &p_stats->f_demux_bitrate );
+ stats_GetInteger( p_input, p_input->p->counters.p_demux_corrupted,
+ &p_stats->i_demux_corrupted );
+ stats_GetInteger( p_input, p_input->p->counters.p_demux_discontinuity,
+ &p_stats->i_demux_discontinuity );
+
+ /* Decoders */
+ stats_GetInteger( p_input, p_input->p->counters.p_decoded_video,
+ &p_stats->i_decoded_video );
+ stats_GetInteger( p_input, p_input->p->counters.p_decoded_audio,
+ &p_stats->i_decoded_audio );
+
+ /* Sout */
+ if( p_input->p->counters.p_sout_send_bitrate )
+ {
+ stats_GetInteger( p_input, p_input->p->counters.p_sout_sent_packets,
+ &p_stats->i_sent_packets );
+ stats_GetInteger( p_input, p_input->p->counters.p_sout_sent_bytes,
+ &p_stats->i_sent_bytes );
+ stats_GetFloat ( p_input, p_input->p->counters.p_sout_send_bitrate,
+ &p_stats->f_send_bitrate );
+ }
+
+ /* Aout */
+ stats_GetInteger( p_input, p_input->p->counters.p_played_abuffers,
+ &p_stats->i_played_abuffers );
+ stats_GetInteger( p_input, p_input->p->counters.p_lost_abuffers,
+ &p_stats->i_lost_abuffers );
+
+ /* Vouts */
+ stats_GetInteger( p_input, p_input->p->counters.p_displayed_pictures,
+ &p_stats->i_displayed_pictures );
+ stats_GetInteger( p_input, p_input->p->counters.p_lost_pictures,
+ &p_stats->i_lost_pictures );
+
+ vlc_mutex_unlock( &p_stats->lock );
+ vlc_mutex_unlock( &p_input->p->counters.counters_lock );