Reapply support for X11 screenshare (#28160)

Reapplies #27807 after [revert due to not building on
ARM](https://github.com/zed-industries/zed/pull/28141) by updating scap
to include [a fix to its build on
ARM](08f0a01417)

Release Notes:

- N/A

---------

Co-authored-by: Marshall Bowers <git@maxdeviant.com>
This commit is contained in:
Michael Sloan 2025-04-06 11:25:29 -06:00 committed by GitHub
parent 0708d476ca
commit 8cfb9beb17
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 618 additions and 47 deletions

View file

@ -25,7 +25,7 @@ async-trait.workspace = true
collections.workspace = true
cpal = "0.15"
futures.workspace = true
gpui.workspace = true
gpui = { workspace = true, features = ["x11", "wayland"] }
gpui_tokio.workspace = true
http_client_tls.workspace = true
image.workspace = true
@ -41,7 +41,12 @@ workspace-hack.workspace = true
[target.'cfg(not(all(target_os = "windows", target_env = "gnu")))'.dependencies]
libwebrtc = { rev = "80bb8f4c9112789f7c24cc98d8423010977806a6", git = "https://github.com/zed-industries/livekit-rust-sdks" }
livekit = { rev = "80bb8f4c9112789f7c24cc98d8423010977806a6", git = "https://github.com/zed-industries/livekit-rust-sdks", features = ["__rustls-tls"] }
livekit = { rev = "80bb8f4c9112789f7c24cc98d8423010977806a6", git = "https://github.com/zed-industries/livekit-rust-sdks", features = [
"__rustls-tls"
] }
[target.'cfg(any(target_os = "linux", target_os = "freebsd"))'.dependencies]
scap.workspace = true
[target.'cfg(target_os = "macos")'.dependencies]
core-foundation.workspace = true

View file

@ -336,7 +336,7 @@ pub(crate) async fn capture_local_video_track(
.await?;
let capture_stream = capture_source
.stream({
.stream(cx.foreground_executor(), {
let track_source = track_source.clone();
Box::new(move |frame| {
if let Some(buffer) = video_frame_buffer_to_webrtc(frame) {
@ -620,7 +620,49 @@ fn video_frame_buffer_to_webrtc(frame: ScreenCaptureFrame) -> Option<impl AsRef<
}
}
#[cfg(not(target_os = "macos"))]
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
fn video_frame_buffer_to_webrtc(frame: ScreenCaptureFrame) -> Option<impl AsRef<dyn VideoBuffer>> {
use libwebrtc::native::yuv_helper::argb_to_nv12;
use livekit::webrtc::prelude::NV12Buffer;
match frame.0 {
scap::frame::Frame::BGRx(frame) => {
let mut buffer = NV12Buffer::new(frame.width as u32, frame.height as u32);
let (stride_y, stride_uv) = buffer.strides();
let (data_y, data_uv) = buffer.data_mut();
argb_to_nv12(
&frame.data,
frame.width as u32 * 4,
data_y,
stride_y,
data_uv,
stride_uv,
frame.width,
frame.height,
);
Some(buffer)
}
scap::frame::Frame::YUVFrame(yuvframe) => {
let mut buffer = NV12Buffer::with_strides(
yuvframe.width as u32,
yuvframe.height as u32,
yuvframe.luminance_stride as u32,
yuvframe.chrominance_stride as u32,
);
let (luminance, chrominance) = buffer.data_mut();
luminance.copy_from_slice(yuvframe.luminance_bytes.as_slice());
chrominance.copy_from_slice(yuvframe.chrominance_bytes.as_slice());
Some(buffer)
}
_ => {
log::error!(
"Expected BGRx or YUV frame from scap screen capture but got some other format."
);
None
}
}
}
#[cfg(target_os = "windows")]
fn video_frame_buffer_to_webrtc(_frame: ScreenCaptureFrame) -> Option<impl AsRef<dyn VideoBuffer>> {
None as Option<Box<dyn VideoBuffer>>
}