Skip to content

Commit

Permalink
vo: add --display-fps-limiter option
Browse files Browse the repository at this point in the history
This is questionable but something like this has been commonly requested
over the years. Using any display-* mode will make mpv render at the
monitor's maximum refresh rate. This is correct given what the modes are
supposed to do, but nowadays people have super high refresh rate
monitors which means mpv can be rendering at 240fps or something crazy
high. One could make a custom modeline or just use the default audio
sync mode, but it might be nice to add in the ability to have an
artificial limiter on the frame rate. The --display-fps-override option
already exists to set a specific fps. All that is missing is a flag to
use that number as a hard cap. Fixes #11122.
  • Loading branch information
Dudemanguy committed Aug 2, 2024
1 parent 11ed012 commit 13d3902
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 1 deletion.
1 change: 1 addition & 0 deletions DOCS/interface-changes/display-fps-limiter.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add `--display-fps-limiter` option
11 changes: 10 additions & 1 deletion DOCS/man/options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1212,7 +1212,16 @@ Video
monitor.

Set this option only if you have reason to believe the automatically
determined value is wrong.
determined value is wrong or intend to use the ``--display-fps-limiter``
option.

``--display-fps-limiter=<yes|no>``
When using a ``--video-sync=display-*``, limit mpv's framerate to the
detected display FPS. This can be combined with the
``--display-fps-override`` option to essentially set a specific framerate
limiter. This is mainly useful for VRR monitors with very high refresh rates
that can also support a lower rate. Using this is probably less accurate
than setting a custom modeline to your target frame rate, so use with care.

``--hwdec=<api1,api2,...|no|auto|auto-safe|auto-copy>``
Specify the hardware video decoding API that should be used if possible.
Expand Down
1 change: 1 addition & 0 deletions options/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ static const m_option_t mp_vo_opt_list[] = {
{"native-fs", OPT_BOOL(native_fs)},
{"native-touch", OPT_BOOL(native_touch)},
{"show-in-taskbar", OPT_BOOL(show_in_taskbar)},
{"display-fps-limiter", OPT_BOOL(display_fps_limiter)},
{"display-fps-override", OPT_DOUBLE(display_fps_override),
M_RANGE(0, DBL_MAX)},
{"video-timing-offset", OPT_DOUBLE(timing_offset), M_RANGE(0.0, 1.0)},
Expand Down
1 change: 1 addition & 0 deletions options/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ typedef struct mp_vo_opts {
char *mmcss_profile;
int window_corners;

bool display_fps_limiter;
double display_fps_override;
double timing_offset;
int video_sync;
Expand Down
12 changes: 12 additions & 0 deletions video/out/vo.c
Original file line number Diff line number Diff line change
Expand Up @@ -980,13 +980,25 @@ static bool render_frame(struct vo *vo)

vo->driver->flip_page(vo);

int64_t forced_wait = 0;
if (vo->opts->display_fps_limiter && VS_IS_DISP(vo->opts->video_sync)) {
forced_wait = now + in->nominal_vsync_interval;
wait_until(vo, forced_wait);
}

struct vo_vsync_info vsync = {
.last_queue_display_time = -1,
.skipped_vsyncs = -1,
};
if (vo->driver->get_vsync)
vo->driver->get_vsync(vo, &vsync);

// If we are using the fps limiter, set these fields using forced wait.
if (forced_wait) {
vsync.last_queue_display_time = forced_wait;
vsync.vsync_duration = forced_wait - now;
}

// Make up some crap if presentation feedback is missing.
if (vsync.last_queue_display_time <= 0)
vsync.last_queue_display_time = mp_time_ns();
Expand Down

0 comments on commit 13d3902

Please sign in to comment.