diff --git a/crates/punktfunk-host/src/config.rs b/crates/punktfunk-host/src/config.rs index b571a97..a22eabf 100644 --- a/crates/punktfunk-host/src/config.rs +++ b/crates/punktfunk-host/src/config.rs @@ -36,7 +36,11 @@ use std::sync::OnceLock; /// derived `Debug` impl, so the parser can stay a single platform-neutral function. #[derive(Debug, Clone, Default)] pub struct HostConfig { - /// `PUNKTFUNK_IDD_PUSH` — use the IDD direct-push capturer (in-process Session-0 capture; no WGC helper). + /// `PUNKTFUNK_IDD_PUSH` — capture from the pf-vdisplay driver's shared ring (in-process Session-0 + /// capture; no WGC helper). **Value-aware** (`0`/`false`/`no`/`off`/empty ⇒ off, else on); unset ⇒ off. + /// The installer's default `host.env` sets it on, so a fresh install runs the validated IDD-push path + /// (it falls back to DDA if the driver can't attach — see [`crate::capture`]). NOT a bare presence flag + /// (so an operator can turn it OFF in `host.env` with `=0`, which a `var_os` presence check can't). pub idd_push: bool, /// `PUNKTFUNK_ENCODER` — explicit encoder-backend override (lowercased; empty = auto-detect by GPU vendor). pub encoder_pref: String, @@ -80,7 +84,16 @@ impl HostConfig { // String value: `var(k).ok()` — `Some` (possibly empty) when set with valid UTF-8, else `None`. let val = |k: &str| std::env::var(k).ok(); Self { - idd_push: flag("PUNKTFUNK_IDD_PUSH"), + // Value-aware (not a bare presence flag): the shipped default `host.env` turns it ON, and an + // operator turns it OFF with `PUNKTFUNK_IDD_PUSH=0` (a `var_os` presence check would read `=0` + // as "on"). Unset ⇒ off (the dev / non-pf-driver default). + idd_push: match std::env::var("PUNKTFUNK_IDD_PUSH") { + Ok(v) => !matches!( + v.trim().to_ascii_lowercase().as_str(), + "" | "0" | "false" | "no" | "off" + ), + Err(_) => false, + }, encoder_pref: std::env::var("PUNKTFUNK_ENCODER") .unwrap_or_default() .to_ascii_lowercase(), diff --git a/crates/punktfunk-host/src/windows/service.rs b/crates/punktfunk-host/src/windows/service.rs index 4c0bb91..36dbb6f 100644 --- a/crates/punktfunk-host/src/windows/service.rs +++ b/crates/punktfunk-host/src/windows/service.rs @@ -621,6 +621,10 @@ fn ensure_default_host_env() -> Result<()> { # Force one with nvenc | amf | qsv | sw (software H.264). amf/qsv need an FFmpeg-built host.\n\ PUNKTFUNK_ENCODER=auto\n\ PUNKTFUNK_VIDEO_SOURCE=virtual\n\ + # Virtual display = the bundled pf-vdisplay driver; capture from its shared ring (the validated\n\ + # zero-copy IDD-push path; falls back to DDA if it can't attach). Set PUNKTFUNK_IDD_PUSH=0 to force WGC/DDA.\n\ + PUNKTFUNK_VDISPLAY=pf\n\ + PUNKTFUNK_IDD_PUSH=1\n\ PUNKTFUNK_SECURE_DDA=1\n\ RUST_LOG=info\n\ \n\ diff --git a/scripts/windows/host.env.example b/scripts/windows/host.env.example index c26d3cf..a86cd39 100644 --- a/scripts/windows/host.env.example +++ b/scripts/windows/host.env.example @@ -15,10 +15,18 @@ # ship in the installer). The published installer is built with all three. PUNKTFUNK_ENCODER=auto -# Video source: `virtual` creates a per-client virtual display (SudoVDA) at the client's exact -# resolution + refresh — the flagship mode. Requires the SudoVDA indirect display driver installed. +# Video source: `virtual` creates a per-client virtual display at the client's exact resolution + +# refresh — the flagship mode. Requires the bundled pf-vdisplay indirect display driver installed. PUNKTFUNK_VIDEO_SOURCE=virtual +# Virtual-display backend: `pf` = the all-Rust pf-vdisplay IddCx driver the installer bundles (the +# shipped driver; leave as the default). `sudovda` selects the legacy backend if one is present. +PUNKTFUNK_VDISPLAY=pf + +# Capture straight from the pf-vdisplay driver's shared ring — the validated zero-copy path (incl. the +# secure desktop). Falls back to DDA if the driver can't attach. Set to 0 to force WGC/DDA capture. +PUNKTFUNK_IDD_PUSH=1 + # Capture the secure desktop (UAC / lock / login) so the stream survives those transitions. PUNKTFUNK_SECURE_DDA=1