Files
punktfunk/docs-site/content/docs/how-it-works.md
T
enricobuehlerandClaude Opus 5 d383161723
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
docs: the docs catch up with five releases of shipped work
~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>
2026-07-31 17:37:06 +02:00

4.8 KiB

title, description
title description
How It Works The ideas behind Punktfunk — per-client virtual displays, the two protocols, and trust.

You don't need to know any of this to use Punktfunk, but it helps to understand what's happening when you connect.

A virtual display, sized to your device

When a client connects, the host asks your desktop to create a new virtual display at exactly the client's resolution and refresh rate, captures that display, and streams it. The virtual display is real to your desktop — apps can be moved onto it, games open on it — but it isn't tied to any physical monitor. When the client disconnects, the virtual display goes away.

That's why a 1080p60 laptop and a 1440p120 desktop can stream from the same host at the same time, each at its own mode — they each get their own virtual display.

How the virtual display is created depends on your host:

Host How
GNOME (Mutter) A virtual monitor via the screen-cast API
KDE Plasma (KWin) A virtual output via KWin's screencast
Bazzite / Steam (gamescope) A nested gamescope session launched at the client's mode
Hyprland A headless output added with hyprctl, captured through xdg-desktop-portal-hyprland
Sway (wlroots) A headless output added to the running session
Windows A virtual-display driver — including Punktfunk's own indirect display driver the host pushes frames straight into — a real virtual display, no physical monitor, even on the secure desktop

That last one is the distinctive part on Windows: rather than only capturing an existing screen, Punktfunk has its own indirect display driver (IDD), and the host can push finished frames straight into the driver. You get the same on-the-fly virtual display the Linux compositors give you — at the client's exact mode, with no physical monitor or dummy HDMI dongle, and even on the secure desktop (UAC / lock screen). That tight, push-based integration is unusual among Windows streaming hosts.

From screen to GPU to wire

Captured frames never touch the CPU on their way to the encoder — a zero-copy GPU path that keeps latency low even at high resolutions and frame rates.

Which encoder runs depends on your GPU: NVIDIA → NVENC on both platforms; AMD → AMF and Intel → QSV on Windows. On Linux AMD and Intel share one path — Vulkan Video for HEVC and AV1, with VAAPI for H.264 and as the fallback when Vulkan encode isn't available. There's also a GPU-less software H.264 encoder: on Windows the host picks it when it finds no supported GPU, and on Linux you turn it on yourself (PUNKTFUNK_ENCODER=software, see Configuration).

Client and host then negotiate the codec: HEVC by default, AV1 where both sides support it, H.264 on the software path, and — if you pick it on a wired link — PyroWave, an intra-only wavelet codec that trades bandwidth for a fraction of a millisecond of codec latency. HDR (10-bit BT.2020 PQ) rides the same path where the host's capture, its encoder, the codec and your client all allow it; HDR has the four-link chain and what each host and client can really do.

Two protocols

Punktfunk speaks two protocols over the same host:

  • GameStream — the protocol Moonlight uses. Start the host with --gamestream and any Moonlight client connects with no special software. This is the most compatible way in.
  • punktfunk/1 (native) — a purpose-built protocol with a QUIC control channel and a UDP data channel hardened with forward error correction and encryption. It's lower-latency and more resilient on imperfect networks, and it's what the native clients (Apple, Linux, Windows, Android) use.

The native punktfunk/1 plane runs by default (the secure default); add --gamestream and both planes serve from a single host process — Moonlight clients use GameStream, the native clients use punktfunk/1.

Pairing and trust

The first time a device connects, you pair it: the host shows a short PIN, you type it into the client, and the two remember each other. After that the device reconnects automatically on a pinned cryptographic identity — no PIN, no account, no cloud. See Pairing & Trust.

Finding hosts

Hosts advertise themselves on your local network, so clients can discover them automatically instead of needing an IP address. The native clients and Moonlight both list hosts they find on the LAN.

Multiple devices at once

A host can stream to several clients simultaneously — your laptop and your TV both viewing (and controlling) the desktop, each at its own resolution. See Multiple devices.