mirror of
https://github.com/mpv-player/mpv
synced 2024-12-24 15:52:25 +00:00
vo: redraw dropped frame if paused between queuing and drawing frame
When frame-stepping with display-sync mode enabled in high framerate video, the frame was sometimes not redrawn correctly. Only the first OSD interaction (or something similar) made it visible. In this case, the core schedules many frames as dropped (because it's ignorant of pausing/frame-stepping, as in theory the player is _not_ paused during frame-stepping, only at the end of it). There's a race between the VO rendering the queued frame, and the core calling vo_set_paused() after it has queued the frame. If the latter happens first, the existing logic to redraw the previous dropped frame does things correctly. If the former happens, the frame is not redrawn automatically, but will be redrawn on the next user input (or if OSD is enabled, and the pause state change updates it, which leads to an immediate redraw). Fix this by never actually dropping a frame in paused mode. The request by the core to drop it is simply ignored. Maybe this could be done slightly nicer by updating the pause state with the VO atomically. Then we wouldn't have the frame drop counter going up either (it's actually dropped, but then redrawn; but I doubt any user, or me in a few weeks, would understand this). But I'm not really interested in polishing this by increasing the complexity of the frame-step code.
This commit is contained in:
parent
c23b3ac53a
commit
000c045aa8
@ -883,6 +883,9 @@ static bool render_frame(struct vo *vo)
|
||||
if (in->current_frame->num_vsyncs > 0)
|
||||
in->current_frame->num_vsyncs -= 1;
|
||||
|
||||
// Always render when paused (it's typically the last frame for a while).
|
||||
in->dropped_frame &= !in->paused;
|
||||
|
||||
bool use_vsync = in->current_frame->display_synced && !in->paused;
|
||||
if (use_vsync && !in->expecting_vsync) // first DS frame in a row
|
||||
in->prev_vsync = now;
|
||||
|
Loading…
Reference in New Issue
Block a user