diff options
author | Dudemanguy <random342@airmail.cc> | 2023-11-07 17:07:14 -0600 |
---|---|---|
committer | Dudemanguy <random342@airmail.cc> | 2023-11-11 20:44:01 +0000 |
commit | 9199afc405d4f53315407133c3d727b025a663e0 (patch) | |
tree | a42b5fee298aea4b9c5fa2d424b89692b921e67a | |
parent | 7302f871d121610ccf81f0ee3fb1f3ad62524d6f (diff) | |
download | mpv-9199afc405d4f53315407133c3d727b025a663e0.tar.bz2 mpv-9199afc405d4f53315407133c3d727b025a663e0.tar.xz |
vo_gpu_next: add some additional sanity checking for interpolation
Several related things in regards to interpolation. Essentially this
adds more general sanity checking to bring it more in line with what
vo_gpu does.
- Add a can_interpolate bool which determines whether or not this frame
is allowed to interpolate.
- p->is_interpolated was sometimes lying and because you can have a mix
frames greater than 1 depending on the video and settings. Make sure
that vsync_offset is not 0 so we know if it's actually interpolated or
not. This prevents a redundant redraw for those edge cases when
pausing.
- When the vo wants a reset, i.e. some sort of discontinuity, don't try
to interpolate the frame. Interpolation is only valid for
monotonically increasing times.
This fixes #11519 because of the additional check to make sure that we
have more than 1 frame. The PTS clamping part is still not great. That
is for the next commit.
-rw-r--r-- | video/out/vo_gpu_next.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c index dd70b0aaa2..76647ca499 100644 --- a/video/out/vo_gpu_next.c +++ b/video/out/vo_gpu_next.c @@ -871,8 +871,10 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) update_options(vo); struct pl_render_params params = pars->params; + const struct gl_video_opts *opts = p->opts_cache->opts; bool will_redraw = frame->display_synced && frame->num_vsyncs > 1; bool cache_frame = will_redraw || frame->still; + bool can_interpolate = opts->interpolation && frame->num_frames > 1; params.info_callback = info_callback; params.info_priv = vo; params.skip_caching_single_frame = !cache_frame; @@ -887,6 +889,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) continue; // ignore already seen frames if (p->want_reset) { + can_interpolate = false; pl_renderer_flush_cache(p->rr); pl_queue_reset(p->queue); p->last_pts = 0.0; @@ -910,7 +913,6 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) p->last_id = id; } - const struct gl_video_opts *opts = p->opts_cache->opts; if (p->target_hint && frame->current) { struct pl_color_space hint = get_mpi_csp(vo, frame->current); if (opts->target_prim) @@ -927,7 +929,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) struct pl_swapchain_frame swframe; struct ra_swapchain *sw = p->ra_ctx->swapchain; - double vsync_offset = opts->interpolation ? frame->vsync_offset : 0; + double vsync_offset = can_interpolate ? frame->vsync_offset : 0; bool should_draw = sw->fns->start_frame(sw, NULL); // for wayland logic if (!should_draw || !pl_swapchain_start_frame(p->sw, &swframe)) { if (frame->current) { @@ -1040,7 +1042,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) pl_renderer_get_hdr_metadata(p->rr, &vo->params->color.hdr); } - p->is_interpolated = mix.num_frames > 1; + p->is_interpolated = vsync_offset != 0 && mix.num_frames > 1; valid = true; // fall through |