Browse Source

vout: count the number of late frames

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).
pull/112/head
Steve Lhomme 6 years ago
parent
commit
b0f4b95366
  1. 1
      include/vlc_input_item.h
  2. 5
      src/input/decoder.c
  3. 2
      src/input/decoder.h
  4. 4
      src/input/es_out.c
  5. 1
      src/input/input_internal.h
  6. 3
      src/input/stats.c
  7. 11
      src/video_output/statistic.h
  8. 5
      src/video_output/video_output.c
  9. 2
      src/video_output/vout_internal.h

1
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 */

5
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 )

2
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);

4
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

1
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;
};

3
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);
}

11
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

5
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);

2
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

Loading…
Cancel
Save