mpv icon indicating copy to clipboard operation
mpv copied to clipboard

Smooth playback of `video-sync=display-*` at FPS below the monitor's maximum

Open hooke007 opened this issue 3 years ago • 30 comments

Currently set video-sync=display-resample would make mpv always try to match the monitor's highest refresh rate. For those 240~360Hz monitors, enabling this option would introduce much frame-drop/delay.

Expected behavior of the wanted feature

Add the new option like video-sync-target-fps=xxx to avoid this trouble.

Alternative behavior of the wanted feature

N/A

Log file

N/A

hooke007 avatar Jan 10 '23 22:01 hooke007

The increased overhead comes from interpolation and not from video-sync=display-*, but reducing the targeted frame rate would certainly help with resource usage.

Instead of targeting a specific refresh rate, it would make more sense to cap it to a max so that it can still line up with lower refresh rates in mixed refresh rate systems.

But even that isn't an optimal solution, because when e.g. a cap of 80fps is set and the window is on a 120hz monitor, then targeting 60fps instead of capping out on 80fps would probably result in smoother playback.

Now with that being said, is there even a need for interpolation on such monitors? I'd imagine that the refresh rate is high enough that slightly imperfectly timed frames would be hardly noticeable. I have never used such a monitor though, so it's hard to say.

christoph-heinrich avatar Jan 10 '23 22:01 christoph-heinrich

The increased overhead comes from interpolation

I didn't enable interpolation with display-resample. Enabling interpolation would increase more GPU consumption.

But even that isn't an optimal solution, because when e.g. a cap of 80fps is set and the window is on a 120hz monitor, then targeting 60fps instead of capping out on 80fps would probably result in smoother playback.

This could ref some games, they could use fixed 1/2 or 1/4 refreash rate as vsync target.

hooke007 avatar Jan 10 '23 23:01 hooke007

Shouldn't --override-display-fps work for this?

Dudemanguy avatar Jan 10 '23 23:01 Dudemanguy

Shouldn't --override-display-fps work for this?

Snipaste_2023-01-10_23-24-42

Unfortunately, it would make more delayed/dropped frames.

override-display-fps=120 Snipaste_2023-01-10_23-24-13

hooke007 avatar Jan 10 '23 23:01 hooke007

Can you post a log with that option set to 120 really quick?

Dudemanguy avatar Jan 10 '23 23:01 Dudemanguy

fps.log (start with override-display-fps=120) fps2.log (apply override-display-fps=120 on the fly)

hooke007 avatar Jan 10 '23 23:01 hooke007

[ 0.104][v][vo/gpu] Assuming 120.000000 FPS for display sync.

So yes, the target FPS is actually configurable and a quick look at the code confirms this. However, when using a display-* video sync mode, this leads to worse results. The reason is because those modes are timed directly to vsync. Since your monitor has such a high refresh rate, the vsync block returns twice as fast (i.e. at a 240hz rate instead of 120hz) which proceeds to mess up mpv's timing code which is being told that the display FPS is 120. So the feature you want technically exists (override-display-fps), but it's at odds with how display-* is designed so it can't possibly work well. I'll alter the title a bit for clarity for clarity.

As for implementing something like this, it wouldn't be impossible but it would take some work and careful thinking.

Dudemanguy avatar Jan 11 '23 00:01 Dudemanguy

I have somewhat similar issue.

Currently set video-sync=display-resample would make mpv always try to match the monitor's highest refresh rate.

In my case Display Fps (specified) is monitor's current refresh rate and when using video-sync=display-* the Display Fps (estimated) is double of specified Display Fps and with mistimed and delayed frames. image

Issue only persists with gpu-api=d3d11, vulkan and opengl doesn't show any drops and delays.

WhoMI7 avatar Jan 12 '23 08:01 WhoMI7

That sounds like a bug.

Dudemanguy avatar Jan 12 '23 14:01 Dudemanguy

Maybe it is. I found 2 fixes for these, (Nvidia GPU)

  1. Turning off G-sync/freesync. (Not reliable)
  2. Setting Monitor Technology to Fixed Refresh Rate for mpv in Nvidia Control Pannel. (Con: Black screen for 2 secs whenever mpv is opened, closed and fullscreen in and out.)

Can't reproduce my issue on AMD gpu.

WhoMI7 avatar Jan 13 '23 06:01 WhoMI7

G-sync is incompatiable with mpv. It's another known issue.

hooke007 avatar Jan 13 '23 07:01 hooke007

Yeah, maybe I should open another issue for my problem, plus I have some questions too.

Edit: Fixed my issue, it was a driver bug in my case. Maybe yours too? https://www.guru3d.com/files-details/display-driver-uninstaller-download.html

WhoMI7 avatar Jan 13 '23 12:01 WhoMI7

+1 for this feature request. I am currently toying with smooth motion and refresh rate handling on my 175hz monitor with gsync and this would solve most of my problems.

dontpokethebear3893 avatar May 20 '23 19:05 dontpokethebear3893

Now with that being said, is there even a need for interpolation on such monitors? I'd imagine that the refresh rate is high enough that slightly imperfectly timed frames would be hardly noticeable. I have never used such a monitor though, so it's hard to say. Actually, the differences between interpolation on and off are noticeable on a 240Hz monitor.

Is this issue related to the drawback described in wiki?

Finally, --video-sync=display-* currently comes with one important drawback: Due to OpenGL's rather severe limitations when it comes to timing, the only way to reliably figure out when vsyncs happen is to actually draw a frame on every vsync. The consequence of this is that, even for 24 Hz video, you need to draw frames at 60 Hz even if they are the same frame over and over again - thus increasing power usage by a factor of 2x-3x in such a case. This is usually somewhat alleviated by caching the frame result, and redrawing the cached frame, instead of scaling and rendering the source frame every time. The problem that there's less time to render subtitles on a 60 Hz screen remains.

snylonue avatar Jul 04 '23 02:07 snylonue

@Dudemanguy Could you consider adding it into https://github.com/mpv-player/mpv/milestone/3 ?

Since your monitor has such a high refresh rate, the vsync block returns twice as fast (i.e. at a 240hz rate instead of 120hz) which proceeds to mess up mpv's timing code which is being told that the display FPS is 120.

Unfortunately, I noticed obvious frame-drops in my current display(4k95hz). I cannot even smoothly playback a 720p24fps short video. This sounds really ridiculous. Which means large numbers of modern monitor would suffer this pain.

hooke007 avatar Nov 08 '23 17:11 hooke007

A framerate limiter is a good feature in general but out of scope for the upcoming release. We can revisit this after 0.37 I think.

Dudemanguy avatar Nov 08 '23 17:11 Dudemanguy

A framerate limiter is a good feature in general but out of scope for the upcoming release. We can revisit this after 0.37 I think.

While this can be added, the limiter is directly contradict the premise of display-sync. The main problem is that we cannot schedule vsyncs accurate enough in software to make perfectly smooth playback, without any strutter. That's why display-sync exist to rely on implicit vsync to sync frames correctly.

So actually the frame limiter will not improve situation, because it will introduce stutter in itself. The proper way to use display-sync is to set your display to certain refresh rate and let mpv sync to that.

Of course frame limiter is viable option, but like I said it will not do what you want it to do in fact.

kasper93 avatar Nov 10 '23 16:11 kasper93

While this can be added, the limiter is directly contradict the premise of display-sync. The main problem is that we cannot schedule vsyncs accurate enough in software to make perfectly smooth playback, without any strutter. That's why display-sync exist to rely on implicit vsync to sync frames correctly.

That's not entirely true, with Freesync it's possible but Freesync only works properly in fullscreen. Currently you need to use a vf to multiply the video's FPS though which isn't really ideal for some since it means you can't use interpolation.

Jules-A avatar Nov 11 '23 08:11 Jules-A

Creating a custom modeline is probably the more elegant and less headache-inducing solution. If you have a custom modeline, it's already debatable whether or not you actually need display-resample to get even pull-down.

The only non-elegant part is that switching between modelines on Windows is just annoying and scripting it requires a lot of external freeware tools that I hate keeping on my system. But modeline switching is probably beyond the scope of mpv since it would need to be OS-specific.

ghost avatar Nov 11 '23 22:11 ghost

I think I'm encountering a similar issue on MacOS on a MacBook Pro with 120Hz monitor. The issue is very apparent when using Vulkan, but not with libmpv.

With this command, a 4K video is pretty jerky, showing a lot of Mistimed/Delayed frames happening during playback:

mpv --no-config -vo=gpu-next -gpu-context=macvk -fs -video-sync=display-resample test.mp4

With this command the same video is smooth:

mpv --no-config -vo=gpu-next -gpu-context=macvk -fs test.mp4

And with this one the video is also smooth, with only a handful of Mistimed/Delayed frames happening at the very beginning:

mpv --no-config -vo=libmpv -video-sync=display-resample -fs test.mp4

bsolar17 avatar Nov 26 '23 10:11 bsolar17

@bsolar17 try with different options of --macos-render-timer, eg precise and system.

Akemi avatar Nov 26 '23 12:11 Akemi

@Akemi, I tried with both options but they did not improve the jerkiness.

bsolar17 avatar Nov 26 '23 14:11 bsolar17

G-sync is incompatiable with mpv. It's another known issue.

Is there any update on this? Also where is the issue about it

ghost avatar Mar 02 '24 16:03 ghost

It has been 1 year, updates ?

ghost avatar Apr 07 '24 21:04 ghost

This could ref some games, they could use fixed 1/2 or 1/4 refreash rate as vsync target.

This is already possible with --opengl-swapinterval/--d3d11-sync-interval and --display-fps-override. You need to manually calculate the display fps after being divided by the swap interval, but this works for me.

na-na-hi avatar Apr 07 '24 21:04 na-na-hi

This could ref some games, they could use fixed 1/2 or 1/4 refreash rate as vsync target.

This is already possible with --opengl-swapinterval/--d3d11-sync-interval and --display-fps-override. You need to manually calculate the display fps after being divided by the swap interval, but this works for me.

but such options won't solve the frame dropping issue as pointed out before.

snylonue avatar Apr 08 '24 01:04 snylonue

but such options won't solve the frame dropping issue as pointed out before.

I don't think setting a larger swap interval was mentioned before in this issue. That is required for this to work.

You need to set the interval to a value larger than 1. If the video driver is working properly, the "estimated" display fps should be reduced by that factor (if not, it will still be the real display fps no matter what the value of --display-fps-override is).

For example, after specifying a factor of 2, the "estimated" display fps should be around 120 for a 240 Hz display. This option throttles the rendering speed so mpv thinks that the display has a lower fps. Then set the value of --display-fps-override to match that estimated fps. This way mpv also thinks that the display's refresh rate matches the rendering speed, so it detects nothing abnormal and will render at the reduced framerate.

na-na-hi avatar Apr 08 '24 01:04 na-na-hi

Not sure if this is the right place for VRR jitter issues but I still have them using

vo=gpu-next
gpu-context=d3d11
hwdec=d3d11va
d3d11-sync-interval=0

On Windows 10 22H2 RX 580, I measured the frame times using CapFrameX (or any similar tool) and they are still unstable.

Image

The only players I found that display VRR properly are the built in Microsoft UWP ones with zero measurable jitter by monitor OSD which updates every frame.

I guess Microsoft must be using a fixed timer or something to present frames because their VRR doesn't support variable rate video.

MPC-VR is a close second, but it seems to use milliseconds or windows timers internally so it has frame time variations at a repeating pattern +/- 1ms.

xCuri0 avatar May 27 '25 04:05 xCuri0

d3d11-sync-interval=0

What about without this?

Jules-A avatar May 27 '25 09:05 Jules-A

@Jules-A doesn't make any difference

xCuri0 avatar May 27 '25 12:05 xCuri0