diff --git a/Cargo.lock b/Cargo.lock index 21893b57542098c6166cc4a822429eb4df902702..823c3d05463a8038f0a426b89b0ac3acaca354c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10004,6 +10004,7 @@ dependencies = [ "tokio", "ui", "util", + "webrtc-sys", "zed-scap", ] diff --git a/Cargo.toml b/Cargo.toml index bc1722718b8ed464b6c78c776699bce890ba223b..b31c088581a65070f348cf55195d0db948b33bb0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -779,6 +779,7 @@ wax = "0.7" which = "6.0.0" wasm-bindgen = "0.2.113" web-time = "1.1.0" +webrtc-sys = "0.3.23" wgpu = { git = "https://github.com/zed-industries/wgpu.git", branch = "v29" } windows-core = "0.61" yawc = "0.2.5" @@ -849,6 +850,7 @@ windows-capture = { git = "https://github.com/zed-industries/windows-capture.git calloop = { git = "https://github.com/zed-industries/calloop" } livekit = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "c1209aa155cbf4543383774f884a46ae7e53ee2e" } libwebrtc = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "c1209aa155cbf4543383774f884a46ae7e53ee2e" } +webrtc-sys = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "c1209aa155cbf4543383774f884a46ae7e53ee2e" } [profile.dev] split-debuginfo = "unpacked" diff --git a/crates/livekit_client/Cargo.toml b/crates/livekit_client/Cargo.toml index d4a238fc15997d833df65ac1be459763be6ec782..42c13f094c1893260f474c98f650ba83be832ef0 100644 --- a/crates/livekit_client/Cargo.toml +++ b/crates/livekit_client/Cargo.toml @@ -49,6 +49,7 @@ livekit.workspace = true [target.'cfg(target_os = "linux")'.dependencies] tokio = { workspace = true, features = ["time"] } +webrtc-sys.workspace = true [target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os = "windows"))'.dependencies] scap.workspace = true diff --git a/crates/livekit_client/src/livekit_client/linux.rs b/crates/livekit_client/src/livekit_client/linux.rs index e7bfa7b2ca631636233586cb902b36bac93c9be1..fe7189e901dc8586dbcbdfadbc7a8a0ef5fb1e5d 100644 --- a/crates/livekit_client/src/livekit_client/linux.rs +++ b/crates/livekit_client/src/livekit_client/linux.rs @@ -14,6 +14,7 @@ use std::sync::{ }; static NEXT_WAYLAND_SHARE_ID: AtomicU64 = AtomicU64::new(1); +const PIPEWIRE_TIMEOUT_S: u64 = 30; pub struct WaylandScreenCaptureStream { id: u64, @@ -64,6 +65,17 @@ pub(crate) async fn start_wayland_desktop_capture( }; use libwebrtc::native::yuv_helper::argb_to_nv12; use std::time::Duration; + use webrtc_sys::webrtc::ffi as webrtc_ffi; + + fn webrtc_log_callback(message: String, severity: webrtc_ffi::LoggingSeverity) { + match severity { + webrtc_ffi::LoggingSeverity::Error => log::error!("[webrtc] {}", message.trim()), + _ => log::debug!("[webrtc] {}", message.trim()), + } + } + + let _webrtc_log_sink = webrtc_ffi::new_log_sink(webrtc_log_callback); + log::debug!("Wayland desktop capture: WebRTC internal logging enabled"); let stop_flag = Arc::new(AtomicBool::new(false)); let (mut video_source_tx, mut video_source_rx) = mpsc::channel::(1); @@ -79,7 +91,6 @@ pub(crate) async fn start_wayland_desktop_capture( })?; let permanent_error = Arc::new(AtomicBool::new(false)); - let stop_cb = stop_flag.clone(); let permanent_error_cb = permanent_error.clone(); capturer.start_capture(None, { @@ -136,6 +147,8 @@ pub(crate) async fn start_wayland_desktop_capture( } }); + log::info!("Wayland desktop capture: starting capture loop"); + let stop = stop_flag.clone(); let tokio_task = gpui_tokio::Tokio::spawn(cx, async move { loop { @@ -162,10 +175,11 @@ pub(crate) async fn start_wayland_desktop_capture( let executor = cx.background_executor().clone(); let video_source = video_source_rx .next() - .with_timeout(Duration::from_secs(15), &executor) + .with_timeout(Duration::from_secs(PIPEWIRE_TIMEOUT_S), &executor) .await .map_err(|_| { stop_flag.store(true, Ordering::Relaxed); + log::error!("Wayland desktop capture timed out."); anyhow::anyhow!( "Screen sharing timed out waiting for the first frame. \ Check that xdg-desktop-portal and PipeWire are running, \ diff --git a/crates/zed/build.rs b/crates/zed/build.rs index 9b9ed59bf4de65220f36c1fd53421fdf44c1e529..690444705c9ed52cf96901a7cda81e04eabeeb4e 100644 --- a/crates/zed/build.rs +++ b/crates/zed/build.rs @@ -7,12 +7,14 @@ fn main() { // Add rpaths for libraries that webrtc-sys dlopens at runtime. // This is mostly required for hosts with non-standard SO installation // locations such as NixOS. - let dlopened_libs = ["libva", "libva-drm"]; + let dlopened_libs = ["libva", "libva-drm", "egl"]; let mut rpath_dirs = std::collections::BTreeSet::new(); for lib in &dlopened_libs { if let Some(libdir) = pkg_config::get_variable(lib, "libdir").ok() { rpath_dirs.insert(libdir); + } else { + eprintln!("zed build.rs: {lib} not found in pkg-config's path"); } } diff --git a/nix/build.nix b/nix/build.nix index a5ced61bbbfd145c1e3f9fc9909ae69779ba133a..02ed6235e54daa27a9af9b86da79618a21e3cc7e 100644 --- a/nix/build.nix +++ b/nix/build.nix @@ -77,7 +77,6 @@ let builtins.elem firstComp topLevelIncludes; craneLib = crane.overrideToolchain rustToolchain; - gpu-lib = if withGLES then libglvnd else vulkan-loader; commonArgs = let zedCargoLock = builtins.fromTOML (builtins.readFile ../crates/zed/Cargo.toml); @@ -179,7 +178,8 @@ let libva libxkbcommon wayland - gpu-lib + libglvnd + vulkan-loader xorg.libX11 xorg.libxcb libdrm @@ -236,7 +236,8 @@ let # about them that's special is that they're manually dlopened at runtime NIX_LDFLAGS = lib.optionalString stdenv'.hostPlatform.isLinux "-rpath ${ lib.makeLibraryPath [ - gpu-lib + libglvnd + vulkan-loader wayland libva ] @@ -245,7 +246,7 @@ let NIX_OUTPATH_USED_AS_RANDOM_SEED = "norebuilds"; }; - # prevent nix from removing the "unused" wayland/gpu-lib rpaths + # prevent nix from removing the "unused" wayland rpaths dontPatchELF = stdenv'.hostPlatform.isLinux; # TODO: try craneLib.cargoNextest separate output