Skip to content

Add support for clientRefreshRateX100, enabling streaming at 59.94 or 119.88 hz - #200

Merged
TheElixZammuto merged 1 commit into
TheElixZammuto:masterfrom
andygrundman:andyg.xbox-5994
Jul 4, 2025
Merged

Add support for clientRefreshRateX100, enabling streaming at 59.94 or 119.88 hz#200
TheElixZammuto merged 1 commit into
TheElixZammuto:masterfrom
andygrundman:andyg.xbox-5994

Conversation

@andygrundman

@andygrundman andygrundman commented Jun 29, 2025

Copy link
Copy Markdown
Collaborator

I've submitted a Sunshine PR [1] to support an old unused GFE parameter for fractional refresh rates. The easiest client that could test this is Xbox and the patch is very small. You can verify that it's working in the Sunshine log by looking for a line like this: Info: Requested frame rate [60000/1001 exactly 59.94 fps]

I've also modified dregu's frameskip tool [2] to support fractional rates. Whether or not it's accurate enough to matter, I don't know, but it's better than nothing. Xbox still needs better frame pacing which I'm working on, but this may be a small improvement in the meantime. I have tested this at 119.88 and 59.94.

[1] LizardByte/Sunshine#4019
[2] https://andygrundman.github.io/frameskip/

Summary by CodeRabbit

  • New Features

    • The app now detects and uses the display's refresh rate on Xbox devices, improving streaming configuration accuracy.
    • Added logging to indicate the detected and requested refresh rate during streaming startup.
  • Bug Fixes

    • Streaming refresh rate is now set only when a valid refresh rate is available from the device, preventing incorrect configurations on unsupported platforms.

@coderabbitai

coderabbitai Bot commented Jun 29, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

A new mechanism for determining and accessing the display refresh rate was added to the device resource management system. The refresh rate is now detected at construction, stored in a member variable, and exposed via accessor methods. The streaming client logic now uses this refresh rate if available, logging the requested value.

Changes

File(s) Change Summary
Common/DeviceResources.cpp, Common/DeviceResources.h Added m_refreshRate member to DeviceResources; introduced GetUWPRefreshRate() and GetRefreshRate() methods; initialized and accessed refresh rate.
State/MoonlightClient.cpp Updated streaming config to use DeviceResources' refresh rate if available; added logging for requested rate.

Poem

A rabbit hopped to screens anew,
Detecting rates both old and true—
Now Moonlight streams with fresher pace,
Device refresh rates in their place!
With every frame, a smoother run,
The code now shines like morning sun.
🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b09e6b4 and 01a4452.

📒 Files selected for processing (3)
  • Common/DeviceResources.cpp (2 hunks)
  • Common/DeviceResources.h (2 hunks)
  • State/MoonlightClient.cpp (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • Common/DeviceResources.h
  • State/MoonlightClient.cpp
  • Common/DeviceResources.cpp
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
Common/DeviceResources.cpp (1)

821-837: Fix float literal inconsistency and approve the implementation approach.

The platform detection logic correctly distinguishes between Xbox and Windows, and the Xbox implementation properly retrieves the display refresh rate. However, there's a minor type inconsistency.

Apply this diff to fix the type consistency:

-	double refreshRate = 0.0f;
+	double refreshRate = 0.0;

The overall approach aligns well with the PR objectives to support fractional refresh rates like 59.94 Hz and 119.88 Hz on Xbox devices.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 33141c5 and b09e6b4.

📒 Files selected for processing (4)
  • Common/DeviceResources.cpp (1 hunks)
  • Common/DeviceResources.h (2 hunks)
  • State/MoonlightClient.cpp (1 hunks)
  • Streaming/moonlight_xbox_dxMain.cpp (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
Streaming/moonlight_xbox_dxMain.cpp (5)
Learnt from: LAGonauta
PR: TheElixZammuto/moonlight-xbox#167
File: State/MoonlightHost.h:38-38
Timestamp: 2025-02-27T02:36:15.388Z
Learning: When using hdmiDisplayMode in the MoonlightHost::Connect() method, a null check should be performed since hdmiDisplayMode might be null when loading previously saved hosts without display information. The MoonlightClient constructor should either handle null parameters or the Connect() method should initialize hdmiDisplayMode with a default value before passing it.
Learnt from: LAGonauta
PR: TheElixZammuto/moonlight-xbox#167
File: State/MoonlightHost.h:38-38
Timestamp: 2025-02-27T02:36:15.388Z
Learning: In MoonlightHost class, hdmiDisplayMode should be explicitly initialized to nullptr in the constructor, and null checks should be added before accessing it in methods like Connect(). This is particularly important because hdmiDisplayMode might not be initialized when loading previously saved hosts that don't contain display information.
Learnt from: LAGonauta
PR: TheElixZammuto/moonlight-xbox#167
File: State/MoonlightHost.h:38-38
Timestamp: 2025-02-27T02:36:15.388Z
Learning: In C++/CX, reference type member variables like HdmiDisplayModeWrapper^ should be explicitly initialized to nullptr in constructors if they don't have a valid value at construction time. Leaving them uninitialized can lead to null-pointer exceptions when they're accessed without checks.
Learnt from: andygrundman
PR: TheElixZammuto/moonlight-xbox#178
File: Streaming/moonlight_xbox_dxMain.cpp:444-455
Timestamp: 2025-03-31T11:54:31.863Z
Learning: In the moonlight-xbox project, using Sleep() inside concurrency::create_async() is an acceptable pattern when the intention is to specifically block that background thread while not affecting the UI responsiveness, such as when simulating key sequences that require specific timing.
Learnt from: LAGonauta
PR: TheElixZammuto/moonlight-xbox#167
File: State/MoonlightHost.h:38-38
Timestamp: 2025-02-27T02:36:15.388Z
Learning: In MoonlightHost class, hdmiDisplayMode should be initialized in the constructor to prevent null-pointer exceptions. This is particularly important when connecting to previously saved hosts where hdmiDisplayMode data might not be available.
Common/DeviceResources.h (1)
Learnt from: LAGonauta
PR: TheElixZammuto/moonlight-xbox#167
File: State/MoonlightHost.h:38-38
Timestamp: 2025-02-27T02:36:15.388Z
Learning: In C++/CX, reference type member variables like HdmiDisplayModeWrapper^ should be explicitly initialized to nullptr in constructors if they don't have a valid value at construction time. Leaving them uninitialized can lead to null-pointer exceptions when they're accessed without checks.
🧬 Code Graph Analysis (1)
State/MoonlightClient.cpp (3)
State/MoonlightClient.h (1)
  • res (23-23)
Utils.hpp (1)
  • Logf (15-15)
Utils.cpp (2)
  • Logf (90-99)
  • Logf (90-90)
🔇 Additional comments (2)
Streaming/moonlight_xbox_dxMain.cpp (1)

76-77: LGTM! Proper refresh rate initialization.

The refresh rate initialization correctly retrieves the UWP refresh rate and stores it in device resources for use by the streaming configuration. This establishes the foundation for fractional refresh rate support.

State/MoonlightClient.cpp (1)

221-225: LGTM! Correctly implements fractional refresh rate streaming.

The conditional logic properly checks for valid refresh rate availability before setting clientRefreshRateX100. The multiplication by 100 and integer cast correctly formats the value for the streaming protocol. The logging will help verify the feature works as described in the PR objectives.

This change enables the core functionality of requesting streams at exact fractional refresh rates like 59.94 Hz and 119.88 Hz, which aligns perfectly with the PR goals.

Comment thread Common/DeviceResources.h
@GuiDev1994

Copy link
Copy Markdown

Can you send me the build files to test it too? I tested the version launched with V-Sync and didn't worked the 120fps.

@sonarqubecloud

sonarqubecloud Bot commented Jul 1, 2025

Copy link
Copy Markdown

@andygrundman

Copy link
Copy Markdown
Collaborator Author

Can you send me the build files to test it too? I tested the version launched with V-Sync and didn't worked the 120fps.

Sorry, do you mean a Sunshine build that supports this option?

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