diff options
author | Kacper Michajłow <kasper93@gmail.com> | 2023-11-10 18:19:04 +0100 |
---|---|---|
committer | Dudemanguy <random342@airmail.cc> | 2023-11-11 20:44:01 +0000 |
commit | 7cab30cec77b3fe4b8ca85b37664a3dc9b270aee (patch) | |
tree | eb98284e2825bbe1e6a8bd263c96284ef21f9384 | |
parent | 5e5a32534ad9aa340f7cf76b2d54461e8f7d1098 (diff) | |
download | mpv-7cab30cec77b3fe4b8ca85b37664a3dc9b270aee.tar.bz2 mpv-7cab30cec77b3fe4b8ca85b37664a3dc9b270aee.tar.xz |
vo_gpu_next: fix interpolation
Fixes gpu-next completely ignoring any speed adjustment, either DS or
playback.
Frames in pl_queue have raw PTS values, so when querying them we have to
use the same time base. There was misunderstanding between mpv and
libplacebo, where the former was querying the frames based on display
vblank timeline, but this cannot work if the playback speed is adjusted
and display timeline is not aligned with video timelien. In which case
we have to schedule "video vsync" points that we want to display.
Previous code was working only when playback speed was 1.0x, but since
DS almost always changes the speed the interpolation was mostly not
timied correctly.
-rw-r--r-- | video/out/vo_gpu_next.c | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c index 6878dc1615..eba1214d63 100644 --- a/video/out/vo_gpu_next.c +++ b/video/out/vo_gpu_next.c @@ -903,7 +903,6 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) pl_queue_push(p->queue, &(struct pl_source_frame) { .pts = mpi->pts, - .duration = frame->ideal_frame_duration, .frame_data = mpi, .map = map_frame, .unmap = unmap_frame, @@ -929,13 +928,13 @@ 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 = can_interpolate ? frame->vsync_offset : 0; + double pts_offset = can_interpolate ? frame->ideal_frame_vsync : 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) { // Advance the queue state to the current PTS to discard unused frames pl_queue_update(p->queue, NULL, pl_queue_params( - .pts = frame->current->pts + vsync_offset, + .pts = frame->current->pts + pts_offset, .radius = pl_frame_mix_radius(¶ms), )); } @@ -959,9 +958,9 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) if (frame->current) { // Update queue state struct pl_queue_params qparams = *pl_queue_params( - .pts = frame->current->pts + vsync_offset, + .pts = frame->current->pts + pts_offset, .radius = pl_frame_mix_radius(¶ms), - .vsync_duration = frame->vsync_interval, + .vsync_duration = frame->ideal_frame_vsync_duration, .interpolation_threshold = opts->interpolation_threshold, ); @@ -1047,7 +1046,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 = vsync_offset != 0 && mix.num_frames > 1; + p->is_interpolated = pts_offset != 0 && mix.num_frames > 1; valid = true; // fall through |