Skip to content

feat(fps): support x-nv-video[0].clientRefreshRateX100 for requesting fractional NTSC framerates #4019

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

andygrundman
Copy link
Contributor

Description

This PR brings back an old GFE parameter for specifying fractional refresh rates. If the param is specified, Sunshine will try to deliver the exact rate requested, which can be helpful for clients using Apple TV, Xbox, and others that might be stuck at 59.94hz or 119.88hz.

Common NTSC rates are hardcoded to their exact values, because 59.94 is not really the true rate, it's defined as 60000/1001. Just for fun, 23.976hz film is also supported if either 2397 or 2398 is supplied.

Screenshot

[2025-06-27 22:08:45.366]: Info: Display refresh rate [119.999Hz]
[2025-06-27 22:08:45.366]: Info: Requested frame rate [60000/1001 exactly 59.94 fps]

Type of Change

  • New feature (non-breaking change which adds functionality)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated the in code docstring/documentation-blocks for new or existing methods/components

Copy link

@andygrundman
Copy link
Contributor Author

I moved the function to video, and reverted the stuff in utility.h affecting tools. No need to include rational.h now either. The only weird thing left is in src/platform/windows/display_base.cpp where I needed to do this due to video namespace issues.

AVRational fps = ::video::framerateX100_to_rational(config.framerateX100);

@ns6089
Copy link
Contributor

ns6089 commented Jul 2, 2025

Alternatively instead of x100 workaround you can introduce new fractional SDP parameter (or two). This should remove intermediate steps and extend the usability, like creating new virtual display modes in runtime.

@andygrundman
Copy link
Contributor Author

Alternatively instead of x100 workaround you can introduce new fractional SDP parameter (or two). This should remove intermediate steps and extend the usability, like creating new virtual display modes in runtime.

I don't follow. You actually need to avoid the use of any floating point numbers because they would introduce rounding errors that get worse over time. NTSC for example if you just tried to stream at 59.94 you would be running slightly off from your TV, as 59.94 is only an approximation. Nvidia had the right idea with this option, we just never implemented it before.

@ns6089
Copy link
Contributor

ns6089 commented Jul 3, 2025

I mean just pass a pair of integer numbers

a=x-ml-video.targetFramerateFractional:60000 1001

or

a=x-ml-video.targetFramerateFractionalNum:60000
a=x-ml-video.targetFramerateFractionalDen:1001

@andygrundman
Copy link
Contributor Author

andygrundman commented Jul 3, 2025

I mean just pass a pair of integer numbers

a=x-ml-video.targetFramerateFractional:60000 1001

or

a=x-ml-video.targetFramerateFractionalNum:60000
a=x-ml-video.targetFramerateFractionalDen:1001

Are you trolling? We have a simpler method and I already got it working. If your comment is about a way to avoid floats please look at the patch. I just hardcoded the few NTSC cases where it matters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants