Files
punktfunk/crates
enricobuehler 677a4f4cf5 perf(gamestream): move FEC packetization off the encode loop (3-stage pipeline)
FEC/Reed-Solomon packetization ran inline on the encode loop (~3 ms/frame at 4K),
serializing behind encode and capping the GameStream frame rate below what the
encoder alone can sustain. Split it into a 3-stage pipeline, each stage on its own
thread joined by a depth-2 bounded queue:

  encode loop → [raw AUs] → packetizer (FEC/RS) → [wire batch] → paced sender

- `spawn_packetizer`: turns each `RawFrame`'s access units into wire datagrams via
  the stateful VideoPacketizer, off the encode loop. Above-normal priority (on the
  per-frame critical path). Tallies goodput (bytes to the wire) for the stats window.
- Backpressure chains up: a slow sender blocks the packetizer, which fills the
  encode→packetizer queue, which makes the encode loop drop the NEWEST frame — encode
  itself never waits.
- A dropped frame now consumes no client-visible frameIndex (packetization is
  downstream), so the host re-anchors the reference chain: a drop arms a keyframe on
  the next iteration (`recover_after_drop`), routed through the same coalesce gate as
  client IDR requests so a burst of drops (congestion) can't become an IDR storm.
- Perf/stats relabeled: `pkt` = AU drain, `send` = enqueue to the pipeline (both
  should be near-zero now; nonzero = encode being stalled by pipeline backpressure).
  Goodput read from the packetizer's atomic at the 1 s stats boundary.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 13:53:43 +00:00
..