mpv icon indicating copy to clipboard operation
mpv copied to clipboard

framerate on variable refresh rate displays fluctuates and causes flickering

Open serolod opened this issue 1 year ago • 8 comments

Important Information

Provide following Information:

  • mpv 0.38.0
  • Void Linux kernel version 6.6.30
  • xbps-install
  • sway 1.9
  • AMD Polaris 22 XT [Radeon RX Vega M GH], normal kernel driver, Mesa 24.0.5

Reproduction steps

mpv --no-config --video-sync=audio --log-file=output.txt 'https://www.youtube.com/watch?v=oaCfKda82nA'

Expected behavior

The framerate should be very close to 60Hz and vary very little. The screen should not flicker.

Actual behavior

Using drm_monitor I measured the timing when the vsyncs actually occur. Sway allows to enable/disable VRR using swaymsg output * adaptive_sync on|off. In
f one can see that with VRR off, the framerate is stable at 120Hz, as expected. With VRR on it fluctuates around 60Hz.

Zooming in f_zoomed one can see the oscillations have an amplitude of around 2.5Hz. The exact amount varies with the video, but the phenomenon can be reproduced reliably. This fluctuation does not sound like much, but can be clearly seen on screen as flickering, especially in darker areas.

Log file

output.txt

Sample files

Occurs on any video I happened to look at, but the measurement was taken on this video.

serolod avatar May 06 '24 22:05 serolod

https://github.com/mpv-player/mpv/issues/12005#issuecomment-1902597586 https://github.com/dechamps/videojitter/blob/master/EXAMPLES.md#video-clock-jitter-eg-vrr

Playing video from a PC using VRR is a very interesting and peculiar case. When using VRR, frames are sent to the display as soon as the video player presents them, as opposed to waiting for the next VSync.

The disavantage is that frame presentation timing now depends on the precise instant at which the video player decides to present a frame. Because Windows is not a real time operating system, and therefore does not make strong timing guarantees, some amount of jitter (most likely video player thread scheduling jitter) is inevitable and will manifest as random variations in frame presentation times.

Note that your result is already much better than the Windows result mentioned. I don't think there is anything mpv can do about this.

na-na-hi avatar May 07 '24 12:05 na-na-hi

I'd be curious to see if you notice any difference using the drm backend with VRR directly instead of going through sway/wlroots but what nanahi said pretty much still stands.

llyyr avatar May 07 '24 16:05 llyyr

I'd be curious to see if you notice any difference using the drm backend with VRR directly instead of going through sway/wlroots but what nanahi said pretty much still stands.

To make sure: You mean running with --vo=drm outside of any X11/wayland session?

#12005 (comment) https://github.com/dechamps/videojitter/blob/master/EXAMPLES.md#video-clock-jitter-eg-vrr

Playing video from a PC using VRR is a very interesting and peculiar case. When using VRR, frames are sent to the display as soon as the video player presents them, as opposed to waiting for the next VSync.

The disavantage is that frame presentation timing now depends on the precise instant at which the video player decides to present a frame. Because Windows is not a real time operating system, and therefore does not make strong timing guarantees, some amount of jitter (most likely video player thread scheduling jitter) is inevitable and will manifest as random variations in frame presentation times.

Note that your result is already much better than the Windows result mentioned. I don't think there is anything mpv can do about this.

I don't know anything about mpv's internals, especially not how the sync to the audio works. But couldn't one calculate when the next frame needs to be presented and (busy) wait until then using a sufficiently high-precision clock? Sort of like a self-imposed vsync. Maybe wayland's presentation time protocol could help?

serolod avatar May 07 '24 19:05 serolod

But couldn't one calculate when the next frame needs to be presented and (busy) wait until then using a sufficiently high-precision clock? Sort of like a self-imposed vsync.

That's already what happens on wayland (minus the busy wait part). And mpv already uses presentation time too.

Dudemanguy avatar May 07 '24 20:05 Dudemanguy

minus the busy wait part

Yeah, if we want to do something at certain time we would need to busy wait at least some part of the sleep duration. Normal sleep will never be accurate enough. It is doable, but this is precisely why display-sync exist, to avoid any timing issues and lock presentation to vsync.

This is again the topic of frame limiter basically, that we had some time ago.

kasper93 avatar May 07 '24 20:05 kasper93

minus the busy wait part

Yeah, if we want to do something at certain time we would need to busy wait at least some part of the sleep duration. Normal sleep will never be accurate enough. It is doable, but this is precisely why display-sync exist, to avoid any timing issues and lock presentation to vsync.

This is again the topic of frame limiter basically, that we had some time ago.

I only used --video-sync=audio because from googling around this seemed the preferred mode to use with VRR. Are the display-* modes actually better suited?

serolod avatar May 07 '24 20:05 serolod

Are the display-* modes actually better suited?

No, they are not compatible with VRR.

kasper93 avatar May 07 '24 20:05 kasper93

In theory, the polling could be removed during the wayland loop and it becomes just purely a busy wait. I doubt that would change OP's results much at all though because it would still be dependent on whenever the compositor sends a frame callback.

Dudemanguy avatar May 07 '24 21:05 Dudemanguy