dee97e893cf4f2a4403a880acf7a267598fedd36
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
dee97e893c |
fix(vkdecode): the address the driver keeps is now the address we keep
The AV1 use-after-free fix (
|
||
|
|
185332a866 |
fix(vkdecode): H.264 and H.265 session parameters own what the driver keeps
The same use-after-free the AV1 rung was just fixed for, closed in the two rungs that ship. session.rs and session_h265.rs handed their Std parameter sets to vkCreateVideoSessionParametersKHR and dropped the backings when the call returned; NVIDIA 610.57.04 was measured retaining such a pointer to decode-record time, which is what made AV1 diverge on 250 of 250 frames. Nothing was known to be broken here — both rungs are bit-exact on four drivers — but that was luck rather than correctness: the freed blocks happen to still hold the right bytes in that window. The native Vulkan rung sits in the auto ladder above FFmpeg-Vulkan on shipping clients, so this was live code, and its failure mode is silent wrong pixels rather than a crash. StoredParams and StoredParamsH265 hold the parameters object together with every wrapper it points at, so an object whose backing is gone cannot be built. create_parameters_object takes the wrappers by value; the Add arm adopts them only after a successful update, so a failed update drops what it never stored; the Recreate arm replaces, destroys the old object, then drops its backings, written explicitly so the ordering survives later edits. The Add-vs-Recreate decision table and the VPS ledger are untouched — only ownership moved. params.rs still carried the refuted claim as a type-level contract, that Vulkan "copies all parameter data before returning" and keeping the wrapper alive across the call "is the whole obligation". Corrected to the measured truth. The tests are what stop this returning, and each was verified by sabotage: inlining the H.264 PPS box fails at pps pScalingLists, inlining the H.265 SPS DPB box fails at sps pDecPicBufMgr, and making either adopt drop instead of store fails both session tests. Two lessons are recorded in them. Pointer equality cannot be the assertion, because the Std struct carries pointers by value and a stale one compares equal — the read-back is the discriminator, so the tests clobber the dead stack first to make a dangling read deterministic rather than lucky. And the first H.265 draft read six of eight pointers and let the sabotage through, so it now reads every one with a labelled assert. ⚠ One site of this class remains, deliberately: the VkVideoProfileInfoKHR chains, where wire()'s borrow dies with its enclosing block while the object created from it lives on — three session creates, an image, a buffer, and a query pool built from a raw pointer into a stack chain. It spans six modules and all three codecs, and a profile is enums a driver resolves at create time with no per-frame deref, so the risk is materially lower. It wants its own pass with its own hardware verification. Gates: macOS fmt/clippy/196 tests, container clippy -D warnings, pf-vkdecode 182/182 and pf-client-core 140/140. On the RTX 5070 Ti, all 8 gpu_parity legs re-verified green after the change — H.264, H.265, Main 10 and AV1 all still bit-identical to libavcodec. |
||
|
|
540c0d3027 |
feat(pf-vkdecode): the GPU half — session, DPB pools, decode recording, status queries
M2 WP-B. VkVideoSessionKHR lifecycle with drain-before-destroy on parameters recreation, DPB pools in both coincide and distinct modes (caps-derived, usage/flags validated against the driver's format properties), an aligned bitstream ring, vkCmdDecodeVideoKHR recording with one-shot RESET re-armed on failed submits, timeline-semaphore completion, and the per-op RESULT_STATUS query ring — the signal FFmpeg's hwaccel never reads and the reason this program exists. Frame lifetime is two-phase by construction: release_frame pins a delivered frame's slot against reuse, closing the coincide-mode overwrite the adversarial review round proved (a full DPB handed a just-returned frame's image back as the same call's decode target). Nine review findings fixed pre-commit; a counterfactual test pins the collision. Generation-stamped frames, memory-type misses as errors, granularity-aligned extents, level gate. AuPlan now carries its activated SPS/PPS (Rc) so backends never re-parse. GPU smoke test (ignored) decodes 48 AUs past DPB-full with releases — the fleet runs it in WP-D. Gates: fmt clean, clippy -D warnings zero, 45+27+53 tests green on macOS and the linux/amd64 container. |
||
|
|
d24f7fc6ac |
feat(pf-vkdecode): the CPU half of native Vulkan decode — StdVideo conversion + slot map
M2 WP-A (design/client-native-decode.md §3.2). AuPlan -> StdVideo parameter sets (owned pointer backings), per-AU decode info with slice start-code offsets, and a PicId->slot map that never evicts on its own. Deliberate rejections over silent claims: FMO, separate colour planes, DPBs deeper than 16 frames (unbounded VUI ue(v)) all fail closed. pf-bitstream API grew what the review proved necessary: RefPic carries the true top/bottom field order counts (a single poc fabricated BottomFieldOrderCnt whenever the PPS signals pic-order deltas), the >16-frame DPB envelope gate, and an MMCO5 rebase warning. Adversarial review round two: 8 findings fixed pre-commit, including transactional slot mutation (an error path could permanently desync the map) and count/pointer coherence on type-1 POC offsets. Gates: fmt clean, clippy -D warnings zero, 45+26+21 tests green on macOS and the linux/amd64 container. |