Files
punktfunk/docs-site/content/docs/roadmap.md
T
enricobuehler dcde856178 feat(pad-audio): Linux hosts stream pad audio — the per-pad PipeWire sink (WP3)
The 0xD1 plane was Windows-host-only: host_cap() answered false and spawn()
was a stub everywhere else, so an Android tier-A client against a Linux host
negotiated the cap off and stayed on wire rumble. The whole downstream
machinery (framer, silence gate, lanes, 0xD1 send) was already capture-
agnostic — only the capturer was WASAPI.

- audio/linux/pad_sink.rs: one Audio/Sink stream node per DualSense-family
  pad, minted with the identity the matchers read (ALSA-style node.name with
  the pad's pairing MAC, description "Wireless Controller", bus/vendor/
  product/form-factor proplist, per-pad serial), 4-ch F32 48 kHz FL FR RL RR,
  no default-sink claim, priority.session 50. The process() callback IS the
  capture. PUNKTFUNK_PAD_SINK_NAME/_DESC override the strings for field
  debugging ({pad}/{mac} expand).
- native/pad_audio.rs: the shared logic and lanes compile on Linux;
  pad_audio_thread is generic over the capturer (open-with-backoff kept);
  host_cap() Linux arm = client asked + PUNKTFUNK_PAD_AUDIO + a reachable
  PipeWire socket; spawn() Linux arm mints the sink lazily in the streamer
  thread. spawn() gains an edge flag (Edge identity; ignored on Windows).
- devtest pad-sink-test: mint one sink and capture from it, no client — the
  WP3 on-glass gate. Verified on a Bazzite 44 host: identity served through
  pipewire-pulse, rear-pair (voice-coil) tone captured bit-exact over both
  the native and pulse legs.
- docs: PUNKTFUNK_PAD_AUDIO{,_SLOTS} are no longer (Windows); the roadmap
  non-goal narrows to Bluetooth client pads.

Gates (fedora:44 container, natively on the .41 box): cargo build --release
--locked (nvenc+vulkan-encode), clippy --all-targets -D warnings, cargo test
pad_audio+pad_sink 11/11, cargo fmt.
2026-08-12 18:53:35 +02:00

104 lines
6.9 KiB
Markdown

---
title: "Roadmap"
description: "Where Punktfunk is heading — the themes being worked on now, what comes after them, and what is deliberately not planned."
---
This page is about **intent**, not inventory. It says what the project is pushing on and why, in
themes rather than checkboxes, because a checklist of forty features is stale the week it is written.
Three other pages answer the questions people usually bring to a roadmap, and they answer them
better:
- **"Does it do X on my machine?"** — the [Support matrix](/docs/support-matrix). Every cell there
was read out of the code that makes the decision. It is the arbiter: where this page and the
matrix disagree, the matrix is right.
- **"What changed recently?"** — the [release notes](https://git.unom.io/unom/punktfunk/releases),
per version.
- **"How finished is this?"** — [How finished each part is](/docs/support-matrix#how-finished-each-part-is).
**Nothing on this page is shipped unless it says so.** Recently shipped work — pen and stylus input,
mirroring one of the host's real monitors, a stream that ends when the game does, settings profiles
and `punktfunk://` links, the `punktfunk` command line, HDR on gamescope hosts, and update checks
with one-click host updating — is described in the release notes for 0.19 through 0.22.3, and its
present-day behaviour is in the matrix.
## Working on now
**Windows host hardening.** The Windows host is the newest large surface in the project and gets the
most attention. Two strands: on-glass validation of the AMD (AMF) and Intel (QSV) encode paths,
which are CI-green but far less exercised than NVENC; and capture-stall attribution — the host now
carries dedicated instrumentation that says *which* link went quiet when a stream stutters — the
content that stopped being drawn, or the display path that stopped presenting it — so field reports
stop being guesswork.
**Latency under load.** The remaining wins are no longer in the encoder. They are in when a frame is
handed to the display: client-side presentation phase control, keeping a decoded frame from waiting
out a refresh interval it did not need to, and holding the frame rate when the link degrades rather
than de-escalating and staying degraded. The next structural lever is **sub-frame pipelining**
overlapping encode and transmit inside a single frame via a direct slice path — which matters most
at high resolutions.
**Finishing the clipboard.** Text crosses today from a Windows, macOS or Android client to a host
whose operator turned the feature on, with images on the first two. Two pieces are genuinely
unfinished: the **Linux client's** side of the bridge is a stub, so a Linux client offers and
applies nothing; and **file transfer** has a wire format and a host-side policy but no client that
offers files, so a copied file never crosses. See [Clipboard](/docs/clipboard).
**Console parity with the apps.** The web console still cannot run a speed test or set a bitrate —
it shows the bitrate a live session is using and stops there, while the client apps can measure the
link and act on the result.
**Closing the unverified cells.** The matrix's [What is not
verified](/docs/support-matrix#what-is-not-verified) list is a work list, not a disclaimer: a
Hyprland virtual output on real display hardware, client-drawn cursors on sway/wlroots and Hyprland,
gamescope headless capture on the proprietary NVIDIA driver, touch input from a Windows client. Most
are settled by a single session log on the right machine.
## Next
**Reach beyond the LAN.** Today a client and host have to be on the same network. The intent is NAT
traversal (ICE/STUN/TURN) with a self-hostable relay for when no direct path can be punched, plus
QUIC connection migration so a client roams between Wi-Fi and cellular without dropping the session.
The control plane is already QUIC over UDP, so this is mostly signalling and relay rather than a
protocol change.
**A host that knows who is connecting.** Two related pieces. *Per-user sessions*: a connecting
client picks an identity — an Apple TV profile, say — which maps to a real account on the host, and
that person lands in their own desktop, signed in, without touching the machine. And *gamescope
multi-user isolation*: per-session input and audio, so concurrent clients are fully independent
desktops rather than several views of one (the shared-desktop case already works).
**The rest of remote work.** Multi-monitor streaming (the host's several outputs as separate client
windows), virtual-webcam redirection (the client's camera appears as a webcam on the host, so video
calls run on the remote machine), and peer-approved pairing (approve a new device from an
already-paired device's own app, rather than only from the web console). Each is a new side plane
over the QUIC channel that already exists.
**Picture and sound frontier.** End-to-end variable refresh — the host rendering at a variable rate
and the client presenting with tearing control instead of a fixed cadence (the Apple client already
varies its own display link; the host half does not exist). True glass-to-glass latency measured
capture-to-present rather than capture-to-receipt. And object-based spatial audio: capturing game
audio objects on native Windows is blocked by a closed renderer API, but Proton already routes them
through Wine's `ISpatialAudioClient`, where the dynamic objects and their positions are currently
discarded — finishing that, and tunnelling objects plus positions to the client, would give
head-tracked remote spatial audio that no streaming stack does today.
## Not planned, or blocked upstream
- **HDR on Mutter, KWin and wlroots virtual displays.** Those compositors' virtual-monitor
screencasts are SDR-only upstream, through the GNOME 51 development branch. The host is ready the
moment that changes. gamescope's virtual output and the GNOME 50+ real-monitor mirror are the two
Linux routes that do carry HDR today — see [HDR](/docs/hdr) and the
[matrix](/docs/support-matrix#input-cursor-and-hdr).
- **Hosting on macOS, iOS, tvOS or Android.** Client-only platforms by construction: every host
entry point fails at compile time. There is no setting that changes this.
- **HEVC 4:4:4 on the AMD encode block.** AMD's VCN never encodes 4:4:4, so there is nothing to
implement. Intel is a different story and *is* a gap rather than a wall — the VAAPI backend
simply has no 4:4:4 path yet, and it waits on hardware that advertises a HEVC 4:4:4 encode
entrypoint to build and validate against. On either vendor, [PyroWave](/docs/pyrowave) already
carries full chroma today.
- **DualSense voice-coil haptics over Bluetooth client pads.** The controller exposes no audio
interface over Bluetooth, so the audio-haptics plane is USB-only on the client side — a BT
DualSense keeps classic rumble. (Hosts stream pad audio on both Windows and Linux; rumble,
adaptive triggers and the lightbar work everywhere regardless.)