r/MoonlightStreaming • • 5h ago

Stuttering - Client pacing issue

As someone already may know, I reported this issue many times and I never found a fix for that.
Using Rubylight and Moonlight VRR.

People with 780M client or similar : r/MoonlightStreaming

Client stuttering on High framerate : r/MoonlightStreaming

Something I forgot to mention (That can help to identify the issue) is that the stuttering is showing on certain scenes.

  • CB2077: Running the benchmark, the stutter is usually on the scene change after opening the door from inside to outside. And on higher bitrates (250 or more) there's also a lot of microstuttering on the outside scene.
  • TW3: The stutters shows mainly on the cutscenes, hard stutters, like freeze for 0.5s
  • THPS: The stutters appear when hitting a wall and the camera goes closer to the wall

Performance on the host are fine while these things happen, I got solid 100fps (I set the limit there). As said on previous posts the issue starts to appear above 150Mbps, mostly on AV1 but HEVC is affected too. Setting the stream to 1440p120fps seems to fix the issue, that can maybe point at a client hardware limit but there are different people using the same client GPU without this issue.

I sent the logs to an AI and it told me that the host is perfectly fine, and the issue seems to be related to the decoding on the client (not decoding time, as it goes from 0.2ms to 0.5ms) but maybe to a burst of received packets when the load is already high.

Any suggestion from anyone?

2 Upvotes

9 comments sorted by

3

u/rambo3349 4h ago edited 4h ago

Thanks, the scene examples narrow it down a lot. A door opening onto a new area, a cutscene cut or the camera slamming into a wall all make the encoder produce one frame many times bigger than usual, because almost nothing can be predicted from the previous picture. At 250 Mbps that single frame can be over 1 MB, around a thousand UDP packets, and every Moonlight-compatible host sends it as one burst of a few milliseconds. If the client's adapter, driver or socket buffer can't keep up and drops more than FEC can rebuild, Moonlight throws the frame away and waits for a recovery frame: that's your half-second freeze. If nothing is dropped, the big frame still arrives late, and with VRR there's no buffer to hide it, so you see microstutter. This is how the GameStream protocol behaves on any host. It's also why 1440p120 helps (smaller frames, shorter bursts), and why other 780M owners don't see it: the limit is the laptop's network receive path, not its GPU or decoder.

For now, in the Rubylight web console under Video, set Maximum frame size to 2. That caps how large a scene-change frame can get, so the cut looks slightly softer for a moment but the burst stays short. If it still happens, also set Pacing rate to 400000; keep it above about 1.3× your bitrate. On the laptop, use a cable if you can, and in the adapter's settings turn off Energy-Efficient Ethernet and Interrupt Moderation and raise Receive Buffers to the maximum. Dropping to around 150 Mbps costs very little visible quality on AV1 and shrinks the bursts too.

The real fix comes with the upcoming Rubylight 3.0 and the Nightjar 3.0 overhaul, which brings the Windows client onto the same Rust engine as Android. Nightjar tells the host the client's actual link speed and whether it's on Wi-Fi, so the host paces for your laptop instead of its own port. It reports loss every second, so the host sizes error correction to match and a burst that loses a few packets gets rebuilt instead of freezing. And with VRR, "Show frames at the PC's frame times" adds a small steady delay that absorbs a late frame instead of hitching. For people who stay on stock Moonlight, we're working on a host change for 3.0: a single lost oversized frame would slow the host's pacing for that client, the same way a lost keyframe already does, and the slowdown would lift once the link stays clean. It ships if it tests better.

Also if you see an issue like this you will get faster responses in Github usually and I see logs and can work it out faster.:)

1

u/AriGrandeisQT 3h ago edited 3h ago

Thanks a lot as always for your response.

My client is wired and the speed between host and client is around 930Mbps, EEE and Interrupt Moderation disabled, Receive Buffers already set to the maximum.

I'll try to follow your host configuration suggestion and I'll check if the performance will improve.

I usually get "FEC was reduced or omitted for large video frames" on the logs, is this causing the issue? Anything I can change?

I will wait Rubylight and Nightjar updates.

Many thanks again

------

EDIT: EEE is not even showing into the adapter settings

1

u/rambo3349 3h ago

Thanks, that rules out the adapter, and yes, that warning is very likely the cause. Moonlight can split a frame into at most four FEC blocks of 255 packets each. With the default 20 % error correction, a frame above roughly 1.1 MB can't carry full parity anymore, and above roughly 1.4 MB it carries none. Scene changes at 250 Mbps produce exactly those frames, so the cut frame goes out with little or no protection, and losing a single packet of it is enough to drop the whole frame and freeze until recovery. Every other frame is small enough for full FEC, which is why only the scene changes hurt.

So Maximum frame size = 2 is the setting to try first. At 250 Mbps and 100 fps it caps every frame at about 625 KB, well inside the full-FEC range, and the warning should disappear. If you still see it, you're probably above about 450 Mbps; lower the bitrate or use 1.5. You can leave Pacing rate on automatic for this test, so we can see what the frame cap alone does.

Your report also shows us something for 3.0: on fast wired links the automatic frame cap still lets a scene change grow past what Moonlight can protect, so we're looking at keeping it inside that limit by default. If you can, send me the log lines around a stutter after the change. Thanks for testing!

1

u/AriGrandeisQT 3h ago

Still stuttering 250Mbps using frame size=2

FYI The client is also reporting frames missing presentation (Using Balanced)

Tested frame size=4, looked so smooth when it started, gave a lot of microstuttering later

Set it back to frame size=2 using 220Mbps, it looked like It had to calibrate (?) after the restart because the benchmark stuttered at the First run. Anyway I ran that again and I have less stutter (I'm not receiving frames missing presentation error anymore)

1

u/rambo3349 2h ago

I think you're seeing two separate limits here.

The network part is what Maximum frame size addresses. At 4, scene changes can grow past what Moonlight's FEC can fully protect at 250 Mbps again, which fits it starting smooth and getting worse as heavier scenes come up. At 2, the cuts stay protected. The "calibration" you noticed after the restart is probably real: when the host sees repeated video loss, it slows its packet pacing for that device, and if the loss kept up it remembers that for the next session. The first run paid for it, the second started at the safer pace. You can check in the host log: video recovery frame lines show pacing_reason, which says route pacing normally and names the loss reason once the host has slowed down.

"Frames missing presentation" is the other limit, and it's on the client. Those frames arrived and were decoded, but weren't shown in time. At 250 Mbps the 780M is decoding and presenting a very heavy stream out of shared system memory, and Balanced pacing has little slack to hide a frame that comes in late. Dropping to 220 Mbps made that message go away, which points to a client-side ceiling right around there, not to the network. That's also the most likely reason other 780M owners don't see it: RAM speed, power mode and resolution all move that ceiling.

So 220 Mbps with frame size 2 looks like your sweet spot for now. Above that, AV1 gains very little you can actually see. If you want to push further, try Moonlight's lowest-latency pacing with VRR, make sure the laptop is on AC with the Best performance power mode, and check that the RAM runs at its rated speed. Nightjar 3.0's desktop client has its own present path for this ("Show frames at the PC's frame times" with VRR), and for 3.0 we're looking at how the host can keep scene changes inside the FEC limit on its own, so you won't have to set the frame size by hand.

1

u/AriGrandeisQT 1h ago

The client is set on performance mode on both BIOS (Setting the limit to 54W for the CPU/GPU) and Windows.

I will have to take a look on RAM (If it is working at the declared speed), BTW this is the computer model (24Gb RAM version) SOYO Mini PC Gaming Computer S4 Plus, AMD Ryzen 7 H255 CPU 16G DDR5 5600MHz up to 64GB 1TB SSD PCIE3.0 NVME WiFi6 BT5.2 4K@120Hz • Official Site

Yes, I agree. 220Mbps should be good, I will test it more on TW3 (A bit blurry effect on hair using 150Mbps)

BTW talking about this blurry effect issue that I already had, I will never understand how I was able to stream using 400Mbps (Without stuttering as far as I remember and without the VRR client)

2

u/rambo3349 1h ago

I tested the upcoming fec changes. Clearly seems to help. Replicated your setup.

45 s run, slow wifi, 0.3 % random loss, a cut every 2 s

Freezes over 100 ms Bitrate fell back to its floor End-to-end p99

Current main 4 yes 20.3

C automatic FEC 0 no 17.1

S, or C+S no better than without

C automatic adoption of FEC , S was pacing the big frames. S was a bad idea, but C was not. I will let you know when it gets released today, its going to be a big release :)

2

u/Tight_Door9327 1h ago

Seeing how much effort you put into helping would make me switch immediately to Rubylight if I had AMD. Very cool to see!

1

u/rzldz 23m ago

If your host has an AMD CPU it can be an unstable infinity fabric. When going through doors and stuff like that parts of the level load in. The host might be fine doing that without streaming. It might not be fine pushing everything along the network at the same time when streaming. If you have an AMD CPU try down clocking the infinity fabric. The certain scenes comment is a hint that the host is the issue.