Every IDD-push capture stall now carries a VERDICT instead of a hypothesis list. The shared ring header grows a v2 telemetry tail (drain-loop heartbeat QPC, last-acquire QPC, full-width offered counter) the driver stamps on every drain pass; the host samples it between fresh frames and attributes each stall: worker-stalled (our thread starved) / compose-silence (DWM composed nothing — the disturbance is below capture) / delivery-leg (frames existed, our publish/ring/consume lost them). The metronomic WARN prints the running tally, so one pasted log line settles the Branch-1/Branch-2 fork of the vdisplay-disturbance-immunity program per session, per box. Both directions stay version-safe: the tail is gated on the HOST-stamped header version (a v2 driver never writes past a v1 host's 64-byte layout — it maps the whole section instead of a fixed 88 bytes), and a v2 host reads a zero heartbeat as pre-telemetry driver, no verdict. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
65 lines
2.9 KiB
TOML
65 lines
2.9 KiB
TOML
# Frame capture (plan §7 / §W6): the Linux xdg-ScreenCast/PipeWire portal capturer and the Windows
|
|
# IDD direct-push capturer, plus the synthetic sources + the Capturer trait, extracted into a
|
|
# subsystem crate. Depends on the shared frame vocabulary (pf-frame), the zero-copy plumbing
|
|
# (pf-zerocopy), and the display leaves (pf-win-display) — never on pf-encode: the encode-backend
|
|
# facts arrive pre-resolved (ZeroCopyPolicy) and the sealed-channel delivery as a closure
|
|
# (FrameChannelSender), so the capture→encode edge is one-way (plan §2.4).
|
|
[package]
|
|
name = "pf-capture"
|
|
version.workspace = true
|
|
edition = "2021"
|
|
rust-version.workspace = true
|
|
license = "MIT OR Apache-2.0"
|
|
description = "punktfunk host frame capture: Linux PipeWire portal + Windows IDD direct-push capturers behind one Capturer trait."
|
|
publish = false
|
|
|
|
[dependencies]
|
|
punktfunk-core = { path = "../punktfunk-core", features = ["quic"] }
|
|
pf-frame = { path = "../pf-frame" }
|
|
pf-zerocopy = { path = "../pf-zerocopy" }
|
|
pf-win-display = { path = "../pf-win-display" }
|
|
pf-gpu = { path = "../pf-gpu" }
|
|
pf-host-config = { path = "../pf-host-config" }
|
|
anyhow = "1"
|
|
tracing = "0.1"
|
|
|
|
[target.'cfg(target_os = "linux")'.dependencies]
|
|
# The xdg ScreenCast + RemoteDesktop portals, and the PipeWire consumer for the capture frames.
|
|
ashpd = { version = "0.13", features = ["screencast", "remote_desktop"] }
|
|
pipewire = "0.9"
|
|
libc = "0.2"
|
|
# ashpd 0.13 uses the tokio runtime for the one-time portal handshake (control plane).
|
|
tokio = { version = "1", features = ["rt", "rt-multi-thread", "net", "time"] }
|
|
# XFixes cursor source for gamescope (remote-desktop-sweep Phase C): gamescope paints no
|
|
# `SPA_META_Cursor`, so the pointer never reaches the PipeWire node. We read the shape/hotspot/
|
|
# visibility from gamescope's nested Xwayland via XFixes instead and feed the existing cursor slot.
|
|
# `RustConnection` is the pure-Rust default (no libxcb link → no new C dependency on the host); the
|
|
# `xfixes` feature (auto-pulls `render` + `shape`) is what exposes GetCursorImage/SelectCursorInput.
|
|
x11rb = { version = "0.13", default-features = false, features = ["xfixes"] }
|
|
|
|
[target.'cfg(target_os = "windows")'.dependencies]
|
|
# The host<->driver wire contract for the sealed frame channel (control IOCTL structs + frame header).
|
|
pf-driver-proto = { path = "../pf-driver-proto" }
|
|
windows = { version = "0.62", features = [
|
|
"Win32_Foundation",
|
|
"Win32_Security",
|
|
"Win32_Security_Authorization",
|
|
"Win32_Graphics_Direct3D",
|
|
"Win32_Graphics_Direct3D11",
|
|
"Win32_Graphics_Direct3D_Fxc",
|
|
"Win32_Graphics_Dxgi",
|
|
"Win32_Graphics_Dxgi_Common",
|
|
"Win32_Graphics_Gdi",
|
|
"Win32_System_LibraryLoader",
|
|
"Win32_System_StationsAndDesktops",
|
|
"Win32_System_Memory",
|
|
"Win32_System_Performance",
|
|
"Win32_System_Threading",
|
|
"Win32_UI_HiDpi",
|
|
"Win32_UI_Input_KeyboardAndMouse",
|
|
"Win32_UI_WindowsAndMessaging",
|
|
] }
|
|
|
|
[lints]
|
|
workspace = true
|