From 9569323f93ecfd45ae50f4c5dd7df40d15184200 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 13 Oct 2022 19:00:20 -0600 Subject: [PATCH] WIP: Getting a big black window, then a crash --- crates/capture/src/main.rs | 17 ++++++------- .../Sources/LiveKitBridge/LiveKitBridge.swift | 8 +++++++ crates/live_kit/src/live_kit.rs | 24 ++++++++++++++----- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/crates/capture/src/main.rs b/crates/capture/src/main.rs index 9398322c69..b248f071f1 100644 --- a/crates/capture/src/main.rs +++ b/crates/capture/src/main.rs @@ -38,11 +38,6 @@ fn main() { let live_kit_secret = std::env::var("LIVE_KIT_SECRET").unwrap(); cx.spawn(|mut cx| async move { - match live_kit::display_sources().await { - Ok(sources) => println!("found {} sources", sources.len()), - Err(error) => println!("error finding display sources {}", error), - } - let user1_token = live_kit_token::create_token( &live_kit_key, &live_kit_secret, @@ -64,12 +59,14 @@ fn main() { room2.connect(&live_kit_url, &user2_token).await.unwrap(); cx.add_window(Default::default(), |cx| ScreenCaptureView::new(room2, cx)); - let windows = live_kit::list_windows(); - let window = windows - .iter() - .find(|w| w.owner_name.as_deref() == Some("Safari")) + let display = live_kit::display_sources() + .await + .unwrap() + .into_iter() + .next() .unwrap(); - let track = LocalVideoTrack::screen_share_for_window(window.id); + + let track = LocalVideoTrack::screen_share_for_display(display); room1.publish_video_track(&track).await.unwrap(); }) .detach(); diff --git a/crates/live_kit/LiveKitBridge/Sources/LiveKitBridge/LiveKitBridge.swift b/crates/live_kit/LiveKitBridge/Sources/LiveKitBridge/LiveKitBridge.swift index c718f27761..2fc35e4e8c 100644 --- a/crates/live_kit/LiveKitBridge/Sources/LiveKitBridge/LiveKitBridge.swift +++ b/crates/live_kit/LiveKitBridge/Sources/LiveKitBridge/LiveKitBridge.swift @@ -92,6 +92,14 @@ public func LKCreateScreenShareTrackForWindow(windowId: uint32) -> UnsafeMutable return Unmanaged.passRetained(track).toOpaque() } +@_cdecl("LKCreateScreenShareTrackForDisplay") +public func LKCreateScreenShareTrackForDisplay(display: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer { + let display = Unmanaged.fromOpaque(display).takeRetainedValue() + print("!!!!!!!!!! display id", display.displayID) + let track = LocalVideoTrack.createMacOSScreenShareTrack(source: display) + return Unmanaged.passRetained(track).toOpaque() +} + @_cdecl("LKVideoRendererCreate") public func LKVideoRendererCreate(data: UnsafeRawPointer, onFrame: @escaping @convention(c) (UnsafeRawPointer, CVPixelBuffer) -> Void, onDrop: @escaping @convention(c) (UnsafeRawPointer) -> Void) -> UnsafeMutableRawPointer { Unmanaged.passRetained(LKVideoRenderer(data: data, onFrame: onFrame, onDrop: onDrop)).toOpaque() diff --git a/crates/live_kit/src/live_kit.rs b/crates/live_kit/src/live_kit.rs index 79ee645041..8cec1e2f65 100644 --- a/crates/live_kit/src/live_kit.rs +++ b/crates/live_kit/src/live_kit.rs @@ -55,7 +55,6 @@ extern "C" { fn LKVideoTrackAddRenderer(track: *const c_void, renderer: *const c_void); - fn LKCreateScreenShareTrackForWindow(windowId: u32) -> *const c_void; fn LKDisplaySources( callback_data: *mut c_void, callback: extern "C" fn( @@ -64,6 +63,8 @@ extern "C" { error: CFStringRef, ), ); + fn LKCreateScreenShareTrackForWindow(windowId: u32) -> *const c_void; + fn LKCreateScreenShareTrackForDisplay(display: *const c_void) -> *const c_void; } pub struct Room { @@ -196,6 +197,13 @@ impl LocalVideoTrack { pub fn screen_share_for_window(window_id: u32) -> Self { Self(unsafe { LKCreateScreenShareTrackForWindow(window_id) }) } + + pub fn screen_share_for_display(display: MacOSDisplay) -> Self { + let ptr = display.0; + let this = Self(unsafe { LKCreateScreenShareTrackForDisplay(ptr) }); + std::mem::forget(display); + this + } } impl Drop for LocalVideoTrack { @@ -285,6 +293,12 @@ pub fn list_windows() -> Vec { pub struct MacOSDisplay(*const c_void); +impl Drop for MacOSDisplay { + fn drop(&mut self) { + unsafe { LKRelease(self.0) } + } +} + pub fn display_sources() -> impl Future>> { extern "C" fn callback(tx: *mut c_void, sources: CFArrayRef, error: CFStringRef) { unsafe { @@ -294,11 +308,9 @@ pub fn display_sources() -> impl Future>> { let _ = tx.send(Err(anyhow!("{}", CFString::wrap_under_get_rule(error)))); } else { let sources = CFArray::wrap_under_get_rule(sources); - let sources = sources - .into_iter() - .map(|source| MacOSDisplay(*source)) - .collect(); - let _ = tx.send(Ok(sources)); + let sources_vec = sources.iter().map(|source| MacOSDisplay(*source)).collect(); + let _ = tx.send(Ok(sources_vec)); + std::mem::forget(sources); // HACK: If I drop the CFArray, all the objects inside it get dropped and we get issues accessing the display later. } } }