perf(latency): tier-0 attribution + tier-1 send-path levers from the latency plan
ci / web (push) Successful in 49s
ci / docs-site (push) Successful in 54s
decky / build-publish (push) Successful in 18s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 10s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 9s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 7s
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 8s
apple / swift (push) Successful in 1m23s
ci / rust (push) Failing after 4m15s
arch / build-publish (push) Failing after 4m35s
deb / build-publish (push) Failing after 4m4s
docker / deploy-docs (push) Successful in 24s
ci / bench (push) Successful in 5m35s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Failing after 3m45s
windows-host / package (push) Failing after 9m8s
release / apple (push) Successful in 5m49s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Failing after 5m25s
flatpak / build-publish (push) Failing after 8m3s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 3m58s
android / android (push) Successful in 14m9s
apple / screenshots (push) Successful in 6m28s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 7m0s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 9m28s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 12m26s

design/latency-reduction-2026-07.md T0.1/T0.2/T1.2/T1.3:

- T1.2 rate-capped front-loaded pacing: the paced overflow's budget is now
  min(0.9x slack, overflow wire time at ~3x the live encoder bitrate)
  (PUNKTFUNK_PACE_FACTOR, 0 = legacy deadline-only spread). A 300 KB-1 MB
  frame's tail leaves in ~2-5 ms instead of smearing across ~15 ms at 60 fps;
  GameStream schedule byte-identical (pins unchanged).
- T1.3 data-first wire order: packetize emits every block's data shards before
  any parity (per-block parity pools keep all blocks' parity alive for the
  second pass), so lossless completion stops waiting behind the parity tail.
  EOF = last emitted packet; receiver already order-agnostic.
- T0.1 staged 0xCF: HostTiming gains an append-extensible per-stage tail
  (queue/encode/pace us; seal+channel-wait derived as residual) - no cap bit
  needed, old peers read the 13-byte prefix. Joined client-side into
  Stats::host_{queue,encode,xfer,pace}_ms, the OSD detailed tier, and the
  probe's report.
- T0.2 true on-glass present timing: VK_KHR_present_id/present_wait enabled
  when supported; a PresentTimer waiter thread resolves each present id to
  real visibility, replacing the submit-time display stamp (which undercounts
  by up to a refresh and hides a silent-FIFO standing queue).

Validated on .21: core 185 + host 185 tests, pf-presenter 19, clippy
-D warnings across all five touched crates; loss-harness recovery curve
unchanged; C ABI harness round-trips.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-17 19:12:36 +02:00
parent c28b10a5b9
commit aedee2a4e3
15 changed files with 779 additions and 94 deletions
+83 -5
View File
@@ -370,16 +370,94 @@ fn e2e_roundtrip(
/// 100 bytes / 16 = 7 shards → blocks of (4 data + 2 rec) and (3 data + 2 rec).
#[test]
fn e2e_multiblock_loss_reorder_dup_gf16() {
// Packet order: blk0 = idx 0..6 (4 data + 2 rec), blk1 = idx 6..11 (3 data + 2 rec).
// Data-first wire order (T1.3): blk0 data = idx 0..4, blk1 data = idx 4..7,
// blk0 rec = idx 7..9, blk1 rec = idx 9..11.
// Kill 2 data in block 0 and 1 data in block 1 — all within the 50% budget.
e2e_roundtrip(FecScheme::Gf16, 100, 50, &[0, 2, 7], false);
e2e_roundtrip(FecScheme::Gf16, 100, 50, &[0, 2, 7], true);
e2e_roundtrip(FecScheme::Gf16, 100, 50, &[0, 2, 5], false);
e2e_roundtrip(FecScheme::Gf16, 100, 50, &[0, 2, 5], true);
}
#[test]
fn e2e_multiblock_loss_reorder_dup_gf8() {
e2e_roundtrip(FecScheme::Gf8, 100, 50, &[1, 3, 8], false);
e2e_roundtrip(FecScheme::Gf8, 100, 50, &[1, 3, 8], true);
e2e_roundtrip(FecScheme::Gf8, 100, 50, &[1, 3, 6], false);
e2e_roundtrip(FecScheme::Gf8, 100, 50, &[1, 3, 6], true);
}
/// T1.3 pin: the wire order is DATA-FIRST — every block's data shards in block order, then
/// every block's parity in block order — so the lossless-completion-gating packet (the last
/// data shard) never sits behind parity in the paced spread. SOF on the first emitted packet,
/// EOF on the last (a parity shard whenever the frame carries FEC).
#[test]
fn packetize_emits_all_data_before_any_parity() {
use zerocopy::FromBytes;
let cfg = e2e_config(FecScheme::Gf16, 50);
let coder = coder_for(FecScheme::Gf16);
let mut pk = Packetizer::new(&cfg);
// 100 B / 16 → 7 data shards → blocks (4 data + 2 rec) + (3 data + 2 rec).
let src: Vec<u8> = (0..100).map(|i| (i * 31 + 3) as u8).collect();
let pkts = pk.packetize(&src, 1, 0, coder.as_ref()).unwrap();
assert_eq!(pkts.len(), 11);
let hdrs: Vec<PacketHeader> = pkts
.iter()
.map(|p| PacketHeader::read_from_bytes(&p[..HEADER_LEN]).unwrap())
.collect();
// (block_index, shard_index) in emission order.
let layout: Vec<(u16, u16)> = hdrs
.iter()
.map(|h| (h.block_index, h.shard_index))
.collect();
assert_eq!(
layout,
vec![
(0, 0),
(0, 1),
(0, 2),
(0, 3), // blk0 data
(1, 0),
(1, 1),
(1, 2), // blk1 data
(0, 4),
(0, 5), // blk0 parity
(1, 3),
(1, 4), // blk1 parity
],
"data-first wire order"
);
// A shard is parity iff shard_index >= data_shards; no parity may precede any data.
let first_parity = hdrs
.iter()
.position(|h| h.shard_index >= h.data_shards)
.unwrap();
assert!(
hdrs[first_parity..]
.iter()
.all(|h| h.shard_index >= h.data_shards),
"no data shard after the first parity shard"
);
// Stream seqs stay strictly sequential in emission order (the nonce contract).
for (i, w) in hdrs.windows(2).enumerate() {
assert_eq!(w[1].stream_seq, w[0].stream_seq + 1, "seq gap at {i}");
}
assert_eq!(hdrs[0].flags & FLAG_SOF, FLAG_SOF, "SOF on first packet");
assert_eq!(
hdrs.last().unwrap().flags & FLAG_EOF,
FLAG_EOF,
"EOF on last (parity) packet"
);
assert_eq!(
hdrs.iter().filter(|h| h.flags & FLAG_EOF != 0).count(),
1,
"exactly one EOF"
);
// FEC-free frame: EOF falls on the last data shard instead.
let cfg0 = e2e_config(FecScheme::Gf16, 0);
let mut pk0 = Packetizer::new(&cfg0);
let pkts0 = pk0.packetize(&src, 2, 0, coder.as_ref()).unwrap();
assert_eq!(pkts0.len(), 7, "no parity at 0% FEC");
let last = PacketHeader::read_from_bytes(&pkts0.last().unwrap()[..HEADER_LEN]).unwrap();
assert_eq!(last.flags & FLAG_EOF, FLAG_EOF, "EOF on last data shard");
assert!(last.shard_index < last.data_shards, "last packet is data");
}
/// Zero losses, in order: the pure fast path (no codec call, recovered == 0) must still