Files
punktfunk/crates/punktfunk-host
enricobuehlerandClaude Opus 4.8 0e7f6d85d6
ci / web (push) Successful in 1m14s
apple / swift (push) Successful in 1m20s
ci / docs-site (push) Successful in 1m20s
decky / build-publish (push) Successful in 20s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 9s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 8s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 8s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 7s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 8s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 10s
ci / bench (push) Successful in 6m41s
apple / screenshots (push) Successful in 6m12s
deb / build-publish (push) Successful in 9m48s
docker / deploy-docs (push) Successful in 25s
deb / build-publish-host (push) Successful in 10m26s
windows-host / package (push) Successful in 16m13s
android / android (push) Successful in 16m27s
arch / build-publish (push) Successful in 17m20s
ci / rust (push) Successful in 20m1s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 20m43s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 19m41s
feat(gamestream): signal HDR mode to the client via the 0x010e control message
punktfunk negotiates HDR correctly (the stream is BT.2020 PQ 10-bit) but never
told the client to switch its display into HDR picture mode, so HDR streams
stayed in SDR on the TV. Sunshine sends an async control-stream message
(IDX_HDR_MODE, type 0x010e, carrying SS_HDR_METADATA) shortly after the stream
starts; Moonlight only flips the TV into HDR on that cue. We sent exactly one
host→client control message (rumble 0x010B) and never this one. (aurora-tv PR
#53 worked around it client-side by inferring HDR from the negotiated format;
this fixes it host-side so stock Moonlight clients switch too.)

Once the control stream is live and the session negotiated HDR, send a one-shot
0x010e message (enable + 26-byte SS_HDR_METADATA from generic HDR10 defaults),
latched per connection and re-armed on Disconnect. The rumble sequence counter
is unified into a single monotonic `host_seq` shared by both message types —
the GCM nonce derives from `seq`, so a separate per-type counter would reuse
(key, nonce) pairs in the host direction.

The BT.2020 PQ VUI already rides the bitstream (the encoder derives it from the
P010 capture format), so this is purely the missing "switch now" signal; no
encoder change needed. Wire layout locked by unit tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 21:35:16 +02:00
..

punktfunk-host

The streaming host — the program you run on the machine whose desktop or games you want to stream. For each client that connects, it spins up a virtual display sized to that device, captures it on the GPU, encodes with hardware NVENC/VAAPI/AMF/QSV, and sends it out over a low-latency transport — no physical monitor, no letterboxing, no rearranging your real screens.

It speaks two protocols from one process:

  • GameStream — so any Moonlight / Artemis client works day one.
  • punktfunk/1 — punktfunk's own faster protocol (QUIC control plane, GF(2¹⁶) FEC + AES-GCM data plane) that the native clients use.

Runs on Linux (the primary, most battle-tested path) and Windows (x64). The shared protocol, FEC, and crypto live in punktfunk-core; this crate is everything platform-facing around it.

What it does

  • Per-client virtual displays at the exact WxH@Hz. Linux uses per-compositor backends — KWin, gamescope, Mutter, and Sway/wlroots; Windows uses its own all-Rust IddCx virtual display, even on the secure desktop (UAC / lock screen).
  • GPU zero-copy capture → encode. dmabuf → CUDA/Vulkan → NVENC on Linux; on Windows the host pushes frames straight into its own IDD (sealed IDD-push, no screen-scraping) → GPU encode. Encoders auto-select by GPU vendor: NVENC (NVIDIA), VAAPI (Linux AMD/Intel), AMF/QSV (Windows AMD/Intel), or software H.264 as a floor. HDR/10-bit and HEVC 4:4:4 supported.
  • Input injection. Mouse/keyboard (libei / gamescope EIS / wlr / Windows SendInput) and virtual gamepads — Xbox 360/One, DualSense, DualShock 4 — with rumble and HID feedback back-channels.
  • Audio both ways. Opus audio host→client, plus a virtual microphone the client can talk into.
  • Trust & discovery. A persistent host identity, SPAKE2 PIN pairing (default) or TOFU, and mDNS auto-advertisement so clients find the host without typing an IP.
  • Management API + web console. A REST API (mgmt.rs, OpenAPI at api/openapi.json) drives status, paired devices, and on-demand pairing; the browser UI is in web/.

Run it

punktfunk-host serve runs inside your desktop session. Bare serve is the secure native-only default (punktfunk/1 + the management API); add --gamestream on a trusted LAN to also accept stock Moonlight clients.

# Linux, from the repo root (see the repo README "Running on this box" for the headless recipe):
cargo run -rp punktfunk-host -- serve                 # native-only (secure default)
cargo run -rp punktfunk-host -- serve --gamestream    # + Moonlight compatibility

Then pair from the web console (https://<host-ip>:47992) or the client app.

Most people should install a package rather than run from source — see packaging/ (apt · rpm/COPR/bootc · Arch/sysext · Windows installer) and the per-platform guides at docs.punktfunk.unom.io/docs/install.

Subcommands

Command Purpose
serve The host (native punktfunk/1 + mgmt API; --gamestream adds Moonlight).
punktfunk1-host Standalone native-protocol listener for testing/measurement (--source virtual, --max-sessions).
openapi Print the management-API OpenAPI spec (regenerates api/openapi.json).
library Inspect the multi-store game library.
service · driver · web Windows: SCM service, driver install, bundled web console.
*-test / *-selftest / *-probe Diagnostics (input, zero-copy, HDR, compositor, gamepads).

--help lists them all.

Layout

src/
  main.rs            CLI + subcommand dispatch
  config.rs · session_plan.rs · session_tuning.rs · pipeline.rs   session setup + the frame pipeline
  vdisplay/          per-compositor virtual outputs (kwin · gamescope · mutter · wlroots)
  capture/ · capture.rs    screen/dmabuf capture (+ Windows IDD-push)
  encode/ · encode.rs      per-GPU encoders (nvenc · vaapi · ffmpeg_win (AMF/QSV) · sw)
  linux/zerocopy/    dmabuf → CUDA → NVENC bridges (EGL/GL tiled, Vulkan LINEAR)
  inject/ · inject.rs      input backends (libei · wlr · uinput gamepads · UHID DualSense/DS4)
  audio/ · audio.rs        Opus out + virtual mic (PipeWire / WASAPI)
  gamestream/        Moonlight compat: nvhttp · pairing · rtsp · control · stream · gamepad · apps
  native.rs      the native punktfunk/1 host (QUIC control + native-thread UDP data plane)
  mgmt.rs · native_pairing.rs · stats_recorder.rs   management API, pairing, perf capture
  hdr.rs · library.rs      HDR metadata; multi-store game library
  linux/ · windows/  platform-confined backends
  • punktfunk-core — the shared protocol · FEC · crypto core
  • Clients — the apps that connect (Apple · Linux · Windows · Android · probe)
  • Packaging & docs — install & operate
  • punktfunk-planning (internal planning repo) — architecture rationale and deep-dive plans