Get test_app running without crashing

This commit is contained in:
Nathan Sobo 2022-10-17 23:38:43 -06:00
parent 8c1c98a0bf
commit c73e2c2d0f
4 changed files with 50 additions and 49 deletions

View file

@ -600,7 +600,7 @@ impl Room {
}; };
cx.foreground().spawn(async move { cx.foreground().spawn(async move {
let display = live_kit_client::display_source().await?; let display = live_kit_client::display_sources().await?;
// let display = displays // let display = displays
// .first() // .first()
// .ok_or_else(|| anyhow!("no display found"))?; // .ok_or_else(|| anyhow!("no display found"))?;

View file

@ -100,15 +100,7 @@ public func LKRoomVideoTracksForRemoteParticipant(room: UnsafeRawPointer, partic
for (_, participant) in room.remoteParticipants { for (_, participant) in room.remoteParticipants {
if participant.identity == participantId as String { if participant.identity == participantId as String {
var tracks = [UnsafeMutableRawPointer]() return participant.videoTracks.compactMap { $0.track as? RemoteVideoTrack } as CFArray?
for publication in participant.videoTracks {
let track = publication.track as? RemoteVideoTrack
if track != nil {
tracks.append(Unmanaged.passRetained(track!).toOpaque())
}
}
return tracks as CFArray?
} }
} }
@ -140,11 +132,10 @@ public func LKRemoteVideoTrackGetSid(track: UnsafeRawPointer) -> CFString {
return track.sid! as CFString return track.sid! as CFString
} }
@_cdecl("LKDisplaySource") @_cdecl("LKDisplaySources")
public func LKDisplaySource(data: UnsafeRawPointer, callback: @escaping @convention(c) (UnsafeRawPointer, UnsafeRawPointer?, CFString?) -> Void) { public func LKDisplaySources(data: UnsafeRawPointer, callback: @escaping @convention(c) (UnsafeRawPointer, CFArray?, CFString?) -> Void) {
MacOSScreenCapturer.sources(for: .display, includeCurrentApplication: false, preferredMethod: .legacy).then { displaySources in MacOSScreenCapturer.sources(for: .display, includeCurrentApplication: false, preferredMethod: .legacy).then { displaySources in
let displaySource = displaySources.first.map { Unmanaged.passRetained($0).toOpaque() } callback(data, displaySources as CFArray, nil)
callback(data, displaySource, nil)
}.catch { error in }.catch { error in
callback(data, nil, error.localizedDescription as CFString) callback(data, nil, error.localizedDescription as CFString)
} }

View file

@ -60,7 +60,8 @@ fn main() {
let mut track_changes = room_b.remote_video_track_updates(); let mut track_changes = room_b.remote_video_track_updates();
let display = live_kit_client::display_source().await.unwrap(); let displays = live_kit_client::display_sources().await.unwrap();
let display = displays.into_iter().next().unwrap();
let track_a = LocalVideoTrack::screen_share_for_display(&display); let track_a = LocalVideoTrack::screen_share_for_display(&display);
room_a.publish_video_track(&track_a).await.unwrap(); room_a.publish_video_track(&track_a).await.unwrap();
@ -68,19 +69,13 @@ fn main() {
let next_update = track_changes.next().await.unwrap(); let next_update = track_changes.next().await.unwrap();
if let RemoteVideoTrackUpdate::Subscribed(track) = next_update { if let RemoteVideoTrackUpdate::Subscribed(track) = next_update {
println!("A !!!!!!!!!!!!");
let remote_tracks = room_b.remote_video_tracks("test-participant-1"); let remote_tracks = room_b.remote_video_tracks("test-participant-1");
println!("B !!!!!!!!!!!!");
assert_eq!(remote_tracks.len(), 1); assert_eq!(remote_tracks.len(), 1);
println!("C !!!!!!!!!!!!");
assert_eq!(remote_tracks[0].publisher_id(), "test-participant-1"); assert_eq!(remote_tracks[0].publisher_id(), "test-participant-1");
println!("D !!!!!!!!!!!!"); assert_eq!(track.publisher_id(), "test-participant-1");
// dbg!(track.id());
// assert_eq!(track.id(), "test-participant-1");
} else { } else {
panic!("unexpected message") panic!("unexpected message")
} }
println!("E !!!!!!!!!!!!");
cx.platform().quit(); cx.platform().quit();
}) })

View file

@ -1,7 +1,7 @@
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use core_foundation::{ use core_foundation::{
array::{CFArray, CFArrayRef}, array::{CFArray, CFArrayRef},
base::TCFType, base::{CFRetain, TCFType},
string::{CFString, CFStringRef}, string::{CFString, CFStringRef},
}; };
use futures::{ use futures::{
@ -65,11 +65,11 @@ extern "C" {
fn LKVideoTrackAddRenderer(track: *const c_void, renderer: *const c_void); fn LKVideoTrackAddRenderer(track: *const c_void, renderer: *const c_void);
fn LKRemoteVideoTrackGetSid(track: *const c_void) -> CFStringRef; fn LKRemoteVideoTrackGetSid(track: *const c_void) -> CFStringRef;
fn LKDisplaySource( fn LKDisplaySources(
callback_data: *mut c_void, callback_data: *mut c_void,
callback: extern "C" fn( callback: extern "C" fn(
callback_data: *mut c_void, callback_data: *mut c_void,
source: *mut c_void, sources: CFArrayRef,
error: CFStringRef, error: CFStringRef,
), ),
); );
@ -119,33 +119,29 @@ impl Room {
async { rx.await.unwrap().context("error publishing video track") } async { rx.await.unwrap().context("error publishing video track") }
} }
pub fn remote_video_tracks(&self, participant_sid: &sid) -> Vec<Arc<RemoteVideoTrack>> { pub fn remote_video_tracks(&self, participant_id: &str) -> Vec<Arc<RemoteVideoTrack>> {
unsafe { unsafe {
let tracks = LKRoomVideoTracksForRemoteParticipant( let tracks = LKRoomVideoTracksForRemoteParticipant(
self.native_room, self.native_room,
CFString::new(participant_sid).as_concrete_TypeRef(), CFString::new(participant_id).as_concrete_TypeRef(),
); );
if tracks.is_null() { if tracks.is_null() {
Vec::new() Vec::new()
} else { } else {
println!("aaaa >>>>>>>>>>>>>>>");
let tracks = CFArray::wrap_under_get_rule(tracks); let tracks = CFArray::wrap_under_get_rule(tracks);
println!("bbbb >>>>>>>>>>>>>>>");
tracks tracks
.into_iter() .into_iter()
.map(|native_track| { .map(|native_track| {
let native_track = *native_track; let native_track = *native_track;
println!("cccc >>>>>>>>>>>>>>>");
let id = let id =
CFString::wrap_under_get_rule(LKRemoteVideoTrackGetSid(native_track)) CFString::wrap_under_get_rule(LKRemoteVideoTrackGetSid(native_track))
.to_string(); .to_string();
println!("dddd >>>>>>>>>>>>>>>"); Arc::new(RemoteVideoTrack::new(
Arc::new(RemoteVideoTrack {
native_track, native_track,
publisher_id: participant_sid.into(),
id, id,
}) participant_id.into(),
))
}) })
.collect() .collect()
} }
@ -235,15 +231,10 @@ impl RoomDelegate {
let room = unsafe { Weak::from_raw(room as *mut Room) }; let room = unsafe { Weak::from_raw(room as *mut Room) };
let publisher_id = unsafe { CFString::wrap_under_get_rule(publisher_id).to_string() }; let publisher_id = unsafe { CFString::wrap_under_get_rule(publisher_id).to_string() };
let track_id = unsafe { CFString::wrap_under_get_rule(track_id).to_string() }; let track_id = unsafe { CFString::wrap_under_get_rule(track_id).to_string() };
let track = RemoteVideoTrack { let track = RemoteVideoTrack::new(track, track_id, publisher_id);
id: track_id,
native_track: track,
publisher_id,
};
if let Some(room) = room.upgrade() { if let Some(room) = room.upgrade() {
room.did_subscribe_to_remote_video_track(track); room.did_subscribe_to_remote_video_track(track);
} }
// let _ = Weak::into_raw(room);
} }
extern "C" fn on_did_unsubscribe_from_remote_video_track( extern "C" fn on_did_unsubscribe_from_remote_video_track(
@ -286,12 +277,23 @@ impl Drop for LocalVideoTrack {
#[derive(Debug)] #[derive(Debug)]
pub struct RemoteVideoTrack { pub struct RemoteVideoTrack {
id: Sid,
native_track: *const c_void, native_track: *const c_void,
publisher_id: Sid, id: Sid,
publisher_id: String,
} }
impl RemoteVideoTrack { impl RemoteVideoTrack {
pub fn new(native_track: *const c_void, id: Sid, publisher_id: String) -> Self {
unsafe {
CFRetain(native_track);
}
Self {
native_track,
id,
publisher_id,
}
}
pub fn id(&self) -> &str { pub fn id(&self) -> &str {
&self.id &self.id
} }
@ -343,22 +345,35 @@ pub enum RemoteVideoTrackUpdate {
pub struct MacOSDisplay(*const c_void); pub struct MacOSDisplay(*const c_void);
impl MacOSDisplay {
fn new(ptr: *const c_void) -> Self {
unsafe {
CFRetain(ptr);
}
Self(ptr)
}
}
impl Drop for MacOSDisplay { impl Drop for MacOSDisplay {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { LKRelease(self.0) } unsafe { LKRelease(self.0) }
} }
} }
pub fn display_source() -> impl Future<Output = Result<MacOSDisplay>> { pub fn display_sources() -> impl Future<Output = Result<Vec<MacOSDisplay>>> {
extern "C" fn callback(tx: *mut c_void, source: *mut c_void, error: CFStringRef) { extern "C" fn callback(tx: *mut c_void, sources: CFArrayRef, error: CFStringRef) {
unsafe { unsafe {
let tx = Box::from_raw(tx as *mut oneshot::Sender<Result<MacOSDisplay>>); let tx = Box::from_raw(tx as *mut oneshot::Sender<Result<Vec<MacOSDisplay>>>);
if source.is_null() { if sources.is_null() {
let _ = tx.send(Err(anyhow!("{}", CFString::wrap_under_get_rule(error)))); let _ = tx.send(Err(anyhow!("{}", CFString::wrap_under_get_rule(error))));
} else { } else {
let source = MacOSDisplay(source); let sources = CFArray::wrap_under_get_rule(sources)
let _ = tx.send(Ok(source)); .into_iter()
.map(|source| MacOSDisplay::new(*source))
.collect();
let _ = tx.send(Ok(sources));
} }
} }
} }
@ -366,7 +381,7 @@ pub fn display_source() -> impl Future<Output = Result<MacOSDisplay>> {
let (tx, rx) = oneshot::channel(); let (tx, rx) = oneshot::channel();
unsafe { unsafe {
LKDisplaySource(Box::into_raw(Box::new(tx)) as *mut _, callback); LKDisplaySources(Box::into_raw(Box::new(tx)) as *mut _, callback);
} }
async move { rx.await.unwrap() } async move { rx.await.unwrap() }