diff options
author | wm4 <wm4@nowhere> | 2018-08-31 16:33:15 +0200 |
---|---|---|
committer | Anton Kindestam <antonki@kth.se> | 2018-12-06 10:30:14 +0100 |
commit | 83884fdf03fc991679bea53d3d5bddf97ed16a9b (patch) | |
tree | 84248a21d9a50185dcc51bfb79077f84bdd0e96c /video/out/vo.c | |
parent | 8b83c8996686072bc743b112ae5cb3bf93aa33ed (diff) | |
download | mpv-83884fdf03fc991679bea53d3d5bddf97ed16a9b.tar.bz2 mpv-83884fdf03fc991679bea53d3d5bddf97ed16a9b.tar.xz |
vo_gpu: glx: use GLX_OML_sync_control for better vsync reporting
Use the extension to compute the (hopefully correct) video delay and
vsync phase.
This is very fuzzy, because the latency will suddenly be applied after
some frames have already been shown. This means there _will_ be "jumps"
in the time accounting, which can lead to strange effects at start of
playback (such as making initial "dropped" etc. frames worse). The only
reasonable way to fix this would be running a few dummy frame swaps at
start of playback until the latency is known. The same happens when
unpausing.
This only affects display-sync mode.
Correct function was not confirmed. It only "looks right". I don't have
the equipment to make scientifically correct measurements.
A potentially bad thing is that we trust the timestamps we're receiving.
Out of bounds timestamps could wreak havoc. On the other hand, this will
probably cause the higher level code to panic and just disable DS.
As a further caveat, this makes a bunch of assumptions about UST
timestamps. If there are delayed frames (i.e. we skipped one or more
vsyncs), the latency logic is mostly reset. There is no attempt to make
the vo.c skipped vsync logic to use this. Also, the latency computation
determines a vsync duration, and there's no effort to reconcile or share
the vo.c logic for determining vsync duration.
Diffstat (limited to 'video/out/vo.c')
-rw-r--r-- | video/out/vo.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/video/out/vo.c b/video/out/vo.c index a33d9fd15f..466759f595 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -141,6 +141,7 @@ struct vo_internal { double estimated_vsync_jitter; bool expecting_vsync; int64_t num_successive_vsyncs; + double last_vo_latency; int64_t flip_queue_offset; // queue flip events at most this much in advance int64_t timing_offset; // same (but from options; not VO configured) @@ -481,6 +482,10 @@ static void update_vsync_timing_after_swap(struct vo *vo) int64_t now = mp_time_us(); int64_t prev_vsync = in->prev_vsync; + // If we can, use a "made up" expected display time. + if (in->last_vo_latency >= 0) + now += in->last_vo_latency * (1000.0 * 1000.0); + in->prev_vsync = now; if (!in->expecting_vsync) { @@ -910,11 +915,15 @@ bool vo_render_frame_external(struct vo *vo) vo->driver->flip_page(vo); + double latency = + vo->driver->get_latency ? vo->driver->get_latency(vo) : -1; + MP_STATS(vo, "end video-flip"); pthread_mutex_lock(&in->lock); in->dropped_frame = prev_drop_count < vo->in->drop_count; in->rendering = false; + in->last_vo_latency = latency; update_vsync_timing_after_swap(vo); } |