feat(host): X11 capture backend + shared pipeline extraction
Extract the display-agnostic encode/mux tail out of wayland.rs into a new host/pipeline.rs: CaptureHandle + lifecycle, audio routing setup, the gst arg builder, the spawn, and Serve::bind now live there. Backends supply only their video-source element args plus a post-spawn hook (Wayland uses it to close its leaked pipewire fd; X11 passes a no-op). capture.rs collapses to a thin dispatcher; its CaptureHandle enum is gone. Add host/x11.rs: ximagesrc (use-damage=false show-pointer=true), whole root window by default or a single window via --window (xwininfo click-picker → xid). x11rb reads geometry for an info log, justifying the previously-vestigial dep. No portal, no fd dance — capture starts silently when the first viewer connects (the ticket is the access control). Viewer is display-agnostic and unchanged. Wire --no-hwencode for real (was a no-op): the shared tail now selects x264enc(tune=zerolatency,ultrafast)/I420 vs vah264enc/NV12 and switches the videoconvert target format to match. Applies to both backends. deps.rs: check_host_binaries now takes &HostOpts and checks shared elements for both backends, encoder by --no-hwencode, source per backend (pipewiresrc/ximagesrc), and xwininfo only when X11 + --window. Install hints added for x264enc, ximagesrc, xwininfo. Verified: warning-free build; smoke test still passes (tail unchanged); ximagesrc + both encoder tails produce mpv-decodable H.264 against an Xwayland root. Interactive cross-machine end-to-end pending. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+10
-30
@@ -1,40 +1,20 @@
|
||||
//! Capture dispatcher. Selects the per-display-server pipeline and returns its
|
||||
//! [`CaptureHandle`]. Each backend owns its own children and tears them down
|
||||
//! via its own Drop / shutdown.
|
||||
//! Capture dispatcher. Picks the per-display-server source backend and returns
|
||||
//! the shared [`pipeline::CaptureHandle`]. The handle itself, its teardown, and
|
||||
//! the whole encode/serve tail are display-agnostic and live in
|
||||
//! [`super::pipeline`]; the backends differ only in how they obtain a video
|
||||
//! source element.
|
||||
|
||||
use anyhow::{Result, bail};
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::cli::HostOpts;
|
||||
use crate::common::display::DisplayServer;
|
||||
use crate::host::wayland;
|
||||
|
||||
pub enum CaptureHandle {
|
||||
Wayland(wayland::CaptureHandle),
|
||||
}
|
||||
|
||||
impl CaptureHandle {
|
||||
pub fn local_port(&self) -> u16 {
|
||||
match self {
|
||||
CaptureHandle::Wayland(h) => h.local_port(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn shutdown(self) {
|
||||
match self {
|
||||
CaptureHandle::Wayland(h) => h.shutdown().await,
|
||||
}
|
||||
}
|
||||
}
|
||||
use crate::host::pipeline::CaptureHandle;
|
||||
use crate::host::{wayland, x11};
|
||||
|
||||
pub async fn spawn(display: DisplayServer, opts: &HostOpts) -> Result<CaptureHandle> {
|
||||
match display {
|
||||
DisplayServer::Wayland => {
|
||||
let h = wayland::start(opts).await?;
|
||||
Ok(CaptureHandle::Wayland(h))
|
||||
}
|
||||
DisplayServer::X11 => {
|
||||
bail!("X11 capture pipeline not yet implemented (Phase 2 follow-up)");
|
||||
}
|
||||
DisplayServer::Wayland => wayland::start(opts).await,
|
||||
DisplayServer::X11 => x11::start(opts).await,
|
||||
DisplayServer::Unknown => unreachable!("caller guarantees display != Unknown"),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user