Cargo.lock 🔗
@@ -10004,6 +10004,7 @@ dependencies = [
"tokio",
"ui",
"util",
+ "webrtc-sys",
"zed-scap",
]
Cameron Mcloughlin and Jakub Konka created
Release Notes:
- Fixed a weird niche interaction between niri and nixos that broke
screensharing
---------
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Cargo.lock | 1
Cargo.toml | 2 +
crates/livekit_client/Cargo.toml | 1
crates/livekit_client/src/livekit_client/linux.rs | 18 +++++++++++++++-
crates/zed/build.rs | 4 ++
nix/build.nix | 9 ++++---
6 files changed, 28 insertions(+), 7 deletions(-)
@@ -10004,6 +10004,7 @@ dependencies = [
"tokio",
"ui",
"util",
+ "webrtc-sys",
"zed-scap",
]
@@ -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"
@@ -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
@@ -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::<NativeVideoSource>(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, \
@@ -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");
}
}
@@ -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