7b99b41ede
Much of design/ described work that has since shipped. Trim each doc to
its durable rationale + still-open items (the code is the source of truth
for shipped detail; git history holds the full originals).
- Shipped plans -> status stubs: stats-capture, gamestream-host-plan,
apple-stage2-presenter, windows-service.
- Trimmed completed-out / open-kept: implementation-plan, hdr-pipeline,
host-latency, gpu-contention (fixed stale status table), game-library,
linux-setup (fixed m0->spike + stale zero-copy claim),
session-aware-host-followups, windows-client-bootstrap,
windows-dualsense-{scoping,game-detection}, windows-virtual-display,
security-review (per-finding status table; #12 still open),
apollo-comparison (shipped backlog collapsed to one-liners).
- Windows-host cluster consolidated: windows-host.md -> redirect into
windows-host-rewrite.md (whose stale scorecard is corrected -- goal1 is
merged, M4 done); windows-secure-desktop.md archived (now a fallback
behind IDD-push primary).
- Kept evergreen: ci.md, gamescope-multiuser.md, windows-build-and-packaging.md.
- New design/README.md: per-doc status table + consolidated open-items
roll-up so nothing is tracked in only one buried doc.
- Repoint 5 code comments to the archived secure-desktop doc path.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
58 lines
3.3 KiB
Markdown
58 lines
3.3 KiB
Markdown
---
|
|
title: "GameStream Host"
|
|
description: "Stream to a stock Moonlight client on a client-sized virtual display."
|
|
---
|
|
|
|
> **Status:** SHIPPED — works end-to-end with a stock Moonlight/Artemis client (initial
|
|
> merge `ab6dda2`, June 2026). Code: [`crates/punktfunk-host/src/gamestream/`](../crates/punktfunk-host/src/gamestream/).
|
|
> Byte-level wire reference: [`research/gamestream-protocol-research.json`](research/gamestream-protocol-research.json)
|
|
> (distilled from Sunshine + moonlight-common-c). This doc is trimmed to design rationale +
|
|
> open items; the shipped code is the source of truth for wire/packet detail.
|
|
|
|
A stock Moonlight client discovers this host, pairs, launches, and gets video + input + audio
|
|
on a client-sized virtual display.
|
|
|
|
## Architecture (respects the "one core" invariant)
|
|
|
|
- **punktfunk-core** holds the **P1 GameStream wire codec** (`ProtocolPhase::P1GameStream`):
|
|
the RTP+`NV_VIDEO_PACKET` framing, the GameStream FEC shard layout, and the video/audio
|
|
AES-GCM/CBC paths. Hot path, native threads, **no async**. Kept beside punktfunk's native
|
|
internal format (P2), selected by phase.
|
|
- **punktfunk-host** holds the **control plane** (tokio/axum OK — I/O-bound, *not* the hot
|
|
path): mDNS discovery, nvhttp serverinfo + the 4-phase pairing, the RTSP handshake, the ENet
|
|
control stream + input injection, the virtual-display lifecycle, and Opus audio encode.
|
|
|
|
## Why we shipped in this order (the two highest interop risks)
|
|
|
|
These two mitigations are why early bring-up deliberately skipped crypto and FEC — both turn
|
|
out to be unnecessary on a clean LAN, and both have a wire-incompatibility that would have
|
|
silently broken interop if done naively.
|
|
|
|
1. **RS-FEC matrix incompatibility — clean-LAN first.** Sunshine + Moonlight both use
|
|
**nanors** (GF(2⁸), poly 0x11d, Vandermonde systematic). punktfunk-core uses
|
|
`reed-solomon-erasure` (Cauchy) — parity bytes **don't match**, so Moonlight silently fails
|
|
to recover any frame with a lost data shard. Mitigation: **on a clean LAN with no loss the
|
|
client never runs RS decode**, so we deferred it — get a frame decoded first, then port
|
|
nanors for loss recovery.
|
|
2. **Crypto layout incompatibility — plaintext video first.** punktfunk's `SessionCrypto`
|
|
(salt + seq-as-AAD) is wire-incompatible with GameStream's GCM; P1 needs a separate
|
|
GameStream GCM path (key = raw 16-byte RIKEY, IV = `counter_le[8]||0,0,0||'V'(0x56)`, **no
|
|
AAD**, **FEC first, then encrypt per shard**). Mitigation: **video encryption is negotiated
|
|
and usually off on LAN** — we implemented plaintext video first and added GCM later.
|
|
|
|
## Open items
|
|
|
|
- **HDR / 10-bit.** Needs HDR capture + metadata plumbing. (`av1_nvenc -highbitdepth 1`
|
|
already encodes Main10 from 8-bit input on this box.)
|
|
- **Reconnect-at-new-mode robustness.**
|
|
- **AV1 negotiation.** Implemented + unit/live-capture tested; needs a **live confirmation
|
|
with a stock Moonlight client** (select AV1 in a stock client).
|
|
- **Surround 5.1/7.1 audio.** Implemented + tested; needs a **real listen** including FEC
|
|
under loss, plus a live Moonlight confirmation.
|
|
|
|
## Testing note
|
|
|
|
The host is headless; end-to-end needs a **stock Moonlight client on the LAN** pointed at this
|
|
box (manual "add host" by IP works without mDNS). `/serverinfo` + the pair flow are testable
|
|
with `curl`; video needs a client that can display.
|