forked from unom/punktfunk
The last piece of M3 WP-2 — VkH265Decoder was built and hardware-gated but nothing drove it. video_vk_native.rs holds a two-arm codec enum and forwards to it; the ledger, release tokens, status-query settling and timeline waits are byte-for-byte what they were, since they were always codec-agnostic over one DecodedVkFrame contract. The forwarders are written out per arm rather than macro'd so the unchanged H.264 arm is visible to a reviewer. The picture's own format now reaches the presenter, which picks bit depth and MSB packing from it instead of assuming the H.264 envelope. That incidentally fixes a live bug on the SHIPPING FFmpeg-Vulkan path: it derived ten-bit-ness by comparing against the 10-bit 4:2:0 format alone, so a 10-bit two-plane 4:4:4 surface — which its own format table accepts, and which NVIDIA reports for HEVC RExt — got 8-bit range and transfer maths. Reachable today with Full chroma plus 10-bit: decoded correctly, displayed wrong. Review round 11 caught a regression this WP would otherwise have shipped. pf-vkdecode refuses a stream whose (chroma, depth) pair has no picture format on the device, but the session is built lazily from the first SPS, so the refusal arrived AFTER construction — past the point where a native init failure falls through to FFmpeg-Vulkan. It burned the error streak instead and demoted to VAAPI/D3D11VA, which on NVIDIA/Linux means software. Turning on Full chroma on any non-NVIDIA GPU was enough: a 4K HEVC session that ran on FFmpeg-Vulkan before this branch would have landed on software decode. Both halves are fixed. The negotiated chroma and bit depth — already at the call site, the PyroWave arm four lines up uses them — are threaded into the backend, which probes the same caps path ensure_state would run, so the whole class refuses at CONSTRUCTION where the fall-through already exists. For the legs no negotiation can carry (a level above maxLevelIdc, an SPS that disagrees with the Welcome) the decoder latches 'never delivered a frame' and routes that first streak to FFmpeg-Vulkan rather than down the hardware ladder. H.264 is deliberately not probed: its envelope is fixed, so a probe would only add a profile guess on the bit-exact path; it gets the latch as its backstop. Two more from the round. Planner warnings are typed again rather than Debug strings — pf-vkdecode simply lacked the h265 re-export its h264 twin already had — which restores the H.264 log rendering exactly and unblocks M4, whose job is counting concealment by kind. And concealment is now the integrity set only: NonZeroReorder is documented spec-legal and fully planned, but the client treated every warning as damage, so the opening IDR and every ABR renegotiation's IDR were released unshown and re-anchored — a visible hitch on a healthy stream. Also: a raw-format newtype so a neighbouring i32 field cannot be passed to the colour maths, the presenter's depth table now pinned against pf-vkdecode's actual output vocabulary rather than the FFmpeg lane's, a per-format warn latch, and four stale docs. Gates: fmt clean; container clippy -D warnings zero across pf-client-core + pf-presenter + pf-vkdecode; tests 69/125/108/40 green; cargo check --workspace clean.
105 lines
5.0 KiB
Rust
105 lines
5.0 KiB
Rust
//! Shared, UI-agnostic client plumbing, extracted verbatim from the GTK client
|
|
//! (design: punktfunk-planning `linux-client-rearchitecture.md`, Phase 0) so the desktop
|
|
//! shells and the Vulkan session binary build on one implementation — on Linux AND
|
|
//! Windows (the session binary runs on both; macOS stays `wol`-only, clients/apple is
|
|
//! the client there).
|
|
//!
|
|
//! Nothing here may depend on a UI toolkit: the presenter contract is `session`'s
|
|
//! channels (`SessionHandle`) and `video`'s `DecodedImage` (RGBA bytes, dmabuf fds +
|
|
//! plane layout, or a decoded VkImage) — how frames reach the screen is the consumer's
|
|
//! business.
|
|
//!
|
|
//! Audio is the one per-OS module swap: `audio.rs` (PipeWire) on Linux,
|
|
//! `audio_wasapi.rs` (WASAPI) on Windows — same public surface, picked here by `#[path]`
|
|
//! so `crate::audio` is the only name the session pump ever sees. `keymap` (evdev-keyed)
|
|
//! stays Linux: the session path uses pf-presenter's SDL-scancode table instead.
|
|
|
|
// Unsafe-proof program: every `unsafe {}` / `unsafe impl` in this crate carries a `// SAFETY:`
|
|
// proof of why it is sound. This crate held ~91 unsafe items with NO enforcement while every
|
|
// other subsystem crate denied it — the decoders' `unsafe impl Send`s had a one-line aside
|
|
// instead of an argument precisely because nothing required one.
|
|
#![deny(clippy::undocumented_unsafe_blocks)]
|
|
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
mod au_dump;
|
|
#[cfg(target_os = "linux")]
|
|
pub mod audio;
|
|
#[cfg(windows)]
|
|
#[path = "audio_wasapi.rs"]
|
|
pub mod audio;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod discovery;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod gamepad;
|
|
#[cfg(target_os = "linux")]
|
|
pub mod keymap;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod library;
|
|
// The `punktfunk://` grammar (design/client-deep-links.md §2): one parser/emitter for the
|
|
// shells, the session and the CLI, held to the Swift/Kotlin ports by a shared vector file.
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod deeplink;
|
|
// The brain layer (design/client-architecture-split.md §3): what a connect is, the wake
|
|
// state machine every front-end drives, and the session spawn + stdout contract.
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod orchestrate;
|
|
// The host's OS-identity chain (mDNS `os=` TXT): sanitize + icon-walk order. Pure string
|
|
// logic, built everywhere (the Apple/Android ports mirror it rather than link it).
|
|
pub mod os;
|
|
// Client settings profiles: the override catalog + the one connect-time resolver
|
|
// (design/client-settings-profiles.md §4). Sits beside `trust`, which owns the host records
|
|
// the bindings live on.
|
|
// Pad audio (the 0xD1 plane): DualSense voice-coil haptics + speaker rendered on the wired
|
|
// physical pad's own 4-ch audio device — correlation, the per-session renderer worker, and
|
|
// the tier-A pad registry the gamepad worker feeds it through.
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod pad_audio;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod profiles;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod session;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod trust;
|
|
// "Is a newer client available, and can this box install it?" — the client half of the
|
|
// signed-manifest update check the host already runs (design: host-update-from-web-console.md).
|
|
// Linux only: the Windows client ships inside the host installer and the Mac one through
|
|
// clients/apple, so neither has a package to reason about here.
|
|
#[cfg(target_os = "linux")]
|
|
pub mod update;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod video;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
mod video_color;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
mod video_software;
|
|
// libav ownership helpers shared by the hardware decoders below (`AvBuffer`).
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
mod video_libav;
|
|
#[cfg(target_os = "linux")]
|
|
mod video_vaapi;
|
|
// Native Vulkan Video decode (WP-C of the native-decode program, HEVC added by M3
|
|
// WP-2): pf-vkdecode's H.264/H.265 decoders on the presenter's shared device — auto's
|
|
// rung immediately above FFmpeg-Vulkan (2026-08-05 ladder decision; the program is
|
|
// dropping FFmpeg from the client), also pinnable via
|
|
// `PUNKTFUNK_DECODER=native-vulkan`.
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
mod video_vk_native;
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
mod video_vulkan;
|
|
// The OS-clipboard bridge for the shared clipboard (design/clipboard-and-file-transfer.md §5).
|
|
// Built everywhere the session client is; the platform seam inside is Windows-real,
|
|
// stub elsewhere.
|
|
#[cfg(any(target_os = "linux", windows))]
|
|
pub mod clipboard;
|
|
// PyroWave decode — Linux + Windows (plan §4.5; the Apple Metal port is its own phase).
|
|
// Windows joined once its client moved to the SAME spawned Vulkan session presenter as
|
|
// Linux's: the decoder is plain Vulkan compute on the presenter's device (no fds, no
|
|
// dmabuf, no D3D11 interop), so the old "Windows present-path decision" that gated it
|
|
// resolved itself — the present path is now literally the same code.
|
|
#[cfg(windows)]
|
|
pub mod video_d3d11;
|
|
#[cfg(all(any(target_os = "linux", windows), feature = "pyrowave"))]
|
|
pub mod video_pyrowave;
|
|
|
|
pub mod wol;
|