Skip to content

Display helper validation gate delays capture start by ~11s, exceeding Moonlight's client timeout on Xbox Series S #357

Description

@thoffmann666-ui

Bug Symptoms

When a virtual display is used, video capture does not start until the display helper validation gate times out. The gate fires Display helper validation failed; starting capture anyway consistently ~11.0 seconds after APPLY dispatch result=true, and capture only begins after that point.

Moonlight UWP on Xbox Series S times out after roughly 10 seconds, so the client disconnects a fraction of a second before the first frame is produced. On the client this looks like a grey screen followed by a silent disconnect — no error is shown.

Occasionally the first stream after a service start succeeds. This is not a configuration difference: when the client's RTSP handshake completes late enough relative to display creation, the remaining wait falls just under the client timeout. It is a race that is lost almost every time.

Measurements — time from Display helper: APPLY dispatch result=true to Display helper validation failed:

Run VDD APPLY confirmed Validation failed Delta Outcome
11:37 Sunshine VDD 23.990 34.994 11.004 s success (57 s session)
11:38 Sunshine VDD 35.701 46.710 11.009 s frame produced, client already gone
11:38 Sunshine VDD 55.558 06.548 10.990 s fail
11:47 SudoVDA 58.030 09.033 11.003 s fail

The delta is constant to within ~20 ms across runs and across two different virtual display drivers, which suggests a fixed timeout rather than a variable wait on Windows.

Both VDD drivers are affected. With dd_use_sunshine_virtual_display_driver = enabled, Windows never exposes a target-specific display identity:

Sunshine temporary display created before Windows exposed a target-specific display identity; waiting for virtual display enumeration.
Warning: Virtual display scale: monitor device path was unavailable; Windows scale was not applied.
Info: Virtual display created (device name pending enumeration).

With dd_use_sunshine_virtual_display_driver = false (SudoVDA fallback), enumeration is clean:

11:47:57.085  Virtual display scale: requested 250%, recommended 150%, previous 150%, current 250%.
11:47:57.094  Virtual display created at \\.\DISPLAY32

Device name available immediately, scale applied, no warning — and the gate still times out at 11.003 s. This suggests the gate is not actually waiting on display identity resolution, or is waiting on something that never resolves on this system regardless of enumeration state.

Failing run, annotated:

11:38:34.214  Virtual display created (device name pending enumeration).
11:38:35.701  Display helper: APPLY dispatch result=true
11:38:37.195  CLIENT CONNECTED
11:38:37.212  Display helper: waiting for apply/validation gate before starting capture.
              ... ~9.5 s of nothing ...
11:38:46.710  Error: Display helper validation failed; starting capture anyway.
11:38:47.231  Capture format [DXGI_FORMAT_R16G16B16A16_FLOAT]
11:38:53.851  CLIENT DISCONNECTED

Steps to reproduce

  1. Fresh install, default settings, pair an Xbox Series S running the official Moonlight app.
  2. Start a stream. It may succeed once.
  3. Start another stream. Grey screen, then silent disconnect after ~10 s.

Reproduced after a complete uninstall including deletion of C:\Program Files\Apollo\config, removal of all hidden monitor devices in Device Manager, and a reboot. Default settings, no per-client overrides, single virtual display in vibeshine_state (remembered virtual display device ... (1 total)).

Workaround

Setting virtual_display_mode = disabled and streaming to a hardware dummy plug (EDID matching the client resolution) removes the gate entirely. Capture starts within ~250 ms of CLIENT CONNECTED and sessions run for 10+ minutes without issue. This confirms the gate is the blocking factor, but it requires extra hardware and frame pacing is noticeably worse than with the virtual display.


### Expected Behavior

Capture should start early enough for the client to receive its first frame within Moonlight's connection timeout (~10 s).

The fallback path already does the right thing: after the gate expires it logs `starting capture anyway` and capture works correctly. Possible fixes:

- Don't gate capture start on helper verification — start capture immediately and let verification run in parallel.
- Reduce the gate timeout to well below typical client timeouts.
- Make the gate timeout configurable.

Windows Version

25H2

Package

Windows - exe installer

GPU Type

NVIDIA

GPU Model

NVIDIA GeForce RTX 4070Ti

GPU Driver Version

610.62

Capture Method

Windows.Graphics.Capture (Windows)

Apps

Logs (Optional but Recommended)

vibepollo-log-1133-sunshine-vdd.txt
vibepollo-log-1147-sudovda.txt

Screenshot (Optional)


Metadata

Metadata

Assignees

No one assigned

    Labels

    fixedThis issue has been marked as fixed and will be closed out once the release has been published.

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions