summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-11-27 14:35:08 +0100
committerwm4 <wm4@nowhere>2015-11-27 14:35:08 +0100
commit85498a0797c36afc383aa1bf911bc760428616b2 (patch)
tree818d2e8d87fd43b2d0d7b1785e90e7fb81aa25e8
parentb250c19a38a97107a7e9ee53370eb2c5d033866d (diff)
downloadmpv-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.c24
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