test(pf-vkdecode): diff a field capture against ffmpeg, frame by frame #461
Merged
enricobuehler
merged 6 commits from 2026-08-30 23:36:49 +00:00
worktree-vkdecode-field-parity into main
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
7db513683d |
Merge main, keeping this branch's App::status() accessor
apple / swift (pull_request) Successful in 2m14s
apple / distribute (pull_request) Skipped
apple / screenshots (pull_request) Skipped
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (pull_request) Successful in 6m36s
android / android (pull_request) Canceled after 0s
ci / rust (pull_request) Canceled after 0s
ci / rust-arm64 (pull_request) Canceled after 0s
ci / web (pull_request) Canceled after 0s
ci / docs-site (pull_request) Canceled after 0s
ci / bun-nix (pull_request) Canceled after 0s
ci / docs-drift (pull_request) Canceled after 0s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (pull_request) Canceled after 0s
Both this branch and #460 fixed the same abort, independently and within the hour. #460 merged first, patching four call sites inline; this one routes all five through one `App::status()`, which is the better shape and also covers the writer in `run()` that the inline pass left alone. Conflict resolved to this branch for `win.rs`. Afterwards the file holds exactly one `lock()` — inside the accessor — so every reader goes through it. `check-unsafe-hygiene.sh` reports all three gates clean and rustfmt is clean under the pinned 2021 style edition. |
||
|
|
1ec673add8 |
fix(tray): a poisoned status lock stops aborting the tray process
ci / bun-nix (pull_request) Successful in 41s
ci / docs-drift (pull_request) Successful in 43s
ci / docs-site (pull_request) Successful in 1m5s
ci / web (pull_request) Successful in 1m23s
ci / rust-arm64 (pull_request) Successful in 1m59s
apple / swift (pull_request) Successful in 2m15s
apple / distribute (pull_request) Skipped
apple / screenshots (pull_request) Skipped
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (pull_request) Successful in 6m45s
ci / rust (pull_request) Failing after 7m32s
android / android (pull_request) Successful in 8m44s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (pull_request) Successful in 3m6s
`ci / rust` has been red on main: gate B of check-unsafe-hygiene.sh flags `.unwrap()` on the status mutex inside `wndproc`, and it is right to. A panic crossing an `extern "system"` boundary does not unwind, it ABORTS the process — so a thread that panicked while holding this lock would take down the host's only visible surface, on a box where the icon is also how the operator stops the host. Poisoning is not a reason to do that here. What the mutex guards is a display enum; reading it after another thread died is harmless, and `PoisonError::into_inner` hands it over — the idiom already used elsewhere in the tree. Routed through one `App::status()` rather than patched at the line CI could see. The gate is lexical, so it flagged only the call written inline in `wndproc`; the other four sit in helpers that `wndproc` calls, where a panic unwinds into the very same boundary and aborts just the same. Fixing only the visible one would have left four identical aborts a function call away and made the gate look satisfied rather than the bug fixed. ⚠ NOT verified locally: the tray cannot be type-checked for Windows from a Mac (aws-lc-sys' build script cross-compiles C and dies in cc-rs long before win.rs), and scripts/xcheck.sh does not carry punktfunk-tray. windows-host.yml builds AND clippies this crate and triggers on `crates/punktfunk-tray/**`, so CI is the verifier here. |
||
|
|
5ee6468b2b |
test(pf-vkdecode): one lock-proving helper replaces six set_var copies
apple / swift (pull_request) Successful in 2m15s
apple / distribute (pull_request) Skipped
apple / screenshots (pull_request) Skipped
ci / rust (pull_request) Failing after 2m29s
ci / bun-nix (pull_request) Successful in 31s
ci / web (pull_request) Successful in 2m53s
ci / docs-site (pull_request) Successful in 2m18s
ci / docs-drift (pull_request) Successful in 1m0s
ci / rust-arm64 (pull_request) Successful in 1m45s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (pull_request) Successful in 6m44s
android / android (pull_request) Successful in 8m21s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (pull_request) Successful in 3m14s
CI gate C counts `env::set_var` mentions per file and this file was at its baseline of five, so the field leg's sixth copy failed the build. Raising the baseline is what the gate tells you not to do, and it would have been the wrong answer anyway: the six copies were the same two-line safety argument written out six times, which is precisely the shape a ratchet exists to discourage. `arm_test_readback` takes the GPU lock guard BY REFERENCE. `env::set_var` is safe to call and unsound from a live multithreaded process, so "the caller holds the binary-wide lock" is the entire safety argument — and a borrow states it in the type system, where it cannot drift out of date, instead of in prose repeated at each call site. The file drops from six mentions to two (the call, and the doc comment that names the API it is arguing about — gate C counts comments too, by design, and writing around its grep would be gaming it). The baseline moves 5 -> 2 to match, so the ratchet stays tight rather than merely satisfied. Gates: fmt, clippy --all-targets and 197 lib tests clean; check-unsafe-hygiene.sh gate C now passes. Gate B's punktfunk-tray finding is untouched by this branch and fails identically on main. |
||
|
|
2629508a10 |
fix(scripts): read framehash's bare hex digest, not a prefix that never existed
ci / bun-nix (pull_request) Successful in 30s
ci / docs-drift (pull_request) Successful in 41s
ci / web (pull_request) Successful in 1m2s
ci / docs-site (pull_request) Successful in 1m3s
ci / rust-arm64 (pull_request) Successful in 1m26s
ci / rust (pull_request) Failing after 4m38s
android / android (pull_request) Successful in 5m28s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (pull_request) Successful in 10m21s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (pull_request) Canceled after 3m10s
The extraction matched on `sha256=`, which ffmpeg's framehash muxer does not emit: its data rows are `0, <dts>, <pts>, <duration>, <size>, <bare hex>` and the algorithm is named once in a `#hash:` header. So the reference file came out EMPTY and the script reported "ffmpeg=0 frames" — indistinguishable, to a reader, from ffmpeg having failed to decode the capture at all. Take the last comma-separated field of every non-comment row instead. |
||
|
|
e7d650f7b6 |
test(pf-vkdecode): report which field AUs needed concealment
A capture taken over a lossy link holds AUs whose references never arrived, and ffmpeg conceals those differently from us — so a divergence at one of them says nothing about this decoder. Recording the AU indices (and printing the verdict last) is what separates "our bug" from "the field lost packets", which is the only reading that makes a field diff actionable. Split out of a dropped commit whose other half was wrong. |
||
|
|
dbb9d75718 |
test(pf-vkdecode): decode a field capture into per-frame hashes
The golden parity legs only decode streams our hosts never emit, and the field defect they cannot see is exactly the one two Deck reporters now show: a smear that accumulates through the reference chain while every integrity counter stays at zero. The full client audit (wire, planner, params conversion, slots, scope, ring, submission, caps/session) found no defect by inspection, so the fix needs the first divergent frame off real silicon. This leg turns any PUNKTFUNK_DUMP_VIDEO capture into that number: PF_VKD_FIELD_STREAM points at the .h265 (the .idx sidecar is honoured when present, complete==0 lines skipped), the join point is found the way the client found it (plan until an AU succeeds), and every delivered frame is read back and hashed to <stream>.pfhash in display order. Per-AU errors are tolerated and counted, off-size frames from a mid-capture renegotiation are released unshown, and PF_VKD_FIELD_YUV dumps named frames' planes for eyes-on inspection. scripts/vkdecode-field-parity.sh is the other half: ffmpeg -f framehash over the same bytes (nv12/p010le match the readback's packing exactly), first divergent index, ffprobe facts for the divergent picture. consume_frame now returns the planes and the hashing moved to its callers, which is the whole extent of the change to the golden legs. |