Files
punktfunk/docs-site/content/docs/pyrowave.md
T
enricobuehler 3ff1973d7f
docker / deploy-docs (push) Successful in 11s
flatpak / build-publish (push) Successful in 6m25s
deb / build-publish (push) Successful in 9m7s
windows-host / package (push) Successful in 16m12s
deb / build-publish-host (push) Successful in 9m31s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 6m41s
ci / rust (push) Successful in 25m11s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 8m56s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 20m28s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 19m59s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 6m45s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 8m2s
apple / swift (push) Successful in 1m15s
release / apple (push) Successful in 9m36s
apple / screenshots (push) Successful in 6m43s
ci / web (push) Successful in 56s
ci / docs-site (push) Successful in 50s
android / android (push) Successful in 13m41s
decky / build-publish (push) Successful in 22s
arch / build-publish (push) Successful in 14m23s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 10s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 12s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 10s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 10s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 9s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 57s
ci / bench (push) Successful in 5m58s
feat(pyrowave): Apple Metal 4:4:4 + HDR decode, EDR present — self-configured in-band
Phases 4+5 of design/pyrowave-444-hdr.md. The Metal decoder needs NO new ABI:
every frame's sequence header carries chroma (444) and, since the Phase-3
stamps, the PQ/BT.2020 bits — so the decoder self-configures per session.

Decoder: WaveletLayout grows the 4:4:4 block space (chroma runs the full
pyramid like luma — no level-0 skip, no early half-res emit; the Metal
kernels were already chroma-agnostic, only the dispatch structure changes);
the parser accepts chroma_resolution=444, reads the PQ transfer bit, and
lifts the even-dims rule for 444; the plane ring allocates full-res chroma
and r16Unorm for PQ streams; CSC rows switch to depth-10 MSB-packed.

Presenter: planar HDR passthrough reuses pf_frag_planar on an rgba16Float
drawable (itur_2100_PQ + EDR metadata interpret the samples — same split as
pf_frag/pf_frag_hdr), plus a new pf_frag_planar_tm PQ->SDR tone-map (shared
pqToSdr tail refactored out of pf_frag_hdr_tv) for tvOS-without-headroom AND
macOS WINDOWED sessions, whose IOSurface present path (the DCP-panic
mitigation) is BGRA8-only. SessionModel stops stripping the HDR/10-bit/444
caps on the PyroWave opt-in.

New golden: au-dense444 + upstream's own 4:4:4 reference planes (regenerated
via the extended pyrowave_dump_golden); Metal decode matches at 64-67 dB
(420 fixtures re-verify 77-88 dB). Full Apple suite 157 tests green on a
real M-series GPU. Docs updated: the 8-bit-SDR-only wording is gone, the
Windows host is no longer 'on the roadmap', bpp scaling documented.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 13:21:23 +02:00

4.2 KiB
Raw Blame History

title, description
title description
PyroWave (wired-LAN codec) 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, 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 2040× keyframe spikes.

What it costs

Bandwidth. At the codec's ~1.6 bits-per-pixel operating point (4:2:0, 60 fps):

Mode Bitrate
1280×800 @ 60 (Deck) ≈ 100 Mbps
1920×1080 @ 60 ≈ 200 Mbps
2560×1440 @ 60 ≈ 355 Mbps
3840×2160 @ 60 ≈ 800 Mbps

120 Hz doubles these, 4:4:4 multiplies them by ~1.6, and an HDR (10-bit) session adds ~15 %. Gigabit Ethernet tops out around 940 Mbps of payload, so 4K60 wants 2.5GbE (or a lower rate). Do not run this over Wi-Fi — that's what HEVC/AV1 are for.

PyroWave follows the same 4:4:4 and HDR settings as HEVC/AV1: a session negotiates full-chroma 4:4:4 when your client's 4:4:4 setting is on, and HDR (BT.2020 PQ, carried in 16-bit planes) when the host's display pipeline is HDR — currently the Windows host only (the Linux host's capture path has no HDR source yet, so Linux-hosted sessions are SDR).

Turning it on

  1. Host (Linux): nothing to do — default builds ship the codec and every Linux GPU host advertises it. AMD/Intel hosts encode from the capture dmabuf zero-copy; on an NVIDIA host a PyroWave session currently captures via CPU RGB (a modest host-side cost that only affects sessions that picked this codec — everything else keeps its zero-copy path).
  2. Client:
    • Linux session client: set Settings → Video codec → PyroWave (wired LAN) in the gamepad console, or launch with PUNKTFUNK_PREFER_PYROWAVE=1.
    • 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 (including docked Deck) and Apple clients (native Metal decode on Mac / Apple TV 4K / iPad) today.
  • HDR needs a Windows host (the Linux host's capture path has no HDR source yet).