refactor(host/W6.2): extract the frame-capture backends into the pf-capture crate

capture/linux (PipeWire portal) + capture/windows (IDD direct-push: dxgi
mechanics, idd_push + submodules, synthetic_nv12) + pwinit move into
crates/pf-capture behind the Capturer trait + synthetic sources (plan §W6).
The crate speaks pf-frame (CapturedFrame/PixelFormat + the DXGI identity),
pf-zerocopy (CUDA import), and the pf-win-display leaves, and NEVER pf-encode —
the capture->encode edge is one-way. This completes the deliberate capture/encode
crate split (the invasive path the plan had merged into one pf-media): capture
and encode are now separate subsystem crates sharing only pf-frame.

Four seams keep the capturer off the orchestrator:
- VirtualOutput is EXPLODED into primitives (remote_fd/node_id/preferred_mode/
  keepalive) by the host facade, so pf-capture never depends on the vdisplay type;
- FrameChannelSender: the sealed-channel delivery is a Send+Sync closure the host
  facade builds from the pf-vdisplay control device + send_frame_channel IOCTL and
  hands in; ChannelBroker holds the closure instead of the control HANDLE (the
  whole-desktop handle-duplication security boundary is byte-for-byte unchanged);
- console_session_mismatch + desktop_bounds live in pf-win-display (leaf peers);
- pwinit moves here (audio caller -> pf_capture::pwinit).

The host keeps capture.rs as a thin BRIDGE: it re-exports the vocabulary + capturer
types (every crate::capture::* path is unchanged) and keeps open_portal_monitor /
capture_virtual_output, which resolve the ZeroCopyPolicy + FrameChannelSender and
call into pf-capture. verify_is_wudfhost + install_gpu_pref_hook are re-exported
(the gamepad-channel bootstrap + the main.rs subcommand consume them).

Co-developed: the resident-HID-mouse compose-kick hook (HID_COMPOSE_KICK + the
HID-first cursor kick + _display_wake) rides this commit into pf-capture; the host
mouse_windows registration side lands separately on top.

Verified: Linux clippy -D warnings (pf-capture + host nvenc,vulkan-encode,pyrowave
--all-targets) + host tests 299/299; Windows clippy -D warnings (pf-capture
--all-targets + host nvenc,amf-qsv --all-targets) Finished exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-17 11:28:56 +02:00
parent 845a97601d
commit 94ca4041ca
17 changed files with 615 additions and 364 deletions
+6 -8
View File
@@ -62,7 +62,6 @@ mod mgmt_token;
mod native;
mod native_pairing;
mod pipeline;
mod pwinit;
mod send_pacing;
#[cfg(target_os = "windows")]
#[path = "windows/service.rs"]
@@ -73,17 +72,16 @@ mod spike;
mod stats_recorder;
mod stream_marker;
mod vdisplay;
// The Windows display-topology cluster (CCD/GDI mode-set, PnP monitor devnodes, the display-change
// watch) lives in the `pf-win-display` leaf crate (plan §W6); import the modules at the crate root
// so every existing `crate::{win_display,monitor_devnode,display_events}::*` path stays valid.
// The Windows display-topology cluster (CCD/GDI mode-set + PnP monitor devnodes) lives in the
// `pf-win-display` leaf crate (plan §W6); import the modules at the crate root so the host's
// `crate::{win_display,monitor_devnode}::*` paths stay valid. (`display_events` moved with the
// IDD-push capturer into pf-capture, which names it directly.)
#[cfg(target_os = "windows")]
use pf_win_display::{display_events, monitor_devnode, win_display};
use pf_win_display::{monitor_devnode, win_display};
// The zero-copy GPU plumbing lives in the `pf-zerocopy` leaf crate (plan §W6); this shim keeps
// every existing `crate::zerocopy::*` path valid. `drm_fourcc` consumes the frame vocabulary, so
// it sits with `capture` and is re-exported here for its old callers.
// every existing `crate::zerocopy::*` path valid for the host's remaining callers (session_plan).
#[cfg(target_os = "linux")]
mod zerocopy {
pub(crate) use crate::capture::drm_fourcc;
pub(crate) use pf_zerocopy::*;
}