diff options
author | wm4 <wm4@nowhere> | 2015-11-27 14:35:08 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-11-27 14:35:08 +0100 |
commit | 85498a0797c36afc383aa1bf911bc760428616b2 (patch) | |
tree | 818d2e8d87fd43b2d0d7b1785e90e7fb81aa25e8 | |
parent | b250c19a38a97107a7e9ee53370eb2c5d033866d (diff) | |
download | mpv-85498a0797c36afc383aa1bf911bc760428616b2.tar.bz2 mpv-85498a0797c36afc383aa1bf911bc760428616b2.tar.xz |
vo: improve vsync delay detection
Actually I'm not content with the detection added in commit 44376d2d. It
triggers too often if vsync is very jittery. It's easy to avoid this: we
add more samples to the detection by reusing the drift computation loop.
If there's a significant step in the drift, we consider it a drop.
-rw-r--r-- | video/out/vo.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/video/out/vo.c b/video/out/vo.c index be0e2c6933..350e5d2583 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -368,7 +368,19 @@ static void update_vsync_timing_after_swap(struct vo *vo) MP_STATS(vo, "value %f jitter", in->estimated_vsync_jitter); MP_STATS(vo, "value %f vsync-diff", in->vsync_samples[0] / 1e6); - if (llabs(in->base_vsync - now) > in->vsync_interval * 2 / 3) { + int window = 4; + int64_t t_r = now, t_e = in->base_vsync, diff = 0, desync_early = 0; + for (int n = 0; n < in->drop_point; n++) { + diff += t_r - t_e; + t_r -= in->vsync_samples[n]; + t_e -= in->vsync_interval; + if (n == window + 1) + desync_early = diff / window; + } + int64_t desync = diff / in->num_vsync_samples; + if (in->drop_point > window * 2 && + labs(desync - desync_early) >= in->vsync_interval * 3 / 4) + { // Assume a drop. An underflow can technically speaking not be a drop // (it's up to the driver what this is supposed to mean), but no reason // to treat it differently. @@ -376,17 +388,11 @@ static void update_vsync_timing_after_swap(struct vo *vo) in->delayed_count += 1; in->drop_point = 0; MP_STATS(vo, "vo-delayed"); + desync = 0; } - // Smooth out drift. - int64_t t_r = now, t_e = in->base_vsync, diff = 0; - for (int n = 0; n < in->drop_point - 1; n++) { - diff += t_r - t_e; - t_r -= in->vsync_samples[n]; - t_e -= in->vsync_interval; - } if (in->drop_point > 10) - in->base_vsync += diff * 0.1 / in->num_vsync_samples; + in->base_vsync += desync / 10; } // to be called from VO thread only |