docs(apple): pickup-ready stage-2 presenter implementation plan
ci / rust (push) Has been cancelled

Stage-2 was a one-line "next" in the README. Add a full, actionable spec
(docs-site apple-stage2-presenter.md) a Mac agent can execute: VTDecompressionSession
decode (with decode-completion stamping) -> CAMetalLayer + display-link present, the
exact integration points against the existing StreamPump/StreamView/AnnexB/LatencyMeter,
the three-stage measurement wiring (capture->decoded / decode->present / capture->present
= glass-to-glass, using the already-wired PunktfunkConnection.clockOffsetNs), a cheaper
decode-only intermediate, validation, and gotchas. Link it from the Apple README's
Stage 2 item. (meta.json nav entry left in the working tree to land with the CI docs WIP.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-12 12:21:08 +00:00
parent bdcc88f5fc
commit 7f234420c7
2 changed files with 128 additions and 3 deletions
+6 -3
View File
@@ -167,9 +167,12 @@ signing, bundle id `io.unom.punktfunk`. Notes:
and recovery keyframes re-send them — "refresh the format description on every IDR"
(what `StreamView` does) is sufficient; there is no out-of-band extradata, ever.
4. **Stage 2 (next)**: explicit `VTDecompressionSession` + `CAMetalLayer` for frame-pacing
control (ProMotion/120 Hz), glass-to-glass measurement via `tools/latency-probe` (the
host stamps `pts_ns` with its capture wall clock; across machines you need a clock
offset estimate from the QUIC RTT).
control (ProMotion/120 Hz) and true decode→present / glass-to-glass measurement. The
cross-machine clock offset is **already wired**`PunktfunkConnection.clockOffsetNs` (from
the connect-time skew handshake); add it to a `CLOCK_REALTIME` present instant and subtract
the AU `pts_ns`. **Full pickup-ready implementation plan** (decode + present + measurement
wiring, integration points, gotchas): `docs-site/content/docs/apple-stage2-presenter.md`
(rendered in the docs site under "Apple Stage-2 Presenter").
5. **Audio — wired, both directions.** Playback: `SessionAudio` drains `nextAudio()`
on its own thread, decodes through CoreAudio's built-in Opus codec (`OpusCodec.swift`
— kAudioFormatOpus, no bundled libopus; round-trip unit-tested) into a priming