LizardByte / LizardByte/Sunshine
NvFBC retrieves slightly outdated images.
@hgaiser is already working on this.
Since Mar 5, 2025.
- Dominant language
- C++
- Stars
- 41.3k
- Forks
- 2.1k
- Avg merge
- 23h 47m
- Merged PRs (30d)
- 124
Description
### Is there an existing issue for this?
- [X] I have searched the existing issues
### Is your issue described in the documentation?
- [X] I have read the documentation
### Is your issue present in the nightly release?
- [X] This issue is present in the nightly release
### Describe the Bug
NvFBC has a few different methods to capture an image. The one used in Sunshine is:
```c++
/*!
* Capturing does not wait for a new frame nor a mouse move.
*
* It is therefore possible to capture the same frame multiple times.
* When this occurs, the dwCurrentFrame parameter of the
* NVFBC_FRAME_GRAB_INFO structure is not incremented.
*/
NVFBC_TOSYS_GRAB_FLAGS_NOWAIT = (1 << 0),
```
Basically it means that whenever Sunshine requests a new frame, a frame is provided, but that frame can be "old" (max of 1/fps seconds old). Still though, it means at 60fps a frame could be 16msec old.
Changing to `NVFBC_TOCUDA_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY` would mean that the frame request blocks until a new frame becomes available, but it returns the frame immediately if NvFBC knows it's a new frame. This also means that when the host is serving static content, the FPS drops to 13.33FPS in my tests (not sure why this amount exactly).
```c++
/*!
* Similar to NVFBC_TOCUDA_GRAB_FLAGS_NOFLAGS, except that the capture will
* not wait if there is already a frame available that the client has
* never seen yet.
*/
NVFBC_TOCUDA_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY = (1 << 2),
```
And for context (since that flag basically extends the NOFLAGS flag) :
```c++
/*!
* Default, capturing waits for a new frame or mouse move.
*
* The default behavior of blocking grabs is to wait for a new frame until
* after the call was made. But it's possible that there is a frame already
* ready that the client hasn't seen.
* \see NVFBC_TOCUDA_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY
*/
NVFBC_TOCUDA_GRAB_FLAGS_NOFLAGS = 0,
```
As far as I can see, we can simply use `NVFBC_TOCUDA_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY` instead of `NVFBC_TOSYS_GRAB_FLAGS_NOWAIT`. [This](https://github.com/LizardByte/Sunshine/blob/7fb8c76590f843f28b2061cd0a1543f0710795e3/src/platform/linux/cuda.cpp#L806-L810) wait becomes kinda redundant, but it won't hurt either.
### Expected Behavior
N/A
### Additional Context
N/A
### Host Operating System
Linux
### Operating System Version
Arch Linux
### Architecture
64 bit
### Sunshine commit or version
7fb8c76590f843f28b2061cd0a1543f0710795e3
### Package
other (self built)
### GPU Type
Nvidia
### GPU Model
GeForce RTX 3090
### GPU Driver/Mesa Version
550.76
### Capture Method (Linux Only)
NvFBC
### Config
N/A
### Apps
N/A
### Relevant log output
N/A
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.