Wayland capture: ashpd portal → gst-launch → ffmpeg → MPEG-TS
Implements the Wayland host pipeline from plan §4.5:
ashpd ScreenCast portal
-> CreateSession + SelectSources + Start + OpenPipeWireRemote
-> (pipewire fd, node_id, width, height)
gst-launch-1.0 pipewiresrc fd=N path=NODE_ID ! videoconvert
! video/x-raw,format=NV12 ! fdsink fd=1
ffmpeg
-f rawvideo -pix_fmt nv12 -video_size WxH -i pipe:0
-f pulse -i default
-c:v libx264 -preset ultrafast -tune zerolatency
-c:a aac -f mpegts -listen 1 http://127.0.0.1:<rand>
Phase 1 ships software x264 per plan §7; VAAPI is Phase 2.
src/host/wayland.rs is the new module. capture.rs becomes a thin
dispatcher with a CaptureHandle enum (Wayland today, X11 next).
host/mod.rs swaps the 150ms sleep for a poll-until-listener-ready
helper, and calls handle.shutdown().await for an orderly SIGTERM /
1s grace / SIGKILL teardown. The Drop impl is the panic backstop.
The pipewire fd handoff clears CLOEXEC before gst-launch spawn and
closes the parent's copy of the raw fd after the child has it.
Also deletes the empty src/host/tunnel.rs and src/viewer/tunnel.rs
placeholder files — the generic bridge in common/tunnel.rs is doing
the work, and there's no host- or viewer-specific tunnel concern
worth a module yet.
This commit is contained in:
+3
-8
@@ -1,5 +1,5 @@
|
||||
mod capture;
|
||||
mod tunnel;
|
||||
mod wayland;
|
||||
|
||||
use anyhow::{Result, bail};
|
||||
use iroh::Endpoint;
|
||||
@@ -71,14 +71,9 @@ async fn handle_peer(
|
||||
) -> Result<()> {
|
||||
let (quic_send, quic_recv) = conn.accept_bi().await?;
|
||||
|
||||
// Spawn ffmpeg (and on Wayland, the gst-launch bridge) listening on a
|
||||
// random localhost port. Returns the port and a guard that kills the
|
||||
// child(ren) on drop.
|
||||
let capture_handle = capture::spawn(display, opts).await?;
|
||||
let port = capture_handle.local_port();
|
||||
|
||||
// Give ffmpeg's `-listen 1` HTTP server a moment to bind before we dial.
|
||||
tokio::time::sleep(std::time::Duration::from_millis(150)).await;
|
||||
wayland::wait_for_listener(port, std::time::Duration::from_secs(5)).await?;
|
||||
let tcp = TcpStream::connect(("127.0.0.1", port)).await?;
|
||||
|
||||
let bridge = crate::common::tunnel::bridge(quic_send, quic_recv, tcp);
|
||||
@@ -96,7 +91,7 @@ async fn handle_peer(
|
||||
}
|
||||
}
|
||||
|
||||
drop(capture_handle); // explicit teardown of ffmpeg/gst
|
||||
capture_handle.shutdown().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user