mirror of
https://github.com/mpv-player/mpv
synced 2025-04-01 14:50:07 +00:00
player/video: fix incorrect VO frame duration and frame drops
The logic in question was added in201bef7ee1
for the VDPAU vsync frame timing algorithm, but after the code was moved around for several times, it is now used for all VOs with non-display-sync mode (where the video is synced to audio or system time). It nonetheless likely never did whatever it was intended for. This "correction" reduced the VO frame duration by the amount that the frame is fallen behind the ideal time. Since a frame is presented between pts (the ideal time for which the frame is scheduled) and pts + duration (the end time for which frame drop is determined), and pts is already computed from the current time and the deviation from the ideal time, this "correction" causes the end time to have the deviation added twice, which is nonsense: if the deviation is -0.5x the frame duration, the frame is dropped, even though it should be displayed from now to 0.5x the frame duration from now. It was not noticed at that time probably because the VDPAU secret rabbit code undid some of its damage, and the subsequent development focus on display-sync modes resulted in negligence and simplification of audio mode (e.g.b8bcf0f466
), but the generic VO frame drop algorithm has been observed to cause inconsistent frame drops with this "correction": playing a 59.94 Hz video at 2x speed on a 60 Hz display results in spending over half of the time dropping adjacent frames instead of every other frames, visually causing stuttering, while it should only happen briefly when the pts is very close to vsync time. Fix this by deleting this logic, making the VO frame always having the duration of the video frame. Fixes:201bef7ee1
This commit is contained in:
parent
52bdeb07a1
commit
eaae9e9cf5
@ -1245,10 +1245,7 @@ void write_video(struct MPContext *mpctx)
|
||||
if (opts->untimed || vo->driver->untimed)
|
||||
diff = -1; // disable frame dropping and aspects of frame timing
|
||||
if (diff >= 0) {
|
||||
// expected A/V sync correction is ignored
|
||||
diff /= mpctx->video_speed;
|
||||
if (mpctx->time_frame < 0)
|
||||
diff += mpctx->time_frame;
|
||||
frame->duration = MP_TIME_S_TO_NS(MPCLAMP(diff, 0, 10));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user