[vlc-devel] [PATCH 1/6] vout: count the number of late frames

Steve Lhomme robux4 at ycbcr.xyz
Mon Aug 10 07:48:47 CEST 2020


We already count the number of displayed frames, the number of dropped frames
(called lost). We should also count the frames that are actually displayed but
not in the desired time. It usually indicates the decoder is too slow or the
rendering to the display is too slow even though it may not be directly
visible (movements not smooth).
---
 include/vlc_input_item.h         |  1 +
 src/input/decoder.c              |  5 +++--
 src/input/decoder.h              |  2 +-
 src/input/es_out.c               |  4 +++-
 src/input/input_internal.h       |  1 +
 src/input/stats.c                |  3 +++
 src/video_output/statistic.h     | 11 ++++++++++-
 src/video_output/video_output.c  |  5 +++--
 src/video_output/vout_internal.h |  2 +-
 9 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/include/vlc_input_item.h b/include/vlc_input_item.h
index 1c99f6c0122..8e5ffc98eca 100644
--- a/include/vlc_input_item.h
+++ b/include/vlc_input_item.h
@@ -520,6 +520,7 @@ struct input_stats_t
 
     /* Vout */
     int64_t i_displayed_pictures;
+    int64_t i_late_pictures;
     int64_t i_lost_pictures;
 
     /* Aout */
diff --git a/src/input/decoder.c b/src/input/decoder.c
index 99c5f12e12f..5aa8ead4baa 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -1080,13 +1080,14 @@ static void ModuleThread_UpdateStatVideo( vlc_input_decoder_t *p_owner,
 {
     unsigned displayed = 0;
     unsigned vout_lost = 0;
+    unsigned vout_late = 0;
     if( p_owner->p_vout != NULL )
     {
-        vout_GetResetStatistic( p_owner->p_vout, &displayed, &vout_lost );
+        vout_GetResetStatistic( p_owner->p_vout, &displayed, &vout_lost, &vout_late );
     }
     if (lost) vout_lost++;
 
-    decoder_Notify(p_owner, on_new_video_stats, 1, vout_lost, displayed);
+    decoder_Notify(p_owner, on_new_video_stats, 1, vout_lost, displayed, vout_late);
 }
 
 static void ModuleThread_QueueVideo( decoder_t *p_dec, picture_t *p_pic )
diff --git a/src/input/decoder.h b/src/input/decoder.h
index b5a05e232e5..f8dede84179 100644
--- a/src/input/decoder.h
+++ b/src/input/decoder.h
@@ -39,7 +39,7 @@ struct vlc_input_decoder_callbacks {
                                void *userdata);
 
     void (*on_new_video_stats)(vlc_input_decoder_t *decoder, unsigned decoded,
-                               unsigned lost, unsigned displayed,
+                               unsigned lost, unsigned displayed, unsigned late,
                                void *userdata);
     void (*on_new_audio_stats)(vlc_input_decoder_t *decoder, unsigned decoded,
                                unsigned lost, unsigned played, void *userdata);
diff --git a/src/input/es_out.c b/src/input/es_out.c
index 2ad863021c6..89d819b4c5b 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -344,7 +344,7 @@ decoder_on_thumbnail_ready(vlc_input_decoder_t *decoder, picture_t *pic, void *u
 
 static void
 decoder_on_new_video_stats(vlc_input_decoder_t *decoder, unsigned decoded, unsigned lost,
-                           unsigned displayed, void *userdata)
+                           unsigned displayed, unsigned late, void *userdata)
 {
     (void) decoder;
 
@@ -365,6 +365,8 @@ decoder_on_new_video_stats(vlc_input_decoder_t *decoder, unsigned decoded, unsig
                               memory_order_relaxed);
     atomic_fetch_add_explicit(&stats->displayed_pictures, displayed,
                               memory_order_relaxed);
+    atomic_fetch_add_explicit(&stats->late_pictures, late,
+                              memory_order_relaxed);
 }
 
 static void
diff --git a/src/input/input_internal.h b/src/input/input_internal.h
index 1391571eeaa..f99e6805eb7 100644
--- a/src/input/input_internal.h
+++ b/src/input/input_internal.h
@@ -729,6 +729,7 @@ struct input_stats {
     atomic_uintmax_t played_abuffers;
     atomic_uintmax_t lost_abuffers;
     atomic_uintmax_t displayed_pictures;
+    atomic_uintmax_t late_pictures;
     atomic_uintmax_t lost_pictures;
 };
 
diff --git a/src/input/stats.c b/src/input/stats.c
index b294a59e98e..bd41a34d755 100644
--- a/src/input/stats.c
+++ b/src/input/stats.c
@@ -66,6 +66,7 @@ struct input_stats *input_stats_Create(void)
     atomic_init(&stats->played_abuffers, 0);
     atomic_init(&stats->lost_abuffers, 0);
     atomic_init(&stats->displayed_pictures, 0);
+    atomic_init(&stats->late_pictures, 0);
     atomic_init(&stats->lost_pictures, 0);
     return stats;
 }
@@ -106,6 +107,8 @@ void input_stats_Compute(struct input_stats *stats, input_stats_t *st)
                                                memory_order_relaxed);
     st->i_displayed_pictures = atomic_load_explicit(&stats->displayed_pictures,
                                                     memory_order_relaxed);
+    st->i_late_pictures = atomic_load_explicit(&stats->late_pictures,
+                                                    memory_order_relaxed);
     st->i_lost_pictures = atomic_load_explicit(&stats->lost_pictures,
                                                memory_order_relaxed);
 }
diff --git a/src/video_output/statistic.h b/src/video_output/statistic.h
index a3fc6ed2c7d..54ee775cf05 100644
--- a/src/video_output/statistic.h
+++ b/src/video_output/statistic.h
@@ -30,12 +30,14 @@
 typedef struct {
     atomic_uint displayed;
     atomic_uint lost;
+    atomic_uint late;
 } vout_statistic_t;
 
 static inline void vout_statistic_Init(vout_statistic_t *stat)
 {
     atomic_init(&stat->displayed, 0);
     atomic_init(&stat->lost, 0);
+    atomic_init(&stat->late, 0);
 }
 
 static inline void vout_statistic_Clean(vout_statistic_t *stat)
@@ -45,11 +47,13 @@ static inline void vout_statistic_Clean(vout_statistic_t *stat)
 
 static inline void vout_statistic_GetReset(vout_statistic_t *stat,
                                            unsigned *restrict displayed,
-                                           unsigned *restrict lost)
+                                           unsigned *restrict lost,
+                                           unsigned *restrict late)
 {
     *displayed = atomic_exchange_explicit(&stat->displayed, 0,
                                           memory_order_relaxed);
     *lost = atomic_exchange_explicit(&stat->lost, 0, memory_order_relaxed);
+    *late = atomic_exchange_explicit(&stat->late, 0, memory_order_relaxed);
 }
 
 static inline void vout_statistic_AddDisplayed(vout_statistic_t *stat,
@@ -64,4 +68,9 @@ static inline void vout_statistic_AddLost(vout_statistic_t *stat, int lost)
     atomic_fetch_add_explicit(&stat->lost, lost, memory_order_relaxed);
 }
 
+static inline void vout_statistic_AddLate(vout_statistic_t *stat, int late)
+{
+    atomic_fetch_add_explicit(&stat->late, late, memory_order_relaxed);
+}
+
 #endif
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index ea24ad6a15a..6cf7a426673 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -347,11 +347,11 @@ static void vout_UpdateWindowSizeLocked(vout_thread_sys_t *vout)
 
 /* */
 void vout_GetResetStatistic(vout_thread_t *vout, unsigned *restrict displayed,
-                            unsigned *restrict lost)
+                            unsigned *restrict lost, unsigned *restrict late)
 {
     vout_thread_sys_t *sys = VOUT_THREAD_TO_SYS(vout);
     assert(!sys->dummy);
-    vout_statistic_GetReset( &sys->statistic, displayed, lost );
+    vout_statistic_GetReset( &sys->statistic, displayed, lost, late );
 }
 
 bool vout_IsEmpty(vout_thread_t *vout)
@@ -1083,6 +1083,7 @@ static int ThreadDisplayPreparePicture(vout_thread_sys_t *vout, bool reuse,
                         continue;
                     } else if (late > 0) {
                         msg_Dbg(&vout->obj, "picture might be displayed late (missing %"PRId64" ms)", MS_FROM_VLC_TICK(late));
+                        vout_statistic_AddLate(&sys->statistic, 1);
                     }
                 }
                 vlc_video_context *pic_vctx = picture_GetVideoContext(decoded);
diff --git a/src/video_output/vout_internal.h b/src/video_output/vout_internal.h
index 9dbed097093..3f5a81c98eb 100644
--- a/src/video_output/vout_internal.h
+++ b/src/video_output/vout_internal.h
@@ -176,7 +176,7 @@ void vout_MouseState(vout_thread_t *, const vlc_mouse_t *);
  * This function will return and reset internal statistics.
  */
 void vout_GetResetStatistic( vout_thread_t *p_vout, unsigned *pi_displayed,
-                             unsigned *pi_lost );
+                             unsigned *pi_lost, unsigned *pi_late );
 
 /**
  * This function will force to display the next picture while paused
-- 
2.26.2



More information about the vlc-devel mailing list