Use scap library to implement screensharing on X11 (#27807)
While `scap` does have support for Wayland and Windows, but haven't seen screensharing work properly there yet. So for now just adding support for X11 screensharing. WIP branches for enabling wayland and windows support: * https://github.com/zed-industries/zed/tree/wayland-screenshare * https://github.com/zed-industries/zed/tree/windows-screenshare Release Notes: - Added support for screensharing on X11 (Linux) --------- Co-authored-by: Conrad <conrad@zed.dev> Co-authored-by: Mikayla <mikayla@zed.dev> Co-authored-by: Junkui Zhang <364772080@qq.com>
This commit is contained in:
co-authored by
Conrad
Mikayla
Junkui Zhang
parent
7bc62de267
commit
c2afc2271b
@@ -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>>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user