LizardByte / LizardByte/Sunshine

NvFBC retrieves slightly outdated images.

Open
#2,472 28 comments 0 reactions 1 assignee View on GitHub

@hgaiser is already working on this.

Since Mar 5, 2025.

stale
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.