summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKacper Michajłow <kasper93@gmail.com>2023-11-10 18:19:04 +0100
committerDudemanguy <random342@airmail.cc>2023-11-11 20:44:01 +0000
commit7cab30cec77b3fe4b8ca85b37664a3dc9b270aee (patch)
treeeb98284e2825bbe1e6a8bd263c96284ef21f9384
parent5e5a32534ad9aa340f7cf76b2d54461e8f7d1098 (diff)
downloadmpv-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.c11
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(&params),
));
}
@@ -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(&params),
- .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