Partial rewrite of stats to avoid lookups (Closes:#693)
authorClément Stenac <zorglub@videolan.org>
Thu, 15 Jun 2006 21:22:35 +0000 (21:22 +0000)
committerClément Stenac <zorglub@videolan.org>
Thu, 15 Jun 2006 21:22:35 +0000 (21:22 +0000)
19 files changed:
include/main.h
include/vlc_httpd.h
include/vlc_input.h
include/vlc_messages.h
include/vlc_symbols.h
src/audio_output/dec.c
src/audio_output/input.c
src/input/decoder.c
src/input/es_out.c
src/input/input.c
src/input/stream.c
src/libvlc.c
src/misc/objects.c
src/misc/stats.c
src/network/httpd.c
src/playlist/control.c
src/playlist/thread.c
src/stream_output/stream_output.c
src/video_output/video_output.c

index 8505478..46a2ccc 100644 (file)
@@ -56,7 +56,9 @@ struct libvlc_t
 
     /* Do stats ? - We keep this boolean to avoid unneeded lookups */
     vlc_bool_t             b_stats;
-    stats_handler_t       *p_stats;
+    vlc_mutex_t            timer_lock;
+    int                    i_timers;
+    counter_t            **pp_timers;
 
     /* Arch-specific variables */
 #if !defined( WIN32 )
index ab3bb02..862f749 100644 (file)
@@ -77,6 +77,10 @@ struct httpd_host_t
     int         i_port;
     int         *fd;
 
+    /* Statistics */
+    counter_t *p_active_counter;
+    counter_t *p_total_counter;
+
     vlc_mutex_t lock;
 
     /* all registered url (becarefull that 2 httpd_url_t could point at the same url)
index 5333c82..897c2f7 100644 (file)
@@ -421,6 +421,26 @@ struct input_thread_t
     int            i_slave;
     input_source_t **slave;
 
+    /* Stats counters */
+    struct {
+        counter_t *p_read_packets;
+        counter_t *p_read_bytes;
+        counter_t *p_input_bitrate;
+        counter_t *p_demux_read;
+        counter_t *p_demux_bitrate;
+        counter_t *p_decoded_audio;
+        counter_t *p_decoded_video;
+        counter_t *p_decoded_sub;
+        counter_t *p_sout_sent_packets;
+        counter_t *p_sout_sent_bytes;
+        counter_t *p_sout_send_bitrate;
+        counter_t *p_played_abuffers;
+        counter_t *p_lost_abuffers;
+        counter_t *p_displayed_pictures;
+        counter_t *p_lost_pictures;
+        vlc_mutex_t counters_lock;
+    } counters;
+
     /* Buffer of pending actions */
     vlc_mutex_t lock_control;
     int i_control;
index 6bd1d3b..7b9e7d6 100644 (file)
@@ -228,8 +228,7 @@ struct counter_sample_t
 
 struct counter_t
 {
-    /* The list is *NOT* sorted at the moment, it could be ... */
-    uint64_t            i_index;
+    unsigned int        i_id;
     char              * psz_name;
     int                 i_type;
     int                 i_compute_type;
@@ -267,70 +266,58 @@ enum
     STATS_TIMER_SKINS_PLAYTREE_IMAGE,
 };
 
-struct stats_handler_t
-{
-    VLC_COMMON_MEMBERS
-
-    int                 i_counters;
-    counter_t         **pp_counters;
-};
+#define stats_Update(a,b,c) __stats_Update( VLC_OBJECT(a), b, c )
+VLC_EXPORT( int, __stats_Update, (vlc_object_t*, counter_t *, vlc_value_t, vlc_value_t *) );
+#define stats_CounterCreate(a,b,c) __stats_CounterCreate( VLC_OBJECT(a), b, c )
+VLC_EXPORT( counter_t *, __stats_CounterCreate, (vlc_object_t*, int, int) );
+#define stats_Get(a,b,c) __stats_Get( VLC_OBJECT(a), b, c)
+VLC_EXPORT( int, __stats_Get, (vlc_object_t*, counter_t *, vlc_value_t*) );
 
-VLC_EXPORT( void, stats_HandlerDestroy, (stats_handler_t*) );
+VLC_EXPORT (void, stats_CounterClean, (counter_t * ) );
 
-#define stats_Update(a,b,c,d) __stats_Update( VLC_OBJECT( a ), b, c, d )
-VLC_EXPORT( int, __stats_Update, (vlc_object_t*, unsigned int, vlc_value_t, vlc_value_t *) );
-#define stats_Create(a,b,c,d,e) __stats_Create( VLC_OBJECT(a), b, c, d,e )
-VLC_EXPORT( int, __stats_Create, (vlc_object_t*, const char *, unsigned int, int, int) );
-#define stats_Get(a,b,c,d) __stats_Get( VLC_OBJECT(a), b, c, d )
-VLC_EXPORT( int, __stats_Get, (vlc_object_t*, int, unsigned int, vlc_value_t*) );
-#define stats_CounterGet(a,b,c) __stats_CounterGet( VLC_OBJECT(a), b, c )
-VLC_EXPORT( counter_t*, __stats_CounterGet, (vlc_object_t*, int, unsigned int ) );
-
-#define stats_GetInteger(a,b,c,d) __stats_GetInteger( VLC_OBJECT(a), b, c, d )
-static inline int __stats_GetInteger( vlc_object_t *p_obj, int i_id,
-                                      unsigned int i_counter, int *value )
+#define stats_GetInteger(a,b,c) __stats_GetInteger( VLC_OBJECT(a), b, c )
+static inline int __stats_GetInteger( vlc_object_t *p_obj, counter_t *p_counter,
+                                      int *value )
 {
     int i_ret;
     vlc_value_t val; val.i_int = 0;
-    i_ret = __stats_Get( p_obj, i_id, i_counter, &val );
+    i_ret = __stats_Get( p_obj, p_counter, &val );
     *value = val.i_int;
     return i_ret;
 }
 
-#define stats_GetFloat(a,b,c,d) __stats_GetFloat( VLC_OBJECT(a), b, c, d )
-static inline int __stats_GetFloat( vlc_object_t *p_obj, int i_id,
-                                    unsigned int i_counter, float *value )
+#define stats_GetFloat(a,b,c) __stats_GetFloat( VLC_OBJECT(a), b, c )
+static inline int __stats_GetFloat( vlc_object_t *p_obj, counter_t *p_counter,
+                                    float *value )
 {
-       int i_ret;
+    int i_ret;
     vlc_value_t val; val.f_float = 0.0;
-    i_ret = __stats_Get( p_obj, i_id, i_counter, &val );
+    i_ret = __stats_Get( p_obj, p_counter, &val );
     *value = val.f_float;
     return i_ret;
 }
 #define stats_UpdateInteger(a,b,c,d) __stats_UpdateInteger( VLC_OBJECT(a),b,c,d )
-static inline int __stats_UpdateInteger( vlc_object_t *p_obj,
-                                         unsigned int i_counter, int i,
-                                         int *pi_new )
+static inline int __stats_UpdateInteger( vlc_object_t *p_obj,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;
     val.i_int = i;
-    i_ret = __stats_Update( p_obj, i_counter, val , &new_val );
+    i_ret = __stats_Update( p_obj, p_co, val, &new_val );
     if( pi_new )
         *pi_new = new_val.i_int;
     return i_ret;
 }
 #define stats_UpdateFloat(a,b,c,d) __stats_UpdateFloat( VLC_OBJECT(a),b,c,d )
-static inline int __stats_UpdateFloat( vlc_object_t *p_obj,
-                                       unsigned int i_counter, float f,
-                                       float *pf_new )
+static inline int __stats_UpdateFloat( vlc_object_t *p_obj, 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;
     val.f_float = f;
-    i_ret =  __stats_Update( p_obj, i_counter, val, &new_val );
+    i_ret =  __stats_Update( p_obj, p_co, val, &new_val );
     if( pf_new )
         *pf_new = new_val.f_float;
     return i_ret;
@@ -413,3 +400,5 @@ VLC_EXPORT( void,__stats_TimerStart, (vlc_object_t*, const char *, unsigned int
 VLC_EXPORT( void,__stats_TimerStop, (vlc_object_t*, unsigned int) );
 VLC_EXPORT( void,__stats_TimerDump, (vlc_object_t*, unsigned int) );
 VLC_EXPORT( void,__stats_TimersDumpAll, (vlc_object_t*) );
+#define stats_TimersClean(a) __stats_TimersClean( VLC_OBJECT(a) )
+VLC_EXPORT( void, __stats_TimersClean, (vlc_object_t * ) );
index 6974e56..aee4c56 100644 (file)
@@ -438,16 +438,15 @@ struct module_symbols_t
     int (*__intf_UserProgress_inner) (vlc_object_t*, const char*, const char*, float);
     void (*__intf_UserProgressUpdate_inner) (vlc_object_t*, int, const char*, float);
     void (*__intf_UserHide_inner) (vlc_object_t *, int);
-    int (*__stats_Create_inner) (vlc_object_t*, const char *, unsigned int, int, int);
-    int (*__stats_Update_inner) (vlc_object_t*, unsigned int, vlc_value_t, vlc_value_t *);
-    int (*__stats_Get_inner) (vlc_object_t*, int, unsigned int, vlc_value_t*);
+    void *__stats_Create_deprecated;
+    int (*__stats_Update_inner) (vlc_object_t*, counter_t *, vlc_value_t, vlc_value_t *);
+    int (*__stats_Get_inner) (vlc_object_t*, counter_t *, vlc_value_t*);
     void (*stats_ComputeInputStats_inner) (input_thread_t*, input_stats_t*);
     void (*stats_DumpInputStats_inner) (input_stats_t *);
     void (*stats_ReinitInputStats_inner) (input_stats_t *);
-    counter_t* (*__stats_CounterGet_inner) (vlc_object_t*, int, unsigned int);
     void *__stats_CounterGet_deprecated;
     input_thread_t * (*__input_CreateThread2_inner) (vlc_object_t *, input_item_t *, char *);
-    void (*stats_HandlerDestroy_inner) (stats_handler_t*);
+    void *stats_HandlerDestroy_deprecated;
     vlc_t * (*vlc_current_object_inner) (int);
     void (*__var_OptionParse_inner) (vlc_object_t *, const char *);
     void *__stats_TimerDumpAll_deprecated;
@@ -514,6 +513,10 @@ struct module_symbols_t
     int (*__intf_UserStringInput_inner) (vlc_object_t*, const char*, const char*, char **);
     void (*playlist_NodesCreateForSD_inner) (playlist_t *, char *, playlist_item_t **, playlist_item_t **);
     vlc_bool_t (*input_AddSubtitles_inner) (input_thread_t *, char *, vlc_bool_t);
+    counter_t * (*__stats_CounterCreate_inner) (vlc_object_t*, int, int);
+    void *stats_TimerClean_deprecated;
+    void *stats_TimersClean_deprecated;
+    void (*__stats_TimersClean_inner) (vlc_object_t *);
 };
 # if defined (__PLUGIN__)
 #  define aout_FiltersCreatePipeline (p_symbols)->aout_FiltersCreatePipeline_inner
@@ -909,15 +912,12 @@ struct module_symbols_t
 #  define __intf_UserProgress (p_symbols)->__intf_UserProgress_inner
 #  define __intf_UserProgressUpdate (p_symbols)->__intf_UserProgressUpdate_inner
 #  define __intf_UserHide (p_symbols)->__intf_UserHide_inner
-#  define __stats_Create (p_symbols)->__stats_Create_inner
 #  define __stats_Update (p_symbols)->__stats_Update_inner
 #  define __stats_Get (p_symbols)->__stats_Get_inner
 #  define stats_ComputeInputStats (p_symbols)->stats_ComputeInputStats_inner
 #  define stats_DumpInputStats (p_symbols)->stats_DumpInputStats_inner
 #  define stats_ReinitInputStats (p_symbols)->stats_ReinitInputStats_inner
-#  define __stats_CounterGet (p_symbols)->__stats_CounterGet_inner
 #  define __input_CreateThread2 (p_symbols)->__input_CreateThread2_inner
-#  define stats_HandlerDestroy (p_symbols)->stats_HandlerDestroy_inner
 #  define vlc_current_object (p_symbols)->vlc_current_object_inner
 #  define __var_OptionParse (p_symbols)->__var_OptionParse_inner
 #  define __stats_TimerDump (p_symbols)->__stats_TimerDump_inner
@@ -982,6 +982,8 @@ struct module_symbols_t
 #  define __intf_UserStringInput (p_symbols)->__intf_UserStringInput_inner
 #  define playlist_NodesCreateForSD (p_symbols)->playlist_NodesCreateForSD_inner
 #  define input_AddSubtitles (p_symbols)->input_AddSubtitles_inner
+#  define __stats_CounterCreate (p_symbols)->__stats_CounterCreate_inner
+#  define __stats_TimersClean (p_symbols)->__stats_TimersClean_inner
 # elif defined (HAVE_DYNAMIC_PLUGINS) && !defined (__BUILTIN__)
 /******************************************************************
  * STORE_SYMBOLS: store VLC APIs into p_symbols for plugin access.
@@ -1380,15 +1382,12 @@ struct module_symbols_t
     ((p_symbols)->__intf_UserProgress_inner) = __intf_UserProgress; \
     ((p_symbols)->__intf_UserProgressUpdate_inner) = __intf_UserProgressUpdate; \
     ((p_symbols)->__intf_UserHide_inner) = __intf_UserHide; \
-    ((p_symbols)->__stats_Create_inner) = __stats_Create; \
     ((p_symbols)->__stats_Update_inner) = __stats_Update; \
     ((p_symbols)->__stats_Get_inner) = __stats_Get; \
     ((p_symbols)->stats_ComputeInputStats_inner) = stats_ComputeInputStats; \
     ((p_symbols)->stats_DumpInputStats_inner) = stats_DumpInputStats; \
     ((p_symbols)->stats_ReinitInputStats_inner) = stats_ReinitInputStats; \
-    ((p_symbols)->__stats_CounterGet_inner) = __stats_CounterGet; \
     ((p_symbols)->__input_CreateThread2_inner) = __input_CreateThread2; \
-    ((p_symbols)->stats_HandlerDestroy_inner) = stats_HandlerDestroy; \
     ((p_symbols)->vlc_current_object_inner) = vlc_current_object; \
     ((p_symbols)->__var_OptionParse_inner) = __var_OptionParse; \
     ((p_symbols)->__stats_TimerDump_inner) = __stats_TimerDump; \
@@ -1453,6 +1452,8 @@ struct module_symbols_t
     ((p_symbols)->__intf_UserStringInput_inner) = __intf_UserStringInput; \
     ((p_symbols)->playlist_NodesCreateForSD_inner) = playlist_NodesCreateForSD; \
     ((p_symbols)->input_AddSubtitles_inner) = input_AddSubtitles; \
+    ((p_symbols)->__stats_CounterCreate_inner) = __stats_CounterCreate; \
+    ((p_symbols)->__stats_TimersClean_inner) = __stats_TimersClean; \
     (p_symbols)->net_ConvertIPv4_deprecated = NULL; \
     (p_symbols)->__playlist_ItemCopy_deprecated = NULL; \
     (p_symbols)->playlist_ItemAddParent_deprecated = NULL; \
@@ -1479,9 +1480,13 @@ struct module_symbols_t
     (p_symbols)->playlist_Sort_deprecated = NULL; \
     (p_symbols)->playlist_Move_deprecated = NULL; \
     (p_symbols)->playlist_NodeRemoveParent_deprecated = NULL; \
+    (p_symbols)->__stats_Create_deprecated = NULL; \
     (p_symbols)->__stats_CounterGet_deprecated = NULL; \
+    (p_symbols)->stats_HandlerDestroy_deprecated = NULL; \
     (p_symbols)->__stats_TimerDumpAll_deprecated = NULL; \
     (p_symbols)->playlist_ItemNewFromInput_deprecated = NULL; \
+    (p_symbols)->stats_TimerClean_deprecated = NULL; \
+    (p_symbols)->stats_TimersClean_deprecated = NULL; \
 
 # endif /* __PLUGIN__ */
 #endif /* __VLC_SYMBOLS_H */
index cecd583..8dd41be 100644 (file)
@@ -312,8 +312,11 @@ int aout_DecPlay( aout_instance_t * p_aout, aout_input_t * p_input,
                   p_buffer->start_date - mdate());
         if( p_input->p_input_thread )
         {
-            stats_UpdateInteger( p_input->p_input_thread, STATS_LOST_ABUFFERS, 1,
-                                 NULL );
+            vlc_mutex_lock( &p_input->p_input_thread->counters.counters_lock);
+            stats_UpdateInteger( p_aout,
+                           p_input->p_input_thread->counters.p_lost_abuffers,
+                           1, NULL );
+            vlc_mutex_unlock( &p_input->p_input_thread->counters.counters_lock);
         }
         aout_BufferFree( p_buffer );
         return -1;
@@ -367,8 +370,11 @@ int aout_DecPlay( aout_instance_t * p_aout, aout_input_t * p_input,
     aout_MixerRun( p_aout );
     if( p_input->p_input_thread )
     {
-        stats_UpdateInteger( p_input->p_input_thread,
-                             STATS_PLAYED_ABUFFERS, 1, NULL );
+        vlc_mutex_lock( &p_input->p_input_thread->counters.counters_lock);
+        stats_UpdateInteger( p_aout,
+                             p_input->p_input_thread->counters.p_lost_abuffers,
+                             1, NULL );
+        vlc_mutex_unlock( &p_input->p_input_thread->counters.counters_lock);
     }
     vlc_mutex_unlock( &p_aout->mixer_lock );
 
index 3566bdf..3df1f4f 100644 (file)
@@ -449,8 +449,9 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
         start_date = 0;
         if( p_input->p_input_thread )
         {
-            stats_UpdateInteger( p_input->p_input_thread, STATS_LOST_ABUFFERS, 1,
-                                 NULL );
+            vlc_mutex_lock( &p_input->p_input_thread->counters.counters_lock);
+            stats_UpdateInteger( p_aout, p_input->p_input_thread->counters.p_lost_abuffers, 1, NULL );
+            vlc_mutex_unlock( &p_input->p_input_thread->counters.counters_lock);
         }
     }
 
@@ -462,8 +463,9 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
                   mdate() - p_buffer->start_date );
         if( p_input->p_input_thread )
         {
-            stats_UpdateInteger( p_input->p_input_thread, STATS_LOST_ABUFFERS,
-                                 1, NULL );
+            vlc_mutex_lock( &p_input->p_input_thread->counters.counters_lock);
+            stats_UpdateInteger( p_aout, p_input->p_input_thread->counters.p_lost_abuffers, 1, NULL );
+            vlc_mutex_unlock( &p_input->p_input_thread->counters.counters_lock);
         }
         aout_BufferFree( p_buffer );
         p_input->i_resampling_type = AOUT_RESAMPLING_NONE;
@@ -504,8 +506,9 @@ int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
         aout_BufferFree( p_buffer );
         if( p_input->p_input_thread )
         {
-            stats_UpdateInteger( p_input->p_input_thread, STATS_LOST_ABUFFERS,
-                                 1, NULL );
+            vlc_mutex_lock( &p_input->p_input_thread->counters.counters_lock);
+            stats_UpdateInteger( p_aout, p_input->p_input_thread->counters.p_lost_abuffers, 1, NULL );
+            vlc_mutex_unlock( &p_input->p_input_thread->counters.counters_lock);
         }
         return 0;
     }
index 638275c..1a02901 100644 (file)
@@ -429,12 +429,6 @@ static decoder_t * CreateDecoder( input_thread_t *p_input,
 
     vlc_object_attach( p_dec, p_input );
 
-    stats_Create( p_dec->p_parent, "decoded_audio", STATS_DECODED_AUDIO,
-                  VLC_VAR_INTEGER, STATS_COUNTER );
-    stats_Create( p_dec->p_parent, "decoded_video", STATS_DECODED_VIDEO,
-                  VLC_VAR_INTEGER, STATS_COUNTER );
-    stats_Create( p_dec->p_parent, "decoded_sub", STATS_DECODED_SUB,
-                  VLC_VAR_INTEGER, STATS_COUNTER );
     /* Find a suitable decoder/packetizer module */
     if( i_object_type == VLC_OBJECT_DECODER )
         p_dec->p_module = module_Need( p_dec, "decoder", "$codec", 0 );
@@ -627,9 +621,14 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
                     while( (p_aout_buf = p_dec->pf_decode_audio( p_dec,
                                                        &p_packetized_block )) )
                     {
-                        stats_UpdateInteger( p_dec->p_parent,
-                                             STATS_DECODED_AUDIO, 1, NULL );
-                        /* FIXME the best would be to handle the case start_date < preroll < end_date
+                        input_thread_t *p_i =(input_thread_t*)(p_dec->p_parent);
+                        vlc_mutex_lock( &p_i->counters.counters_lock );
+                        stats_UpdateInteger( p_dec,
+                               p_i->counters.p_decoded_audio, 1, NULL );
+                        vlc_mutex_unlock( &p_i->counters.counters_lock );
+
+                        /* FIXME the best would be to handle the case
+                         * start_date < preroll < end_date
                          * but that's not easy with non raw audio stream */
                         if( p_dec->p_owner->i_preroll_end > 0 &&
                             p_aout_buf->start_date < p_dec->p_owner->i_preroll_end )
@@ -652,7 +651,12 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
         }
         else while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
         {
-            stats_UpdateInteger( p_dec->p_parent, STATS_DECODED_AUDIO, 1, NULL );
+            input_thread_t *p_i = (input_thread_t*)(p_dec->p_parent);
+            vlc_mutex_lock( &p_i->counters.counters_lock );
+            stats_UpdateInteger( p_dec,
+                               p_i->counters.p_decoded_audio, 1, NULL );
+            vlc_mutex_unlock( &p_i->counters.counters_lock );
+
             if( p_dec->p_owner->i_preroll_end > 0 &&
                 p_aout_buf->start_date < p_dec->p_owner->i_preroll_end )
             {
@@ -698,8 +702,12 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
                     while( (p_pic = p_dec->pf_decode_video( p_dec,
                                                        &p_packetized_block )) )
                     {
-                        stats_UpdateInteger( p_dec->p_parent, STATS_DECODED_VIDEO,
-                                                             1, NULL );
+                        input_thread_t *p_i =(input_thread_t*)(p_dec->p_parent);
+                        vlc_mutex_lock( &p_i->counters.counters_lock );
+                        stats_UpdateInteger( p_dec,
+                               p_i->counters.p_decoded_video, 1, NULL );
+                        vlc_mutex_unlock( &p_i->counters.counters_lock );
+
                         if( p_dec->p_owner->i_preroll_end > 0 &&
                             p_pic->date < p_dec->p_owner->i_preroll_end )
                         {
@@ -720,7 +728,12 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
         }
         else while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) )
         {
-            stats_UpdateInteger( p_dec->p_parent, STATS_DECODED_VIDEO, 1 , NULL);
+            input_thread_t *p_i = (input_thread_t*)(p_dec->p_parent);
+            vlc_mutex_lock( &p_i->counters.counters_lock );
+            stats_UpdateInteger( p_dec,
+                               p_i->counters.p_decoded_video, 1, NULL );
+            vlc_mutex_unlock( &p_i->counters.counters_lock );
+
             if( p_dec->p_owner->i_preroll_end > 0 &&
                 p_pic->date < p_dec->p_owner->i_preroll_end )
             {
@@ -740,7 +753,12 @@ static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
         subpicture_t *p_spu;
         while( (p_spu = p_dec->pf_decode_sub( p_dec, &p_block ) ) )
         {
-            stats_UpdateInteger( p_dec->p_parent, STATS_DECODED_SUB, 1 , NULL);
+            input_thread_t *p_i = (input_thread_t*)(p_dec->p_parent);
+            vlc_mutex_lock( &p_i->counters.counters_lock );
+            stats_UpdateInteger( p_dec,
+                               p_i->counters.p_decoded_sub, 1, NULL );
+            vlc_mutex_unlock( &p_i->counters.counters_lock );
+
             if( p_dec->p_owner->i_preroll_end > 0 &&
                 p_spu->i_start < p_dec->p_owner->i_preroll_end &&
                 ( p_spu->i_stop <= 0 || p_spu->i_stop <= p_dec->p_owner->i_preroll_end ) )
index f59ca7b..a76883f 100644 (file)
@@ -1025,9 +1025,12 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
 
     if( p_input->p_libvlc->b_stats )
     {
-        stats_UpdateInteger( p_input, STATS_DEMUX_READ, p_block->i_buffer,
-                             &i_total );
-        stats_UpdateFloat( p_input , STATS_DEMUX_BITRATE, (float)i_total, NULL );
+        vlc_mutex_lock( &p_input->counters.counters_lock );
+        stats_UpdateInteger( p_input, p_input->counters.p_demux_read,
+                             p_block->i_buffer, &i_total );
+        stats_UpdateFloat( p_input , p_input->counters.p_demux_bitrate,
+                           (float)i_total, NULL );
+        vlc_mutex_unlock( &p_input->counters.counters_lock );
     }
 
     /* Mark preroll blocks */
index 0e01e6b..66edd2b 100644 (file)
@@ -679,29 +679,27 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick )
     if( !b_quick )
     {
         /* Prepare statistics */
-        counter_t *p_counter;
-        stats_Create( p_input, "read_bytes", STATS_READ_BYTES,
-                      VLC_VAR_INTEGER, STATS_COUNTER );
-        stats_Create( p_input, "read_packets", STATS_READ_PACKETS,
-                      VLC_VAR_INTEGER, STATS_COUNTER );
-        stats_Create( p_input, "demux_read", STATS_DEMUX_READ,
-                      VLC_VAR_INTEGER, STATS_COUNTER );
-        stats_Create( p_input, "input_bitrate", STATS_INPUT_BITRATE,
-                      VLC_VAR_FLOAT, STATS_DERIVATIVE );
-        stats_Create( p_input, "demux_bitrate", STATS_DEMUX_BITRATE,
-                      VLC_VAR_FLOAT,  STATS_DERIVATIVE );
-
-        p_counter = stats_CounterGet( p_input, p_input->i_object_id,
-                                      STATS_INPUT_BITRATE );
-        if( p_counter ) p_counter->update_interval = 1000000;
-        p_counter = stats_CounterGet( p_input, p_input->i_object_id,
-                                      STATS_DEMUX_BITRATE );
-        if( p_counter ) p_counter->update_interval = 1000000;
-
-        stats_Create( p_input, "played_abuffers", STATS_PLAYED_ABUFFERS,
-                      VLC_VAR_INTEGER, STATS_COUNTER );
-        stats_Create( p_input, "lost_abuffers", STATS_LOST_ABUFFERS,
-                      VLC_VAR_INTEGER, STATS_COUNTER );
+#define INIT_COUNTER( p, type, compute ) p_input->counters.p_##p = \
+     stats_CounterCreate( p_input, VLC_VAR_##type, STATS_##compute);
+
+        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( 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 );
+        p_input->counters.p_sout_send_bitrate = NULL;
+        p_input->counters.p_sout_sent_packets = NULL;
+        p_input->counters.p_sout_sent_bytes = NULL;
+        p_input->counters.p_demux_bitrate->update_interval = 1000000;
+        p_input->counters.p_input_bitrate->update_interval = 1000000;
+        vlc_mutex_init( p_input, &p_input->counters.counters_lock );
 
         /* handle sout */
         psz = var_GetString( p_input, "sout" );
@@ -715,6 +713,10 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick )
                 free( psz );
                 return VLC_EGENERIC;
             }
+            INIT_COUNTER( sout_sent_packets, INTEGER, COUNTER );
+            INIT_COUNTER (sout_sent_bytes, INTEGER, COUNTER );
+            INIT_COUNTER( sout_send_bitrate, FLOAT, DERIVATIVE );
+            p_input->counters.p_sout_send_bitrate->update_interval = 1000000;
         }
         free( psz );
     }
@@ -1105,6 +1107,22 @@ static void End( input_thread_t * p_input )
     if( p_input->p_es_out )
         input_EsOutDelete( p_input->p_es_out );
 
+#define CL_CO( c ) stats_CounterClean( p_input->counters.p_##c )
+
+        CL_CO( read_bytes );
+        CL_CO( read_packets );
+        CL_CO( demux_read );
+        CL_CO( input_bitrate );
+        CL_CO( demux_bitrate );
+        CL_CO( played_abuffers );
+        CL_CO( lost_abuffers );
+        CL_CO( displayed_pictures );
+        CL_CO( lost_pictures );
+        CL_CO( decoded_audio) ;
+        CL_CO( decoded_video );
+        CL_CO( decoded_sub) ;
+        CL_CO( read_bytes );
+
     /* Close optional stream output instance */
     if( p_input->p_sout )
     {
@@ -1112,6 +1130,10 @@ static void End( input_thread_t * p_input )
             vlc_object_find( p_input, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
         vlc_value_t keep;
 
+        CL_CO( sout_sent_packets );
+        CL_CO( sout_sent_bytes );
+        CL_CO( sout_send_bitrate );
+
         if( var_Get( p_input, "sout-keep", &keep ) >= 0 && keep.b_bool && p_pl )
         {
             /* attach sout to the playlist */
@@ -1128,6 +1150,7 @@ static void End( input_thread_t * p_input )
             vlc_object_release( p_pl );
     }
 
+#undef CL_CO
     /* Tell we're dead */
     p_input->b_dead = VLC_TRUE;
 }
index c833f7d..7dddf52 100644 (file)
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 #include <vlc/vlc.h>
 #include <vlc/input.h>
+#include <assert.h>
 
 #include "input_internal.h"
 
@@ -1577,15 +1578,19 @@ static int AReadStream( stream_t *s, void *p_read, int i_read )
     int i_read_orig = i_read;
     int i_total;
 
+    input_thread_t *p_input = (input_thread_t *)s->p_parent->p_parent ;
+    assert( p_input );
+
     if( !p_sys->i_list )
     {
         i_read = p_access->pf_read( p_access, p_read, i_read );
-        stats_UpdateInteger( s->p_parent->p_parent , STATS_READ_BYTES, i_read,
+        vlc_mutex_lock( &p_input->counters.counters_lock );
+        stats_UpdateInteger( s, p_input->counters.p_read_bytes, i_read,
                              &i_total );
-        stats_UpdateFloat( s->p_parent->p_parent , STATS_INPUT_BITRATE,
+        stats_UpdateFloat( s, p_input->counters.p_input_bitrate,
                            (float)i_total, NULL );
-        stats_UpdateInteger( s->p_parent->p_parent , STATS_READ_PACKETS, 1,
-                             NULL );
+        stats_UpdateInteger( s, p_input->counters.p_read_packets, 1, NULL );
+        vlc_mutex_unlock( &p_input->counters.counters_lock );
         return i_read;
     }
 
@@ -1614,11 +1619,12 @@ static int AReadStream( stream_t *s, void *p_read, int i_read )
     }
 
     /* Update read bytes in input */
-    stats_UpdateInteger( s->p_parent->p_parent ,  STATS_READ_BYTES, i_read,
-                         &i_total );
-    stats_UpdateFloat( s->p_parent->p_parent ,  STATS_INPUT_BITRATE,
-                      (float)i_total, NULL );
-    stats_UpdateInteger( s->p_parent->p_parent ,  STATS_READ_PACKETS, 1, NULL );
+    vlc_mutex_lock( &p_input->counters.counters_lock );
+    stats_UpdateInteger( s, p_input->counters.p_read_bytes, i_read, &i_total );
+    stats_UpdateFloat( s, p_input->counters.p_input_bitrate,
+                       (float)i_total, NULL );
+    stats_UpdateInteger( s, p_input->counters.p_read_packets, 1, NULL );
+    vlc_mutex_unlock( &p_input->counters.counters_lock );
     return i_read;
 }
 
@@ -1630,17 +1636,22 @@ static block_t *AReadBlock( stream_t *s, vlc_bool_t *pb_eof )
     vlc_bool_t b_eof;
     int i_total;
 
+    input_thread_t *p_input = (input_thread_t *)s->p_parent->p_parent ;
+    assert( p_input );
+
     if( !p_sys->i_list )
     {
         p_block = p_access->pf_block( p_access );
         if( pb_eof ) *pb_eof = p_access->info.b_eof;
         if( p_block && p_access->p_libvlc->b_stats )
         {
-            stats_UpdateInteger( s->p_parent->p_parent,  STATS_READ_BYTES,
+            vlc_mutex_lock( &p_input->counters.counters_lock );
+            stats_UpdateInteger( s, p_input->counters.p_read_bytes,
                                  p_block->i_buffer, &i_total );
-            stats_UpdateFloat( s->p_parent->p_parent ,  STATS_INPUT_BITRATE,
+            stats_UpdateFloat( s, p_input->counters.p_input_bitrate,
                               (float)i_total, NULL );
-            stats_UpdateInteger( s->p_parent->p_parent ,  STATS_READ_PACKETS, 1, NULL );
+            stats_UpdateInteger( s, p_input->counters.p_read_packets, 1, NULL );
+            vlc_mutex_unlock( &p_input->counters.counters_lock );
         }
         return p_block;
     }
@@ -1671,14 +1682,15 @@ static block_t *AReadBlock( stream_t *s, vlc_bool_t *pb_eof )
     }
     if( p_block )
     {
-        stats_UpdateInteger( s->p_parent->p_parent,  STATS_READ_BYTES,
+        vlc_mutex_lock( &p_input->counters.counters_lock );
+        stats_UpdateInteger( s, p_input->counters.p_read_bytes,
                              p_block->i_buffer, &i_total );
-        stats_UpdateFloat( s->p_parent->p_parent ,  STATS_INPUT_BITRATE,
+        stats_UpdateFloat( s, p_input->counters.p_input_bitrate,
                           (float)i_total, NULL );
-        stats_UpdateInteger( s->p_parent->p_parent ,  STATS_READ_PACKETS,
+        stats_UpdateInteger( s, p_input->counters.p_read_packets,
                              1 , NULL);
+        vlc_mutex_unlock( &p_input->counters.counters_lock );
     }
-
     return p_block;
 }
 
index 9b7a7db..9e7d2bd 100644 (file)
@@ -686,7 +686,9 @@ int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
     }
 
     libvlc.b_stats = config_GetInt( p_vlc, "stats" );
-    libvlc.p_stats = NULL;
+    libvlc.i_timers = 0;
+    libvlc.pp_timers = NULL;
+    vlc_mutex_init( p_vlc, &libvlc.timer_lock );
 
     /*
      * Initialize hotkey handling
@@ -887,7 +889,6 @@ int VLC_CleanUp( int i_object )
     vout_thread_t      * p_vout;
     aout_instance_t    * p_aout;
     announce_handler_t * p_announce;
-    stats_handler_t    * p_stats;
     vlc_t *p_vlc = vlc_current_object( i_object );
 
     /* Check that the handle is valid */
@@ -942,14 +943,8 @@ int VLC_CleanUp( int i_object )
         aout_Delete( p_aout );
     }
 
-    while( ( p_stats = vlc_object_find( p_vlc, VLC_OBJECT_STATS, FIND_CHILD) ))
-    {
-        stats_TimersDumpAll( p_vlc );
-        stats_HandlerDestroy( p_stats );
-        vlc_object_detach( (vlc_object_t*) p_stats );
-        vlc_object_release( (vlc_object_t *)p_stats );
-        // TODO: Delete it
-    }
+    stats_TimersDumpAll( p_vlc );
+    stats_TimersClean( p_vlc );
 
     /*
      * Free announce handler(s?)
index 2478612..b140f93 100644 (file)
@@ -216,10 +216,6 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type )
             i_size = sizeof( osd_menu_t );
             psz_type = "osd menu";
             break;
-        case VLC_OBJECT_STATS:
-            i_size = sizeof( stats_handler_t );
-            psz_type = "statistics";
-            break;
         default:
             i_size = i_type > (int)sizeof(vlc_object_t)
                          ? i_type : (int)sizeof(vlc_object_t);
index 2f37949..821e7ea 100644 (file)
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static counter_t *GetCounter( stats_handler_t *p_handler, int i_object_id,
-                              unsigned int i_counter );
-static int stats_CounterUpdate( stats_handler_t *p_handler,
-                                counter_t *p_counter,
-                                vlc_value_t val, vlc_value_t * );
-static stats_handler_t* stats_HandlerCreate( vlc_object_t *p_this );
-static stats_handler_t *stats_HandlerGet( vlc_object_t *p_this );
-
+static int CounterUpdate( vlc_object_t *p_this,
+                          counter_t *p_counter,
+                          vlc_value_t val, vlc_value_t * );
 static void TimerDump( vlc_object_t *p_this, counter_t *p_counter, vlc_bool_t);
 
 /*****************************************************************************
  * Exported functions
  *****************************************************************************/
 
-/**
- * Cleanup statistics handler stuff
- * \param p_stats the handler to clean
- * \return nothing
- */
-void stats_HandlerDestroy( stats_handler_t *p_stats )
-{
-    int i;
-    for ( i =  p_stats->i_counters - 1 ; i >= 0 ; i-- )
-    {
-        int j;
-        counter_t *p_counter = p_stats->pp_counters[i];
-
-        for( j = p_counter->i_samples -1; j >= 0 ; j-- )
-        {
-            counter_sample_t *p_sample = p_counter->pp_samples[j];
-            REMOVE_ELEM( p_counter->pp_samples, p_counter->i_samples, j );
-            free( p_sample );
-        }
-        free( p_counter->psz_name );
-        REMOVE_ELEM( p_stats->pp_counters, p_stats->i_counters, i );
-        free( p_counter );
-    }
-}
-
 /**
  * Create a statistics counter
- * \param p_this the object for which to create the counter
- * \param psz_name the name
+ * \param p_this a VLC object
  * \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
@@ -82,111 +51,53 @@ void stats_HandlerDestroy( stats_handler_t *p_stats )
  * STATS_MAX (keep the maximum passed value), STATS_MIN, or STATS_DERIVATIVE
  * (keep a time derivative of the value)
  */
-int __stats_Create( vlc_object_t *p_this, const char *psz_name, unsigned int i_id,
-                    int i_type, int i_compute_type )
+counter_t * __stats_CounterCreate( vlc_object_t *p_this,
+                                   int i_type, int i_compute_type )
 {
     counter_t *p_counter;
-    stats_handler_t *p_handler;
-
-    if( !p_this->p_libvlc->b_stats ) return VLC_EGENERIC;
-
-    p_handler = stats_HandlerGet( p_this );
-    if( !p_handler ) return VLC_ENOMEM;
-
-    vlc_mutex_lock( &p_handler->object_lock );
+    if( !p_this->p_libvlc->b_stats ) return NULL;
 
     p_counter = (counter_t*) malloc( sizeof( counter_t ) ) ;
 
-    p_counter->psz_name = strdup( psz_name );
-    p_counter->i_index = ((uint64_t)p_this->i_object_id << 32 ) + i_id;
     p_counter->i_compute_type = i_compute_type;
     p_counter->i_type = i_type;
     p_counter->i_samples = 0;
     p_counter->pp_samples = NULL;
+    p_counter->psz_name = NULL;
 
     p_counter->update_interval = 0;
     p_counter->last_update = 0;
 
-    INSERT_ELEM( p_handler->pp_counters, p_handler->i_counters,
-                 p_handler->i_counters, p_counter );
-
-    vlc_mutex_unlock( &p_handler->object_lock );
-    vlc_object_release( p_handler );
-
-    return VLC_SUCCESS;
+    return p_counter;
 }
 
 /** Update a counter element with new values
- * \param p_this the object in which to update
- * \param psz_name the name
+ * \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, unsigned int i_counter,
+int __stats_Update( vlc_object_t *p_this, counter_t *p_counter,
                     vlc_value_t val, vlc_value_t *val_new )
 {
-    int i_ret;
-    counter_t *p_counter;
-    stats_handler_t *p_handler;
-
     if( !p_this->p_libvlc->b_stats ) return VLC_EGENERIC;
-
-    /* Get stats handler singleton */
-    p_handler = stats_HandlerGet( p_this );
-    if( !p_handler ) return VLC_ENOMEM;
-
-    vlc_mutex_lock( &p_handler->object_lock );
-    /* Look for existing element */
-    p_counter = GetCounter( p_handler, p_this->i_object_id, i_counter );
-    if( !p_counter )
-    {
-        vlc_mutex_unlock( &p_handler->object_lock );
-        vlc_object_release( p_handler );
-        return VLC_ENOOBJ;
-    }
-
-    i_ret = stats_CounterUpdate( p_handler, p_counter, val, val_new );
-    vlc_mutex_unlock( &p_handler->object_lock );
-    vlc_object_release( p_handler );
-
-    return i_ret;
+    return CounterUpdate( p_this, p_counter, val, val_new );
 }
 
 /** Get the aggregated value for a counter
  * \param p_this an object
- * \param i_object_id the object id from which we want the data
- * \param psz_name the name of the couner
+ * \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, int i_object_id,
-                 unsigned int i_counter, vlc_value_t *val )
+int __stats_Get( vlc_object_t *p_this, counter_t *p_counter, vlc_value_t *val )
 {
-    counter_t *p_counter;
-    stats_handler_t *p_handler;
-
     if( !p_this->p_libvlc->b_stats ) return VLC_EGENERIC;
 
-    /* Get stats handler singleton */
-    p_handler = stats_HandlerGet( p_this );
-    if( !p_handler ) return VLC_ENOMEM;
-    vlc_mutex_lock( &p_handler->object_lock );
-
-    /* Look for existing element */
-    p_counter = GetCounter( p_handler, i_object_id, i_counter );
-    if( !p_counter )
-    {
-        vlc_mutex_unlock( &p_handler->object_lock );
-        vlc_object_release( p_handler );
-        val->i_int = val->f_float = 0.0;
-        return VLC_ENOOBJ;
-    }
-
     if( p_counter->i_samples == 0 )
     {
-        vlc_mutex_unlock( &p_handler->object_lock );
-        vlc_object_release( p_handler );
         val->i_int = val->f_float = 0.0;
         return VLC_EGENERIC;
     }
@@ -203,8 +114,6 @@ int __stats_Get( vlc_object_t *p_this, int i_object_id,
         /* Not ready yet */
         if( p_counter->i_samples < 2 )
         {
-            vlc_mutex_unlock( &p_handler->object_lock );
-            vlc_object_release( p_handler );
             val->i_int = 0; val->f_float = 0.0;
             return VLC_EGENERIC;
         }
@@ -226,107 +135,59 @@ int __stats_Get( vlc_object_t *p_this, int i_object_id,
         }
         break;
     }
-    vlc_object_release( p_handler );
-
-    vlc_mutex_unlock( &p_handler->object_lock );
     return VLC_SUCCESS;;
 }
 
-/** Get a statistics counter structure. This allows for low-level modifications
- * \param p_this a parent object
- * \param i_object_id the object from which to retrieve data
- * \param psz_name the name
- * \return the counter, or NULL if not found (or handler not created yet)
- */
-counter_t *__stats_CounterGet( vlc_object_t *p_this, int i_object_id,
-                               unsigned int i_counter )
-{
-    counter_t *p_counter;
-    stats_handler_t *p_handler;
-
-    if( !p_this->p_libvlc->b_stats ) return NULL;
-
-    p_handler = stats_HandlerGet( p_this );
-    if( !p_handler ) return NULL;
-
-    vlc_mutex_lock( &p_handler->object_lock );
-
-    /* Look for existing element */
-    p_counter = GetCounter( p_handler, i_object_id, i_counter );
-    vlc_mutex_unlock( &p_handler->object_lock );
-    vlc_object_release( p_handler );
-
-    return p_counter;
-}
-
-
 void stats_ComputeInputStats( input_thread_t *p_input, input_stats_t *p_stats )
 {
-    vlc_object_t *p_obj;
-    vlc_list_t *p_list;
-    int i_index;
-
     if( !p_input->p_libvlc->b_stats ) return;
 
     vlc_mutex_lock( &p_stats->lock );
 
     /* Input */
-    stats_GetInteger( p_input, p_input->i_object_id, STATS_READ_PACKETS,
-                       &p_stats->i_read_packets );
-    stats_GetInteger( p_input, p_input->i_object_id, STATS_READ_BYTES,
-                       &p_stats->i_read_bytes );
-    stats_GetFloat( p_input, p_input->i_object_id, STATS_INPUT_BITRATE,
-                       &p_stats->f_input_bitrate );
-
-    stats_GetInteger( p_input, p_input->i_object_id, STATS_DEMUX_READ,
+    stats_GetInteger( p_input, p_input->counters.p_read_packets,
+                      &p_stats->i_read_packets );
+    stats_GetInteger( p_input, p_input->counters.p_read_bytes, 
+                      &p_stats->i_read_bytes );
+    stats_GetFloat( p_input, p_input->counters.p_input_bitrate,
+                    &p_stats->f_input_bitrate );
+    stats_GetInteger( p_input, p_input->counters.p_demux_read,
                       &p_stats->i_demux_read_bytes );
-    stats_GetFloat( p_input, p_input->i_object_id, STATS_DEMUX_BITRATE,
-                      &p_stats->f_demux_bitrate );
+    stats_GetFloat( p_input, p_input->counters.p_demux_bitrate,
+                    &p_stats->f_demux_bitrate );
 
-    stats_GetInteger( p_input, p_input->i_object_id, STATS_DECODED_VIDEO,
+    /* Decoders */
+    stats_GetInteger( p_input, p_input->counters.p_decoded_video,
                       &p_stats->i_decoded_video );
-    stats_GetInteger( p_input, p_input->i_object_id, STATS_DECODED_AUDIO,
+    stats_GetInteger( p_input, p_input->counters.p_decoded_audio,
                       &p_stats->i_decoded_audio );
 
     /* Sout */
-    stats_GetInteger( p_input, p_input->i_object_id, STATS_SOUT_SENT_PACKETS,
-                      &p_stats->i_sent_packets );
-    stats_GetInteger( p_input, p_input->i_object_id, STATS_SOUT_SENT_BYTES,
-                      &p_stats->i_sent_bytes );
-    stats_GetFloat  ( p_input, p_input->i_object_id, STATS_SOUT_SEND_BITRATE,
-                      &p_stats->f_send_bitrate );
-
-    /* Aout - We store in p_input because aout is shared */
-    stats_GetInteger( p_input, p_input->i_object_id, STATS_PLAYED_ABUFFERS,
+    if( p_input->counters.p_sout_send_bitrate )
+    {
+        stats_GetInteger( p_input, p_input->counters.p_sout_sent_packets,
+                          &p_stats->i_sent_packets );
+        stats_GetInteger( p_input, p_input->counters.p_sout_sent_bytes,
+                          &p_stats->i_sent_bytes );
+        stats_GetFloat  ( p_input, p_input->counters.p_sout_send_bitrate,
+                          &p_stats->f_send_bitrate );
+    }
+
+    /* Aout */
+    stats_GetInteger( p_input, p_input->counters.p_played_abuffers,
                       &p_stats->i_played_abuffers );
-    stats_GetInteger( p_input, p_input->i_object_id, STATS_LOST_ABUFFERS,
+    stats_GetInteger( p_input, p_input->counters.p_lost_abuffers,
                       &p_stats->i_lost_abuffers );
 
-    /* Vouts - FIXME: Store all in input */
-    p_list = vlc_list_find( p_input, VLC_OBJECT_VOUT, FIND_CHILD );
-    if( p_list )
-    {
-        p_stats->i_displayed_pictures  = 0 ;
-        p_stats->i_lost_pictures = 0;
-        for( i_index = 0; i_index < p_list->i_count ; i_index ++ )
-        {
-            int i_displayed = 0, i_lost = 0;
-            p_obj = (vlc_object_t *)p_list->p_values[i_index].p_object;
-            stats_GetInteger( p_obj, p_obj->i_object_id,
-                              STATS_DISPLAYED_PICTURES,
-                              &i_displayed );
-            stats_GetInteger( p_obj, p_obj->i_object_id, STATS_LOST_PICTURES,
-                              &i_lost );
-            p_stats->i_displayed_pictures += i_displayed;
-            p_stats->i_lost_pictures += i_lost;
-         }
-        vlc_list_release( p_list );
-    }
+    /* Vouts */
+    stats_GetInteger( p_input, p_input->counters.p_displayed_pictures,
+                      &p_stats->i_displayed_pictures );
+    stats_GetInteger( p_input, p_input->counters.p_lost_pictures,
+                      &p_stats->i_lost_pictures );
 
     vlc_mutex_unlock( &p_stats->lock );
 }
 
-
 void stats_ReinitInputStats( input_stats_t *p_stats )
 {
     p_stats->i_read_packets = p_stats->i_read_bytes =
@@ -374,13 +235,14 @@ void __stats_ComputeGlobalStats( vlc_object_t *p_obj, global_stats_t *p_stats )
         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 );
+            input_thread_t *p_input = (input_thread_t *)
+                             p_list->p_values[i_index].p_object;
+            stats_GetFloat( p_obj, p_input->counters.p_input_bitrate, &f_in );
+            if( p_input->counters.p_sout_send_bitrate )
+                stats_GetFloat( p_obj, p_input->counters.p_sout_send_bitrate,
+                                    &f_out );
+            stats_GetFloat( p_obj, p_input->counters.p_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;
@@ -401,18 +263,30 @@ void stats_ReinitGlobalStats( global_stats_t *p_stats )
 void __stats_TimerStart( vlc_object_t *p_obj, const char *psz_name,
                          unsigned int i_id )
 {
-    counter_t *p_counter;
-
+    int i;
+    counter_t *p_counter = NULL;
     if( !p_obj->p_libvlc->b_stats ) return;
+    vlc_mutex_lock( &p_obj->p_libvlc->timer_lock );
 
-    p_counter = stats_CounterGet( p_obj, p_obj->p_vlc->i_object_id, i_id );
+    for( i = 0 ; i < p_obj->p_libvlc->i_timers; i++ )
+    {
+        if( p_obj->p_libvlc->pp_timers[i]->i_id == i_id )
+        {
+            p_counter = p_obj->p_libvlc->pp_timers[i];
+            break;
+        }
+    }
     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 );
+        p_counter = stats_CounterCreate( p_obj->p_libvlc, VLC_VAR_TIME,
+                                         STATS_TIMER );
         if( !p_counter ) return;
+        p_counter->psz_name = strdup( psz_name );
+        p_counter->i_id = i_id;
+        INSERT_ELEM( p_obj->p_libvlc->pp_timers, p_obj->p_libvlc->i_timers,
+                     p_obj->p_libvlc->i_timers, p_counter );
+
         /* 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,
@@ -431,54 +305,89 @@ void __stats_TimerStart( vlc_object_t *p_obj, const char *psz_name,
     }
     p_counter->pp_samples[0]->value.b_bool = VLC_TRUE;
     p_counter->pp_samples[0]->date = mdate();
+    vlc_mutex_unlock( &p_obj->p_libvlc->timer_lock );
 }
 
 void __stats_TimerStop( vlc_object_t *p_obj, unsigned int i_id )
 {
-    counter_t *p_counter;
-
+    counter_t *p_counter = NULL;
+    int i;
     if( !p_obj->p_libvlc->b_stats ) return;
-
-    p_counter = stats_CounterGet( p_obj, p_obj->p_vlc->i_object_id, i_id );
+    vlc_mutex_lock( &p_obj->p_libvlc->timer_lock );
+    for( i = 0 ; i < p_obj->p_libvlc->i_timers; i++ )
+    {
+        if( p_obj->p_libvlc->pp_timers[i]->i_id == i_id )
+        {
+            p_counter = p_obj->p_libvlc->pp_timers[i];
+            break;
+        }
+    }
     if( !p_counter || p_counter->i_samples != 2 )
     {
-        msg_Err( p_obj, "Timer does not exist" );
+        msg_Err( p_obj, "timer does not exist" );
+        vlc_mutex_unlock( &p_obj->p_libvlc->timer_lock );
         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;
+    vlc_mutex_unlock( &p_obj->p_libvlc->timer_lock );
 }
 
 void __stats_TimerDump( vlc_object_t *p_obj, unsigned int i_id )
 {
-    counter_t *p_counter;
-
+    counter_t *p_counter = NULL;
+    int i;
     if( !p_obj->p_libvlc->b_stats ) return;
-
-    p_counter = stats_CounterGet( p_obj, p_obj->p_vlc->i_object_id, i_id );
+    vlc_mutex_lock( &p_obj->p_libvlc->timer_lock );
+    for( i = 0 ; i < p_obj->p_libvlc->i_timers; i++ )
+    {
+        if( p_obj->p_libvlc->pp_timers[i]->i_id == i_id )
+        {
+            p_counter = p_obj->p_libvlc->pp_timers[i];
+            break;
+        }
+    }
     TimerDump( p_obj, p_counter, VLC_TRUE );
+    vlc_mutex_unlock( &p_obj->p_libvlc->timer_lock );
 }
 
 
 void __stats_TimersDumpAll( vlc_object_t *p_obj )
 {
     int i;
-    stats_handler_t *p_handler = stats_HandlerGet( p_obj );
-    if( !p_handler ) return;
+    if( !p_obj->p_libvlc->b_stats ) return;
+    vlc_mutex_lock( &p_obj->p_libvlc->timer_lock );
+    for ( i = 0 ; i< p_obj->p_libvlc->i_timers ; i++ )
+        TimerDump( p_obj, p_obj->p_libvlc->pp_timers[i], VLC_FALSE );
+    vlc_mutex_unlock( &p_obj->p_libvlc->timer_lock );
+}
 
-    vlc_mutex_lock( &p_handler->object_lock );
-    for ( i = 0 ; i< p_handler->i_counters; i++ )
+void __stats_TimersClean( vlc_object_t *p_obj )
+{
+    int i;
+    vlc_mutex_lock( &p_obj->p_libvlc->timer_lock );
+    for ( i = p_obj->p_libvlc->i_timers -1 ; i >= 0; 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 );
-        }
+        counter_t *p_counter = p_obj->p_libvlc->pp_timers[i];
+        REMOVE_ELEM( p_obj->p_libvlc->pp_timers, p_obj->p_libvlc->i_timers, i );
+        stats_CounterClean( p_counter );
     }
-    vlc_mutex_unlock( &p_handler->object_lock );
-    vlc_object_release( p_handler );
+    vlc_mutex_unlock( &p_obj->p_libvlc->timer_lock );
+}
+
+void stats_CounterClean( counter_t *p_c )
+{
+    int i;
+    for( i = p_c->i_samples - 1 ; i >= 0 ; i-- )
+    {
+        counter_sample_t *p_s = p_c->pp_samples[i];
+        REMOVE_ELEM( p_c->pp_samples, p_c->i_samples, i );
+        free( p_s );
+    }
+    if( p_c->psz_name ) free( p_c->psz_name );
+    free( p_c );
 }
 
 
@@ -490,14 +399,13 @@ void __stats_TimersDumpAll( vlc_object_t *p_obj )
  * 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 )
+static int CounterUpdate( vlc_object_t *p_handler,
+                          counter_t *p_counter,
+                          vlc_value_t val, vlc_value_t *new_val )
 {
     switch( p_counter->i_compute_type )
     {
@@ -621,66 +529,6 @@ static int stats_CounterUpdate( stats_handler_t *p_handler,
     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 )
 {
@@ -688,7 +536,7 @@ static void TimerDump( vlc_object_t *p_obj, counter_t *p_counter,
     int i_total;
     if( !p_counter || p_counter->i_samples != 2 )
     {
-        msg_Err( p_obj, "Timer %s does not exist", p_counter->psz_name );
+        msg_Err( p_obj, "timer %s does not exist", p_counter->psz_name );
         return;
     }
     i_total = p_counter->pp_samples[1]->value.i_int;
index 7a29212..1a5d743 100644 (file)
@@ -1942,10 +1942,10 @@ static void httpd_HostThread( httpd_host_t *host )
 {
     tls_session_t *p_tls = NULL;
 
-    stats_Create( host, "client_connections", STATS_CLIENT_CONNECTIONS,
-                  VLC_VAR_INTEGER, STATS_COUNTER );
-    stats_Create( host, "active_connections", STATS_ACTIVE_CONNECTIONS,
-                  VLC_VAR_INTEGER, STATS_COUNTER );
+    host->p_total_counter = stats_CounterCreate( host,
+                                          VLC_VAR_INTEGER, STATS_COUNTER );
+    host->p_active_counter = stats_CounterCreate( host,
+                                          VLC_VAR_INTEGER, STATS_COUNTER );
 
     while( !host->b_die )
     {
@@ -1995,7 +1995,7 @@ static void httpd_HostThread( httpd_host_t *host )
                     cl->i_activity_date+cl->i_activity_timeout < mdate()) ) ) )
             {
                 httpd_ClientClean( cl );
-                stats_UpdateInteger( host, STATS_ACTIVE_CONNECTIONS, -1, NULL );
+                stats_UpdateInteger( host, host->p_active_counter, -1, NULL );
                 TAB_REMOVE( host->i_client, host->client, cl );
                 free( cl );
                 i_client--;
@@ -2490,10 +2490,10 @@ static void httpd_HostThread( httpd_host_t *host )
                     {
                         httpd_client_t *cl;
                         char ip[NI_MAXNUMERICHOST];
-                        stats_UpdateInteger( host, STATS_CLIENT_CONNECTIONS,
+                        stats_UpdateInteger( host, host->p_total_counter,
+                                             1, NULL );
+                        stats_UpdateInteger( host, host->p_active_counter,
                                              1, NULL );
-                        stats_UpdateInteger( host, STATS_ACTIVE_CONNECTIONS, 1,
-                                             NULL );
                         cl = httpd_ClientNew( fd, &sock, i_sock_size, p_tls );
                         httpd_ClientIP( cl, ip );
                         msg_Dbg( host, "Connection from %s", ip );
index 241d3a0..81802f3 100644 (file)
@@ -80,7 +80,6 @@ int playlist_Control( playlist_t * p_playlist, int i_query, ... )
 
 int PlaylistVAControl( playlist_t * p_playlist, int i_query, va_list args )
 {
-    int i_view;
     playlist_item_t *p_item, *p_node;
     vlc_value_t val;
 
index a7ca7e4..049bf17 100644 (file)
@@ -188,7 +188,7 @@ static void EndPlaylist( playlist_t *p_playlist )
  *****************************************************************************/
 static void RunPreparse ( playlist_preparse_t *p_obj )
 {
-    playlist_t *p_playlist = p_obj->p_parent;
+    playlist_t *p_playlist = (playlist_t *)p_obj->p_parent;
     /* Tell above that we're ready */
     vlc_thread_ready( p_obj );
 
index e0072f9..496f74d 100644 (file)
@@ -72,7 +72,6 @@ sout_instance_t *__sout_NewInstance( vlc_object_t *p_parent, char * psz_dest )
 {
     sout_instance_t *p_sout;
     vlc_value_t keep;
-    counter_t *p_counter;
 
     if( var_Get( p_parent, "sout-keep", &keep ) < 0 )
     {
@@ -142,17 +141,6 @@ sout_instance_t *__sout_NewInstance( vlc_object_t *p_parent, char * psz_dest )
     /* attach it for inherit */
     vlc_object_attach( p_sout, p_parent );
 
-    /* Create statistics */
-    stats_Create( p_parent, "sout_sent_packets", STATS_SOUT_SENT_PACKETS,
-                  VLC_VAR_INTEGER, STATS_COUNTER );
-    stats_Create( p_parent, "sout_sent_bytes", STATS_SOUT_SENT_BYTES,
-                  VLC_VAR_INTEGER, STATS_COUNTER );
-    stats_Create( p_parent, "sout_send_bitrate", STATS_SOUT_SEND_BITRATE,
-                  VLC_VAR_FLOAT, STATS_DERIVATIVE );
-    p_counter = stats_CounterGet( p_parent, p_parent->i_object_id,
-                                  STATS_SOUT_SEND_BITRATE );
-    if( p_counter) p_counter->update_interval = 1000000;
-
     p_sout->p_stream = sout_StreamNew( p_sout, p_sout->psz_chain );
 
     if( p_sout->p_stream == NULL )
@@ -383,11 +371,12 @@ int sout_AccessOutWrite( sout_access_out_t *p_access, block_t *p_buffer )
                                                FIND_PARENT );
         if( p_input )
         {
-            stats_UpdateInteger( p_input, STATS_SOUT_SENT_PACKETS, 30, NULL );
-            stats_UpdateInteger( p_input, STATS_SOUT_SENT_BYTES,
+            stats_UpdateInteger( p_input, p_input->counters.p_sout_sent_packets,
+                                30, NULL );
+            stats_UpdateInteger( p_input, p_input->counters.p_sout_sent_bytes,
                                  p_access->i_sent_bytes, &i_total );
-            stats_UpdateFloat( p_input, STATS_SOUT_SEND_BITRATE, (float)i_total,
-                               NULL );
+            stats_UpdateFloat( p_input, p_input->counters.p_sout_send_bitrate,
+                                (float)i_total, NULL );
             p_access->i_sent_bytes = 0;
             vlc_object_release( p_input );
         }
index e1a9c4d..c49e66b 100644 (file)
@@ -229,11 +229,6 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt )
         return NULL;
     }
 
-    stats_Create( p_vout, "displayed_pictures",STATS_DISPLAYED_PICTURES,
-                  VLC_VAR_INTEGER, STATS_COUNTER );
-    stats_Create( p_vout, "lost_pictures", STATS_LOST_PICTURES,
-                  VLC_VAR_INTEGER, STATS_COUNTER );
-
     /* Initialize pictures - translation tables and functions
      * will be initialized later in InitThread */
     for( i_index = 0; i_index < 2 * VOUT_MAX_PICTURES + 1; i_index++)
@@ -701,6 +696,8 @@ static void RunThread( vout_thread_t *p_vout)
 
     subpicture_t *  p_subpic = NULL;                   /* subpicture pointer */
 
+    input_thread_t *p_input = NULL ; /* Parent input, if it exists */
+
     vlc_value_t     val;
     vlc_bool_t      b_drop_late;
 
@@ -723,6 +720,8 @@ static void RunThread( vout_thread_t *p_vout)
         return;
     }
 
+    p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT, FIND_PARENT );
+
     /*
      * Main loop - it is not executed if an error occurred during
      * initialization
@@ -820,7 +819,10 @@ static void RunThread( vout_thread_t *p_vout)
                 }
                 msg_Warn( p_vout, "late picture skipped ("I64Fd")",
                                   current_date - display_date );
-                stats_UpdateInteger( p_vout, STATS_LOST_PICTURES, 1 , NULL);
+                vlc_mutex_lock( &p_input->counters.counters_lock );
+                stats_UpdateInteger( p_vout, p_input->counters.p_lost_pictures,
+                                     1 , NULL);
+                vlc_mutex_unlock( &p_input->counters.counters_lock );
                 vlc_mutex_unlock( &p_vout->picture_lock );
 
                 continue;
@@ -843,7 +845,10 @@ static void RunThread( vout_thread_t *p_vout)
                     p_picture->i_status = DESTROYED_PICTURE;
                     p_vout->i_heap_size--;
                 }
-                stats_UpdateInteger( p_vout, STATS_LOST_PICTURES, 1, NULL );
+                vlc_mutex_lock( &p_input->counters.counters_lock );
+                stats_UpdateInteger( p_vout, p_input->counters.p_lost_pictures,
+                                     1 , NULL);
+                vlc_mutex_unlock( &p_input->counters.counters_lock );
                 msg_Warn( p_vout, "vout warning: early picture skipped "
                           "("I64Fd")", display_date - current_date
                           - p_vout->i_pts_delay );
@@ -901,7 +906,10 @@ static void RunThread( vout_thread_t *p_vout)
         /*
          * Perform rendering
          */
-        stats_UpdateInteger( p_vout, STATS_DISPLAYED_PICTURES, 1, NULL );
+        vlc_mutex_lock( &p_input->counters.counters_lock );
+        stats_UpdateInteger( p_vout, p_input->counters.p_displayed_pictures,
+                                 1 , NULL);
+        vlc_mutex_unlock( &p_input->counters.counters_lock );
         p_directbuffer = vout_RenderPicture( p_vout, p_picture, p_subpic );
 
         /*