PunktfunkPunktfunk
Streaming

PyroWave (wired-LAN codec)

The wavelet codec for wired links — near-zero codec latency for a bitrate you set in bits per pixel.

PyroWave is an opt-in video codec for wired links. Every frame is a complete picture, compressed with a wavelet transform in Vulkan compute (upstream). It encodes and decodes in a fraction of a millisecond, and pays for that with far more bandwidth than HEVC or AV1.

Punktfunk never picks it for you. It runs when you choose it on the client and the host supports it; otherwise the session uses the normal codecs. Setting the host's Encoder to PyroWave chooses it for every client whose Video codec is on automatic and that can decode it.

Why use it

  • Codec latency almost disappears. Encode takes ~0.15 ms and decode ~0.07 ms at 1080p on an RTX 5070 Ti. Hardware HEVC takes one to several milliseconds on each side.
  • A lost packet blurs a small patch of one frame. No frame depends on another, so there is no keyframe request and no stutter while the stream recovers. Only each frame's coarsest layer, whose loss would show, carries recovery data.
  • Every frame is the same size. The network sees a steady load instead of keyframe bursts.

Setting it up

Host: Linux hosts (AMD, Intel and NVIDIA) and x64 Windows hosts support it with nothing to install. Windows on Arm hosts don't.

Client: set Video codec to PyroWave (wired LAN).

ClientNeeds
Linux (desktop app, controller UI, Steam Deck)—
Windowsx64
Mac, iPhone, iPad, Apple TVApple silicon, or A13 and newer
Android64-bit, Vulkan 1.3 GPU

The Apple and Android apps and the controller UI list it only when the device can decode it. A session whose host or device can't run it falls back to HEVC. The stats overlay names PyroWave as the codec while it runs.

From a Moonlight client

A host that supports PyroWave also offers it to Moonlight forks that support it: pick it in the fork's codec setting.

  • The fork's bitrate sets the rate, up to the largest frame a Moonlight stream can carry. That limit binds at 60 fps and high bitrates.
  • 4:4:4 needs Full color 4:4:4 on in the host settings. The host refuses a 4:4:4 request it can't serve, 8K-class modes included, because the fork can't decode 4:2:0 instead.

Bits per pixel

PyroWave has no quality setting of its own: its encoder fills each frame's byte budget exactly. Punktfunk sets that budget in bits per pixel, so one number means the same picture at every resolution and frame rate.

Set it on the client under PyroWave quality, 0.5 to 2, shown as the rate it needs at your stream's mode (Client settings). For a client without that row, set the host's value in the web console under Host → Video → PyroWave quality, or with PUNKTFUNK_PYROWAVE_BPP in host.env: 0.25 to 4, from the next session. The client's Bitrate then offers Automatic or Fixed: Fixed streams at the quality, and with Automatic the quality is the most a session uses (Fitting the link).

The default is 1.6, the codec author's clean point: at 200 Mbps for 1080p60 he could not spot compression artifacts without comparing side by side and zooming in.

Mode (4:2:0, 8-bit)At 1.6 bits/pixel
1280×800 @ 60 (Steam Deck)≈ 100 Mbps
1920×1080 @ 60≈ 200 Mbps
1920×1080 @ 120≈ 400 Mbps
2560×1440 @ 120≈ 710 Mbps
3840×2160 @ 60≈ 800 Mbps
3840×2160 @ 120≈ 1.6 Gbps

These are what the link carries, recovery data and packet headers included.

Lower values work and look softer: fewer bits never break the stream. PyroWave sends every frame whole and keeps its coding simple for speed, which costs the most at low bitrates. Text, thin UI lines and texture go soft first, and hard edges ring. For scale, Steam Remote Play's PyroWave tops out at 500 Mbit/s, which at 4K120 is 0.5 bits per pixel.

1.60
≈ 199 Mbps
415 KB per frame
Gigabit
1.60 bits/pixel
2.5 GbE
1.60 bits/pixel
5 GbE
1.60 bits/pixel
10 GbE
1.60 bits/pixel

Each bar is what an Automatic session keeps on that link. A link that can't carry the rate with room to spare gets 70 % of what it delivered in the test before the first frame. Link figures assume a payload ceiling a bit under line rate.

4:4:4 and HDR

Both follow the client's settings, as with HEVC and AV1, and scale your bits per pixel:

  • 4:4:4 (full chroma, sharp coloured text): ×1.625, so 2.6 at the default.
  • 10-bit and HDR (BT.2020 PQ): +15 %. On Linux, HDR needs a punktfunk-gamescope session.

Together, 4:4:4 HDR at the default is ~3.0 bits per pixel.

Before the first frame the client tests the link. If it can't carry the rate with room to spare, the session starts at 70 % of what the link delivered, so 4K120 on Gigabit still streams at fewer bits per pixel.

With the client's bitrate on Automatic, the default, PyroWave then adapts like the other codecs: bits per pixel follow the link between 0.5 and PyroWave quality, dropping under loss and climbing back when the link recovers. Held at 0.5 for three seconds, the stats overlay says the network is weak and that HEVC would look better on this link. With Bitrate on Fixed the session stays at the rate the test left.

To hold every session under a fixed rate, set PyroWave bitrate cap (under Show advanced, PUNKTFUNK_PYROWAVE_MAX_MBPS, 0 for no cap).

Checking a Linux host is zero-copy

The host logs which capture path a session took, once:

capture pipeline resolved: dmabuf-passthrough → pyrowave

dmabuf-passthrough is zero-copy. cpu means every frame is copied, which lowers the frame-rate ceiling and raises CPU use; the warning after it names the cause, such as PUNKTFUNK_ZEROCOPY set to 0 or a compositor that would not hand over a dmabuf.

Limits

  • Wired links only. Wi-Fi can't carry these rates; use HEVC or AV1 there.
  • No decoder in the Windows ARM64 client or the 32-bit Android build.
  • The host accepts up to 8 Gbps, so 2.5, 5 and 10 GbE links get used.

On this page