Files
punktfunk/clients/probe
enricobuehler a2433d77cf
ci / web (push) Successful in 50s
ci / docs-site (push) Successful in 53s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 10s
decky / build-publish (push) Successful in 19s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 10s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 9s
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 9s
ci / bench (push) Successful in 5m35s
docker / deploy-docs (push) Successful in 25s
arch / build-publish (push) Successful in 11m22s
android / android (push) Successful in 14m48s
deb / build-publish (push) Successful in 14m45s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 15m12s
ci / rust (push) Successful in 18m20s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 13m11s
flatpak / build-publish (push) Successful in 5m59s
windows-host / package (push) Successful in 8m3s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 3m47s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 4m27s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 5m6s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 5m52s
apple / swift (push) Successful in 5m12s
release / apple (push) Successful in 26m35s
apple / screenshots (push) Successful in 19m28s
fix(core): reordering no longer reads as packet loss — net late shards out of the loss estimate
Reversed/reordered delivery lets a FEC block reconstruct EARLY
(data + recovery >= k), counting still-in-flight shards into
fec_recovered_shards; window_loss_ppm then reported pure reordering as
loss, inflating LossReports — which size adaptive FEC and, since the
Automatic overhaul, feed the ABR controller (one severe window ends slow
start FOR GOOD, so a reorder burst could permanently kneecap a session's
climb).

Early reconstruct stays (it's the latency-right choice); the accounting
now nets it out. The reassembler counts a new fec_late_shards stat when a
parity-restored data shard ARRIVES after all — matched exactly: the
completed/abandoned-frame memory (ReassemblyWindow::completed, now a map)
remembers which shards each terminal frame reconstructed, and a late
arrival must match one (removed on hit), so wire duplicates of delivered
shards and stragglers of failed blocks count nothing. In-flight blocks
dedup via have_data. window_loss_ppm takes the late delta and estimates
from (recovered - late), saturating across window boundaries; both
callers (client core + probe) pass it.

The e2e reorder tests now assert the NET equals the true kill count in
both delivery orders, dup included (previously documented as a known
inflation). Not mirrored into the C-ABI PunktfunkStats — the loss windows
run in-core on every platform.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 20:59:17 +02:00
..

punktfunk — probe (reference client)

punktfunk-probe is the headless reference client for the punktfunk/1 protocol — a command-line tool for testing, latency measurement, and validating host behavior. It's not a streaming app you'd watch on; it connects, exercises a plane, and reports numbers. If you want to actually stream, use the Linux, Windows, Apple, or Android clients.

Because it links the same punktfunk-core as every other client, it's also the canonical example of driving the protocol end to end: QUIC control plane, UDP data plane, and the side planes (input, audio, rumble) over QUIC datagrams.

What it does

  • Receives a real stream, writes a playable elementary stream (.h265/.h264/.av1 — the extension tracks the negotiated codec; the probe advertises all three and the host picks), and reports per-frame capture→received latency percentiles (the host stamps each frame with its capture clock).
  • Verification mode against a synthetic host — byte-checks deterministic test frames.
  • Exercises every plane with scripted test traffic: --input-test (mouse/keyboard), --mic-test (a 440 Hz Opus tone up to the host mic), --touch-test (a synthetic finger), --rich-input-test (DualSense touchpad + motion, logging the HID-output feedback that comes back).
  • Trust--pin <64-hex> pins the host fingerprint; --pair <PIN> runs the SPAKE2 pairing ceremony and prints the verified fingerprint to pin from then on. Without a pin it trusts on first use.
  • Discovery--discover [secs] browses the LAN for _punktfunk._udp hosts and prints each (name, addr:port, pairing requirement, cert fingerprint), then exits.
  • Negotiation knobs--mode WxHxFPS, --remode (mid-stream mode change), --bitrate, --codec auto|h264|hevc|av1 (preference; the host resolves), --audio-channels (stereo / 5.1 / 7.1), --compositor, --gamepad, --launch, --speed-test. Env: PUNKTFUNK_CLIENT_10BIT=1 / PUNKTFUNK_CLIENT_444=1 advertise the 10-bit / 4:4:4 client caps (for testing a host's PUNKTFUNK_10BIT/PUNKTFUNK_444).

Usage

# stream 720p120 from a host, save the video, and print latency percentiles:
cargo run -p punktfunk-probe -- --mode 1280x720x120 --connect HOST:PORT --out /tmp/a.h265

# list hosts on the LAN:
cargo run -p punktfunk-probe -- --discover

# pair with a host that requires it (read the PIN off the host), then stream:
cargo run -p punktfunk-probe -- --connect HOST:PORT --pair 1234
cargo run -p punktfunk-probe -- --connect HOST:PORT --pin <64-hex> --input-test

Full flag reference is in the module doc-comment at the top of src/main.rs.

  • Project README — the host, the streaming clients, and the protocol
  • punktfunk-host punktfunk1-host — the persistent native-protocol listener to probe against (see the "Running on this box" section of the repo README / CLAUDE.md)