summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-04-06 22:56:06 +0200
committerwm4 <wm4@nowhere>2016-04-06 22:56:12 +0200
commit32a92071b4cc58967d51a5e3ce1c3bed219d9111 (patch)
tree32045d5fff6090aa5b0151d0c2fa053e6e16b22e /video
parenta606b92f4a6fab12e94ad687f65d4d65f52b6d59 (diff)
downloadmpv-32a92071b4cc58967d51a5e3ce1c3bed219d9111.tar.bz2
mpv-32a92071b4cc58967d51a5e3ce1c3bed219d9111.tar.xz
vo: don't reset vsync statistics on seeks etc.
The sync-by-display mode relies on using the vsync statistics for timing. As a consequence discontinuities must be handled somehow. Until now we have done this by completely resetting these statistics. This can be somewhat annoying, especially if the GL driver's vsync timing is not ideal. So after e.g. a seek it could take a second until it locked back to the proper values. Change it not to reset all statistics. Some state obviously has to be reset, because it's a discontinuity. To make it worse, the driver's vsync behavior will also change on such discontinuities. To compensate, we discard the timings for the first 2 vsyncs after each discontinuity (via num_successive_vsyncs). This is probably not fully ideal, and num_total_vsync_samples handling in particular becomes a bit questionable.
Diffstat (limited to 'video')
-rw-r--r--video/out/vo.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/video/out/vo.c b/video/out/vo.c
index 5c56f62690..3e7999a698 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -150,6 +150,7 @@ struct vo_internal {
double estimated_vsync_interval;
double estimated_vsync_jitter;
bool expecting_vsync;
+ int64_t num_successive_vsyncs;
int64_t flip_queue_offset; // queue flip events at most this much in advance
@@ -247,6 +248,7 @@ static struct vo *vo_create(bool probing, struct mpv_global *global,
*vo->in = (struct vo_internal) {
.dispatch = mp_dispatch_create(vo),
.req_frames = 1,
+ .estimated_vsync_jitter = -1,
};
mp_make_wakeup_pipe(vo->in->wakeup_pipe);
mp_dispatch_set_wakeup_fn(vo->in->dispatch, dispatch_wakeup_cb, vo);
@@ -321,13 +323,10 @@ void vo_destroy(struct vo *vo)
static void reset_vsync_timings(struct vo *vo)
{
struct vo_internal *in = vo->in;
- in->num_vsync_samples = 0;
- in->num_total_vsync_samples = 0;
in->drop_point = 0;
- in->estimated_vsync_interval = 0;
- in->estimated_vsync_jitter = -1;
in->base_vsync = 0;
in->expecting_vsync = false;
+ in->num_successive_vsyncs = 0;
}
static double vsync_stddef(struct vo *vo, int64_t ref_vsync)
@@ -419,17 +418,23 @@ static void update_vsync_timing_after_swap(struct vo *vo)
struct vo_internal *in = vo->in;
int64_t now = mp_time_us();
+ int64_t prev_vsync = in->prev_vsync;
+
+ in->prev_vsync = now;
if (!in->expecting_vsync) {
- in->prev_vsync = now; // for normal system-time framedrop
reset_vsync_timings(vo);
return;
}
+ in->num_successive_vsyncs++;
+ if (in->num_successive_vsyncs <= 2)
+ return;
+
if (in->num_vsync_samples >= MAX_VSYNC_SAMPLES)
in->num_vsync_samples -= 1;
MP_TARRAY_INSERT_AT(in, in->vsync_samples, in->num_vsync_samples, 0,
- now - in->prev_vsync);
+ now - prev_vsync);
in->drop_point = MPMIN(in->drop_point + 1, in->num_vsync_samples);
in->num_total_vsync_samples += 1;
if (in->base_vsync) {
@@ -437,7 +442,6 @@ static void update_vsync_timing_after_swap(struct vo *vo)
} else {
in->base_vsync = now;
}
- in->prev_vsync = now;
double avg = 0;
for (int n = 0; n < in->num_vsync_samples; n++)
@@ -788,9 +792,10 @@ static bool render_frame(struct vo *vo)
if (in->current_frame->num_vsyncs > 0)
in->current_frame->num_vsyncs -= 1;
- in->expecting_vsync = in->current_frame->display_synced && !in->paused;
- if (in->expecting_vsync && !in->num_vsync_samples) // first DS frame in a row
+ bool use_vsync = in->current_frame->display_synced && !in->paused;
+ if (use_vsync && !in->expecting_vsync) // first DS frame in a row
in->prev_vsync = now;
+ in->expecting_vsync = use_vsync;
if (in->dropped_frame) {
in->drop_count += 1;