ci / rust (push) Failing after 2m31s
ci / docs-site (push) Successful in 1m22s
ci / web (push) Successful in 1m48s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 1m1s
ci / rust-arm64 (push) Successful in 2m2s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 11s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 9s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 9s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 9s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 9s
docker / builders-arm64cross (push) Successful in 20s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Canceled after 36s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Canceled after 36s
docker / deploy-docs (push) Canceled after 0s
~1150 feat/fix commits landed since v0.19 and the docs drifted badly. This is a full sweep of every page against the code as shipped: ~280 verified corrections, nine new pages, and one deletion. The worst of what was wrong: the quickstart's five-minute path could not work (`serve` never started the web console, so step 3 had no PIN to read); every packaged Linux host runs `serve --gamestream` while security.md told readers to leave GameStream off; HDR was documented as Windows-only; `PUNKTFUNK_SECURE_DDA` was documented as a working knob that nothing reads; `PUNKTFUNK_INPUT_BACKEND` listed a `uinput` value that does not exist and named libei for KDE instead of kwin; README linked three pages deleted on 2026-07-05; and the rpm-ostree update command pointed at a script no package installs. Completeness: about half of what shipped since v0.19 had no page at all. New: support-matrix (what works where, from 217 verified capability cells), input (mouse/touch/pen — and the in-stream chords, so the docs finally say how to get your mouse back), client-settings, profiles-and-links, game-library, clipboard, wake-on-lan, hdr, uninstall. Updating existed but had zero inbound links. status.md is gone: its facts moved into the support matrix, its shell stays as a redirect so the public URL does not 404. roadmap.md is themes now, not a feature checklist — checkboxes are what rotted. Debian is no longer claimed. The .deb's Depends resolve against Ubuntu images, nothing in CI builds or tests Debian, and Debian 12 is below the glibc 2.39 floor. The `debian` in the repo URL is the package format. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
111 lines
6.4 KiB
Plaintext
111 lines
6.4 KiB
Plaintext
---
|
||
title: PyroWave (wired-LAN codec)
|
||
description: The opt-in ultra-low-latency wavelet codec for wired links — what it is, the bandwidth it needs, and how to turn it on.
|
||
---
|
||
|
||
PyroWave is an **opt-in** video codec mode for links that can afford real bandwidth: wired
|
||
Ethernet, a docked Steam Deck, a 2.5GbE LAN. It trades bitrate for latency — instead of
|
||
H.264/HEVC/AV1 on the GPU's video engine, frames are compressed with
|
||
[PyroWave](https://github.com/Themaister/pyrowave), an intra-only wavelet codec running as plain
|
||
Vulkan compute. Punktfunk vendors a pinned copy and runs it on both ends.
|
||
|
||
**It is never selected automatically.** HEVC/AV1 remain the codecs for Wi-Fi and everything
|
||
else; PyroWave engages only when *you* pick it on the client **and** the host supports it. If
|
||
either side can't, the session silently falls back to the normal codec ladder.
|
||
|
||
## Why you'd want it
|
||
|
||
- **Codec latency drops by an order of magnitude.** Encode and decode each take a fraction of a
|
||
millisecond of GPU compute (measured ~0.15 ms encode / ~0.07 ms decode at 1080p on an
|
||
RTX 5070 Ti), versus one-to-several milliseconds per side for the hardware H.26x pipelines.
|
||
- **Every frame is a keyframe.** There is no GOP, no reference chain, no keyframe round-trip
|
||
after packet loss — a lost frame costs exactly that frame, and the next one is already a
|
||
complete picture. The whole IDR/recovery apparatus that produces loss-time stutter simply
|
||
doesn't exist in this mode.
|
||
- **Uniform frame sizes.** The rate control hits its per-frame byte budget exactly, so the
|
||
pacer sees a flat load instead of 20–40× keyframe spikes.
|
||
|
||
## What it costs
|
||
|
||
Bandwidth. At the codec's ~1.6 bits-per-pixel operating point (4:2:0, SDR):
|
||
|
||
| Mode | Bitrate |
|
||
|---|---|
|
||
| 1280×800 @ 60 (Deck) | ≈ 100 Mbps |
|
||
| 1920×1080 @ 60 | ≈ 200 Mbps |
|
||
| 1920×1080 @ 120 | ≈ 400 Mbps |
|
||
| 2560×1440 @ 60 | ≈ 355 Mbps |
|
||
| 2560×1440 @ 120 | ≈ 710 Mbps |
|
||
| 3840×2160 @ 60 | ≈ 800 Mbps |
|
||
| 3840×2160 @ 120 | ≈ 1.6 Gbps |
|
||
|
||
Frame rate scales the rate linearly, [4:4:4](#444-and-hdr) multiplies it by ~1.6, and an
|
||
[HDR](#444-and-hdr) (10-bit) session adds ~15 %. Estimate any combination:
|
||
|
||
<BitrateCalculator />
|
||
|
||
Gigabit Ethernet tops out around 940 Mbps of payload, so 4K60 wants 2.5GbE and the big
|
||
4:4:4 / HDR / high-refresh modes want 5GbE or 10GbE. **Do not run this over Wi-Fi** — that's
|
||
what HEVC/AV1 are for.
|
||
|
||
## 4:4:4 and HDR
|
||
|
||
PyroWave carries **full-chroma 4:4:4** and **HDR** the same way it carries everything else —
|
||
intra-only, every frame a keyframe — so the low-latency and clean-loss properties above hold
|
||
in these modes too. Both are negotiated per session from your client's settings, exactly like
|
||
HEVC/AV1; nothing PyroWave-specific to turn on beyond picking the codec.
|
||
|
||
- **4:4:4 (full chroma).** With your client's **4:4:4** setting on, the session encodes chroma
|
||
at full resolution instead of subsampled 4:2:0 — sharp coloured text, thin UI lines, and
|
||
red/blue edges that 4:2:0 softens. It costs ~1.6× the bitrate (chroma compresses better than
|
||
luma, so it is less than the 2× the extra samples imply). Available on Linux and Windows
|
||
hosts.
|
||
- **HDR (10-bit, BT.2020 PQ).** With HDR on, the session carries the 10-bit BT.2020 PQ signal in
|
||
16-bit planes and adds ~15 % to the bitrate. **PyroWave HDR needs a Windows host today** — the
|
||
Linux PyroWave path has no HDR colour conversion, so a Linux-hosted PyroWave session is SDR; stay
|
||
on HEVC or AV1 for HDR from Linux, where PyroWave is the odd one out among the
|
||
[codec rules](/docs/hdr#codec-rules). 4:4:4 works with PyroWave on both.
|
||
- The two combine: a 4:4:4 **and** HDR session applies both factors (~1.6 × 1.15 ≈ 1.9× the
|
||
4:2:0 SDR rate). The Apple and Rust clients decode whatever the session negotiated — 4:2:0
|
||
or 4:4:4, SDR or HDR — with no extra setup.
|
||
|
||
At the top end this gets demanding: 4:4:4 + HDR at a super-ultrawide 5120×1440@240 pins around
|
||
5.3 Gbps, which is more than a 5GbE link carries. On a link that can't keep up, either set an
|
||
explicit lower bitrate on the client or cap the host's Automatic pin with
|
||
[`PUNKTFUNK_PYROWAVE_MAX_MBPS`](/docs/configuration) — otherwise the overshoot just becomes
|
||
dropped packets.
|
||
|
||
## Turning it on
|
||
|
||
1. **Host** (Linux): nothing to do — default builds ship the codec and every Linux GPU host
|
||
advertises it. AMD, Intel and NVIDIA hosts all encode straight from the capture dmabuf: the
|
||
wavelet encoder owns its own Vulkan device and imports the buffer on any vendor, so there is
|
||
no CPU copy on the host. (A compositor that refuses every offered dmabuf format still falls
|
||
back to the CPU path, as it does for the other codecs.)
|
||
2. **Client**:
|
||
- Linux client: set **Settings → Video codec → PyroWave (wired LAN)** — the same setting in
|
||
the GTK desktop app and in the full-screen controller UI. Or launch with
|
||
`PUNKTFUNK_PREFER_PYROWAVE=1`.
|
||
- Windows client: set **Settings → Video codec → PyroWave (wired LAN)** (Intel, AMD and
|
||
NVIDIA alike; x64 only — the ARM64 build does not include the decoder).
|
||
- Apple (Mac, Apple TV 4K, iPad — wired networking strongly recommended): set
|
||
**Settings → Codec → PyroWave (wired LAN)**. The option appears only on devices whose
|
||
GPU passes the decode probe (Apple Silicon and A13-class or newer). The decoder follows
|
||
the stream: 4:2:0 or 4:4:4, SDR or HDR, per what the session negotiated.
|
||
3. Leave the bitrate on Automatic: a PyroWave session pins itself to the ~1.6 bpp rate for
|
||
your mode (≈200 Mbps at 1080p60; ~2.6 bpp for 4:4:4, +15 % for HDR). An explicit bitrate is honored if you set one, but the
|
||
adaptive-bitrate controller stays off either way — this codec has no useful low-rate
|
||
regime, so under sustained loss the right move is switching back to HEVC, not degrading.
|
||
The pin follows the resolution: a mid-stream resize (e.g. Match window) re-pins the rate
|
||
for the new mode, so resizing a window down also cuts the bandwidth.
|
||
|
||
The stats overlay shows `pyrowave` as the decode path when the mode is active.
|
||
|
||
## Current limits
|
||
|
||
- Linux and Windows hosts; Linux clients (the GTK desktop app and the session client, including
|
||
a docked Deck), the Windows client on x64, and Apple clients (native Metal decode on Mac, and on
|
||
A13-or-newer iPhone, iPad and Apple TV hardware) today. Android has no PyroWave decoder.
|
||
- **PyroWave HDR needs a Windows host today** — a Linux-hosted PyroWave session is SDR, however the
|
||
rest of the box is set up (see [4:4:4 and HDR](#444-and-hdr) above). 4:4:4 works on both.
|