cleanup: room & dependencies (#76)
This commit is contained in:
@@ -28,6 +28,3 @@ livekit-api = { path = "../livekit-api", version = "0.1.0" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "staticlib"]
|
||||
|
||||
[profile.release]
|
||||
opt-level = "z"
|
||||
|
||||
@@ -18,7 +18,7 @@ message AllocAudioBufferResponse { AudioFrameBufferInfo buffer = 1; }
|
||||
// Create a new AudioStream
|
||||
// AudioStream is used to receive audio frames from a track
|
||||
message NewAudioStreamRequest {
|
||||
FFIHandleId room_handle = 1;
|
||||
FfiHandleId room_handle = 1;
|
||||
string participant_sid = 2;
|
||||
string track_sid = 3;
|
||||
AudioStreamType type = 4;
|
||||
@@ -31,21 +31,21 @@ message NewAudioSourceResponse { AudioSourceInfo source = 1; }
|
||||
|
||||
// Push a frame to an AudioSource
|
||||
message CaptureAudioFrameRequest {
|
||||
FFIHandleId source_handle = 1;
|
||||
FFIHandleId buffer_handle = 2;
|
||||
FfiHandleId source_handle = 1;
|
||||
FfiHandleId buffer_handle = 2;
|
||||
}
|
||||
message CaptureAudioFrameResponse {}
|
||||
|
||||
// Create a new AudioResampler
|
||||
message NewAudioResamplerRequest {}
|
||||
message NewAudioResamplerResponse {
|
||||
FFIHandleId handle = 1;
|
||||
FfiHandleId handle = 1;
|
||||
}
|
||||
|
||||
// Remix and resample an audio frame
|
||||
message RemixAndResampleRequest {
|
||||
FFIHandleId resampler_handle = 1;
|
||||
FFIHandleId buffer_handle = 2;
|
||||
FfiHandleId resampler_handle = 1;
|
||||
FfiHandleId buffer_handle = 2;
|
||||
uint32 num_channels = 3;
|
||||
uint32 sample_rate = 4;
|
||||
}
|
||||
@@ -59,7 +59,7 @@ message RemixAndResampleResponse {
|
||||
///
|
||||
|
||||
message AudioFrameBufferInfo {
|
||||
FFIHandleId handle = 1;
|
||||
FfiHandleId handle = 1;
|
||||
uint64 data_ptr = 2; // *const i16
|
||||
uint32 num_channels = 3;
|
||||
uint32 sample_rate = 4;
|
||||
@@ -76,13 +76,13 @@ enum AudioStreamType {
|
||||
}
|
||||
|
||||
message AudioStreamInfo {
|
||||
FFIHandleId handle = 1;
|
||||
FfiHandleId handle = 1;
|
||||
AudioStreamType type = 2;
|
||||
string track_sid = 3;
|
||||
}
|
||||
|
||||
message AudioStreamEvent {
|
||||
FFIHandleId handle = 1;
|
||||
FfiHandleId handle = 1;
|
||||
oneof message { AudioFrameReceived frame_received = 2; }
|
||||
}
|
||||
|
||||
@@ -99,6 +99,6 @@ enum AudioSourceType {
|
||||
}
|
||||
|
||||
message AudioSourceInfo {
|
||||
FFIHandleId handle = 1;
|
||||
FfiHandleId handle = 1;
|
||||
AudioSourceType type = 2;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import "audio_frame.proto";
|
||||
|
||||
/// This is the input of livekit_ffi_request function
|
||||
/// We always expect a response (FFIResponse)
|
||||
message FFIRequest {
|
||||
message FfiRequest {
|
||||
oneof message {
|
||||
InitializeRequest initialize = 1;
|
||||
DisposeRequest dispose = 2;
|
||||
@@ -33,7 +33,7 @@ message FFIRequest {
|
||||
NewVideoSourceRequest new_video_source = 11;
|
||||
CaptureVideoFrameRequest capture_video_frame = 12;
|
||||
ToI420Request to_i420 = 13;
|
||||
ToARGBRequest to_argb = 14;
|
||||
ToArgbRequest to_argb = 14;
|
||||
|
||||
// Audio
|
||||
AllocAudioBufferRequest alloc_audio_buffer = 15;
|
||||
@@ -46,7 +46,7 @@ message FFIRequest {
|
||||
}
|
||||
|
||||
/// This is the output of livekit_ffi_request function.
|
||||
message FFIResponse {
|
||||
message FfiResponse {
|
||||
oneof message {
|
||||
InitializeResponse initialize = 1;
|
||||
DisposeResponse dispose = 2;
|
||||
@@ -67,7 +67,7 @@ message FFIResponse {
|
||||
NewVideoSourceResponse new_video_source = 11;
|
||||
CaptureVideoFrameResponse capture_video_frame = 12;
|
||||
ToI420Response to_i420 = 13;
|
||||
ToARGBResponse to_argb = 14;
|
||||
ToArgbResponse to_argb = 14;
|
||||
|
||||
// Audio
|
||||
AllocAudioBufferResponse alloc_audio_buffer = 15;
|
||||
@@ -79,7 +79,7 @@ message FFIResponse {
|
||||
}
|
||||
}
|
||||
|
||||
message FFIEvent {
|
||||
message FfiEvent {
|
||||
oneof message {
|
||||
RoomEvent room_event = 1;
|
||||
TrackEvent track_event = 2;
|
||||
@@ -104,11 +104,11 @@ message DisposeRequest {
|
||||
}
|
||||
|
||||
message DisposeResponse {
|
||||
optional FFIAsyncId async_id = 1; // None if sync
|
||||
optional FfiAsyncId async_id = 1; // None if sync
|
||||
}
|
||||
|
||||
message DisposeCallback {
|
||||
FFIAsyncId async_id = 1;
|
||||
FfiAsyncId async_id = 1;
|
||||
}
|
||||
|
||||
// TODO(theomonnom): Debug messages (Print handles, forward logs).
|
||||
|
||||
@@ -7,11 +7,11 @@ option csharp_namespace = "LiveKit.Proto";
|
||||
/// The foreign language is responsable for disposing handles
|
||||
/// Forgetting to dispose the handle may lead to memory leaks
|
||||
/// Messages in this file can contain an FFIHandle
|
||||
message FFIHandleId {
|
||||
message FfiHandleId {
|
||||
uint64 id = 1;
|
||||
}
|
||||
|
||||
/// Link the request/response of an asynchronous call
|
||||
message FFIAsyncId {
|
||||
message FfiAsyncId {
|
||||
uint64 id = 1;
|
||||
}
|
||||
|
||||
@@ -15,42 +15,42 @@ message ConnectRequest {
|
||||
RoomOptions options = 3;
|
||||
}
|
||||
message ConnectResponse {
|
||||
FFIAsyncId async_id = 1;
|
||||
FfiAsyncId async_id = 1;
|
||||
}
|
||||
message ConnectCallback {
|
||||
FFIAsyncId async_id = 1;
|
||||
FfiAsyncId async_id = 1;
|
||||
optional string error = 2;
|
||||
RoomInfo room = 3;
|
||||
}
|
||||
|
||||
// Disconnect from the a room
|
||||
message DisconnectRequest { FFIHandleId room_handle = 1; }
|
||||
message DisconnectResponse { FFIAsyncId async_id = 1; }
|
||||
message DisconnectRequest { FfiHandleId room_handle = 1; }
|
||||
message DisconnectResponse { FfiAsyncId async_id = 1; }
|
||||
message DisconnectCallback { }
|
||||
|
||||
// Publish a track to the room
|
||||
message PublishTrackRequest {
|
||||
FFIHandleId room_handle = 1;
|
||||
FFIHandleId track_handle = 2;
|
||||
FfiHandleId room_handle = 1;
|
||||
FfiHandleId track_handle = 2;
|
||||
TrackPublishOptions options = 3;
|
||||
}
|
||||
message PublishTrackResponse {
|
||||
FFIAsyncId async_id = 1;
|
||||
FfiAsyncId async_id = 1;
|
||||
}
|
||||
message PublishTrackCallback {
|
||||
FFIAsyncId async_id = 1;
|
||||
FfiAsyncId async_id = 1;
|
||||
optional string error = 2;
|
||||
TrackPublicationInfo publication = 3;
|
||||
}
|
||||
|
||||
// Unpublish a track from the room
|
||||
message UnpublishTrackRequest {
|
||||
FFIHandleId room_handle = 1;
|
||||
FfiHandleId room_handle = 1;
|
||||
string track_sid = 2;
|
||||
bool stop_on_unpublish = 3;
|
||||
}
|
||||
message UnpublishTrackResponse {
|
||||
FFIAsyncId async_id = 1;
|
||||
FfiAsyncId async_id = 1;
|
||||
}
|
||||
message UnpublishTrackCallback {
|
||||
optional string error = 1;
|
||||
@@ -109,7 +109,7 @@ enum DataPacketKind {
|
||||
}
|
||||
|
||||
message RoomEvent {
|
||||
FFIHandleId room_handle = 1;
|
||||
FfiHandleId room_handle = 1;
|
||||
oneof message {
|
||||
ParticipantConnected participant_connected = 2;
|
||||
ParticipantDisconnected participant_disconnected = 3;
|
||||
@@ -131,7 +131,7 @@ message RoomEvent {
|
||||
}
|
||||
|
||||
message RoomInfo {
|
||||
FFIHandleId handle = 1;
|
||||
FfiHandleId handle = 1;
|
||||
string sid = 2;
|
||||
string name = 3;
|
||||
string metadata = 4;
|
||||
@@ -140,7 +140,7 @@ message RoomInfo {
|
||||
}
|
||||
|
||||
message DataReceived {
|
||||
FFIHandleId handle = 1;
|
||||
FfiHandleId handle = 1;
|
||||
optional string participant_sid = 2;
|
||||
uint64 data_ptr = 3;
|
||||
uint64 data_size = 4;
|
||||
|
||||
@@ -21,7 +21,7 @@ message AudioCaptureOptions {
|
||||
message CreateVideoTrackRequest {
|
||||
string name = 1;
|
||||
VideoCaptureOptions options = 2;
|
||||
FFIHandleId source_handle = 3;
|
||||
FfiHandleId source_handle = 3;
|
||||
}
|
||||
message CreateVideoTrackResponse {
|
||||
TrackInfo track = 1;
|
||||
@@ -31,7 +31,7 @@ message CreateVideoTrackResponse {
|
||||
message CreateAudioTrackRequest {
|
||||
string name = 1;
|
||||
AudioCaptureOptions options = 2;
|
||||
FFIHandleId source_handle = 3;
|
||||
FfiHandleId source_handle = 3;
|
||||
}
|
||||
message CreateAudioTrackResponse {
|
||||
TrackInfo track = 1;
|
||||
@@ -80,7 +80,7 @@ message TrackPublicationInfo {
|
||||
|
||||
message TrackInfo {
|
||||
// Tracks created/owned by the client will have a handle
|
||||
FFIHandleId opt_handle = 1;
|
||||
FfiHandleId opt_handle = 1;
|
||||
string sid = 2;
|
||||
string name = 3;
|
||||
TrackKind kind = 4;
|
||||
|
||||
@@ -16,7 +16,7 @@ message AllocVideoBufferResponse { VideoFrameBufferInfo buffer = 1; }
|
||||
// Create a new VideoStream
|
||||
// VideoStream is used to receive video frames from a track
|
||||
message NewVideoStreamRequest {
|
||||
FFIHandleId room_handle = 1;
|
||||
FfiHandleId room_handle = 1;
|
||||
string participant_sid = 2;
|
||||
string track_sid = 3;
|
||||
VideoStreamType type = 4;
|
||||
@@ -30,9 +30,9 @@ message NewVideoSourceResponse { VideoSourceInfo source = 1; }
|
||||
|
||||
// Push a frame to a VideoSource
|
||||
message CaptureVideoFrameRequest {
|
||||
FFIHandleId source_handle = 1;
|
||||
FfiHandleId source_handle = 1;
|
||||
VideoFrameInfo frame = 2;
|
||||
FFIHandleId buffer_handle = 3;
|
||||
FfiHandleId buffer_handle = 3;
|
||||
}
|
||||
message CaptureVideoFrameResponse {}
|
||||
|
||||
@@ -42,15 +42,15 @@ message ToI420Request {
|
||||
bool flip_y = 1;
|
||||
oneof from {
|
||||
ARGBBufferInfo argb = 2;
|
||||
FFIHandleId buffer = 3;
|
||||
FfiHandleId buffer = 3;
|
||||
}
|
||||
}
|
||||
message ToI420Response { VideoFrameBufferInfo buffer = 1; }
|
||||
|
||||
// Convert a YUV frame to a RGBA frame
|
||||
// Only I420 is supported atm
|
||||
message ToARGBRequest {
|
||||
FFIHandleId buffer = 1;
|
||||
message ToArgbRequest {
|
||||
FfiHandleId buffer = 1;
|
||||
uint64 dst_ptr = 2;
|
||||
VideoFormatType dst_format = 3;
|
||||
uint32 dst_stride = 4;
|
||||
@@ -58,7 +58,7 @@ message ToARGBRequest {
|
||||
uint32 dst_height = 6;
|
||||
bool flip_y = 7;
|
||||
}
|
||||
message ToARGBResponse {}
|
||||
message ToArgbResponse {}
|
||||
|
||||
///
|
||||
/// VideoFrame buffers ///
|
||||
@@ -115,7 +115,7 @@ message VideoFrameInfo {
|
||||
}
|
||||
|
||||
message VideoFrameBufferInfo {
|
||||
FFIHandleId handle = 1;
|
||||
FfiHandleId handle = 1;
|
||||
VideoFrameBufferType buffer_type = 2;
|
||||
uint32 width = 3;
|
||||
uint32 height = 4;
|
||||
@@ -166,13 +166,13 @@ enum VideoStreamType {
|
||||
}
|
||||
|
||||
message VideoStreamInfo {
|
||||
FFIHandleId handle = 1;
|
||||
FfiHandleId handle = 1;
|
||||
VideoStreamType type = 2;
|
||||
string track_sid = 3;
|
||||
}
|
||||
|
||||
message VideoStreamEvent {
|
||||
FFIHandleId handle = 1;
|
||||
FfiHandleId handle = 1;
|
||||
oneof message { VideoFrameReceived frame_received = 2; }
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ enum VideoSourceType {
|
||||
message VideoSourceInfo {
|
||||
// # SAFETY
|
||||
// This handle must not be dropped if a track is currently using it
|
||||
FFIHandleId handle = 1;
|
||||
FfiHandleId handle = 1;
|
||||
VideoSourceType type = 2;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ impl proto::RoomEvent {
|
||||
}
|
||||
|
||||
impl proto::RoomInfo {
|
||||
pub fn from_session(handle_id: FfiHandleId, session: &RoomSession) -> Self {
|
||||
pub fn from_room(handle_id: FfiHandleId, session: &Room) -> Self {
|
||||
Self {
|
||||
handle: Some(handle_id.into()),
|
||||
sid: session.sid().into(),
|
||||
|
||||
@@ -60,6 +60,7 @@ impl_publication_into!(&TrackPublication);
|
||||
macro_rules! impl_track_into {
|
||||
($fnc:ident, $t:ty) => {
|
||||
impl proto::TrackInfo {
|
||||
#[allow(dead_code)]
|
||||
pub fn $fnc(handle_id: FfiHandleId, track: $t) -> Self {
|
||||
Self {
|
||||
opt_handle: Some(handle_id.into()),
|
||||
|
||||
@@ -157,8 +157,7 @@ impl FfiAudioSource {
|
||||
proto::AudioSourceType::AudioSourceNative => {
|
||||
let audio_source = NativeAudioSource::default();
|
||||
Ok::<AudioSource, FfiError>(AudioSource::Native(audio_source))
|
||||
}
|
||||
_ => return Err(FfiError::InvalidRequest("unsupported audio source type")),
|
||||
} //_ => return Err(FfiError::InvalidRequest("unsupported audio source type")),
|
||||
}?;
|
||||
|
||||
let audio_source = Self {
|
||||
|
||||
@@ -209,12 +209,12 @@ impl FfiServer {
|
||||
.ok_or(FfiError::InvalidRequest("room_handle is empty"))?
|
||||
.id as FfiHandleId;
|
||||
|
||||
let room = self
|
||||
let ffi_room = self
|
||||
.ffi_handles
|
||||
.get(&room_handle)
|
||||
.ok_or(FfiError::InvalidRequest("room not found"))?;
|
||||
|
||||
let room = room
|
||||
let ffi_room = ffi_room
|
||||
.downcast_ref::<room::FfiRoom>()
|
||||
.ok_or(FfiError::InvalidRequest("room is not a FfiRoom"))?;
|
||||
|
||||
@@ -233,8 +233,8 @@ impl FfiServer {
|
||||
.downcast_ref::<LocalTrack>()
|
||||
.ok_or(FfiError::InvalidRequest("track is not a LocalTrack"))?;
|
||||
|
||||
let publication = room
|
||||
.session()
|
||||
let publication = ffi_room
|
||||
.room()
|
||||
.local_participant()
|
||||
.publish_track(
|
||||
track.clone(),
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use crate::server::FfiServer;
|
||||
use crate::{proto, FfiHandleId, FfiResult};
|
||||
use livekit::prelude::*;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
pub struct FfiRoom {
|
||||
room: Room,
|
||||
handle_id: FfiHandleId,
|
||||
room: Arc<Room>,
|
||||
handle: JoinHandle<()>,
|
||||
close_tx: oneshot::Sender<()>,
|
||||
}
|
||||
@@ -17,45 +17,42 @@ impl FfiRoom {
|
||||
connect: proto::ConnectRequest,
|
||||
) -> FfiResult<proto::RoomInfo> {
|
||||
let (room, events) = Room::connect(&connect.url, &connect.token).await?;
|
||||
let room = Arc::new(room);
|
||||
let (close_tx, close_rx) = oneshot::channel();
|
||||
let session = room.session();
|
||||
let next_id = server.next_id() as FfiHandleId;
|
||||
|
||||
let handle = server.async_runtime.spawn(room_task(
|
||||
server,
|
||||
session.clone(),
|
||||
next_id,
|
||||
events,
|
||||
close_rx,
|
||||
));
|
||||
let room_info = proto::RoomInfo::from_session(next_id, &session);
|
||||
let handle =
|
||||
server
|
||||
.async_runtime
|
||||
.spawn(room_task(server, room.clone(), next_id, events, close_rx));
|
||||
let room_info = proto::RoomInfo::from_room(next_id, &room);
|
||||
|
||||
let ffi_room = Self {
|
||||
handle_id: next_id,
|
||||
room,
|
||||
room: room.clone(),
|
||||
handle,
|
||||
close_tx,
|
||||
};
|
||||
|
||||
server.ffi_handles().insert(next_id, Box::new(ffi_room));
|
||||
server.rooms().lock().insert(session.sid(), next_id);
|
||||
server.rooms().lock().insert(room.sid(), next_id);
|
||||
|
||||
Ok(room_info)
|
||||
}
|
||||
|
||||
pub async fn close(self) {
|
||||
self.room.close().await;
|
||||
let _ = self.room.close().await;
|
||||
let _ = self.close_tx.send(());
|
||||
let _ = self.handle.await;
|
||||
}
|
||||
|
||||
pub fn session(&self) -> RoomSession {
|
||||
self.room.session()
|
||||
pub fn room(&self) -> &Arc<Room> {
|
||||
&self.room
|
||||
}
|
||||
}
|
||||
|
||||
async fn room_task(
|
||||
server: &'static FfiServer,
|
||||
session: RoomSession,
|
||||
room: Arc<Room>,
|
||||
room_handle: FfiHandleId,
|
||||
mut events: mpsc::UnboundedReceiver<livekit::RoomEvent>,
|
||||
mut close_rx: oneshot::Receiver<()>,
|
||||
@@ -63,7 +60,7 @@ async fn room_task(
|
||||
server
|
||||
.async_runtime
|
||||
.spawn(participant_task(Participant::Local(
|
||||
session.local_participant(),
|
||||
room.local_participant(),
|
||||
)));
|
||||
|
||||
loop {
|
||||
|
||||
@@ -12,8 +12,8 @@ mod client {
|
||||
INVALID_HANDLE,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use parking_lot::Mutex;
|
||||
use prost::Message;
|
||||
use std::sync::Mutex;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
lazy_static! {
|
||||
@@ -31,7 +31,7 @@ mod client {
|
||||
impl Default for FfiClient {
|
||||
fn default() -> Self {
|
||||
let (event_tx, event_rx) = mpsc::unbounded_channel();
|
||||
*EVENT_TX.lock().unwrap() = Some(event_tx);
|
||||
*EVENT_TX.lock() = Some(event_tx);
|
||||
Self { event_rx }
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,6 @@ mod client {
|
||||
let event = proto::FfiEvent::decode(data).unwrap();
|
||||
EVENT_TX
|
||||
.lock()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.send(event.message.unwrap())
|
||||
@@ -99,9 +98,9 @@ mod client {
|
||||
struct TestScope {}
|
||||
|
||||
impl TestScope {
|
||||
fn new() -> (Self, std::sync::MutexGuard<'static, client::FfiClient>) {
|
||||
fn new() -> (Self, parking_lot::MutexGuard<'static, client::FfiClient>) {
|
||||
// Run one test at a time
|
||||
let client = client::FFI_CLIENT.lock().unwrap();
|
||||
let client = client::FFI_CLIENT.lock();
|
||||
|
||||
(TestScope {}, client)
|
||||
}
|
||||
@@ -176,7 +175,7 @@ fn create_i420_buffer() {
|
||||
#[test]
|
||||
#[ignore] // Ignore for now ( need to setup GHA )
|
||||
fn publish_video_track() {
|
||||
let (test, mut client) = TestScope::new();
|
||||
let (_test, mut client) = TestScope::new();
|
||||
let (lk_url, lk_api_key, lk_api_secret) = test_env();
|
||||
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
|
||||
@@ -7,17 +7,17 @@ pub fn find_remote_track(
|
||||
participant_sid: &ParticipantSid,
|
||||
room_handle: FfiHandleId,
|
||||
) -> FfiResult<RemoteTrack> {
|
||||
let room = server
|
||||
let ffi_room = server
|
||||
.ffi_handles()
|
||||
.get(&room_handle)
|
||||
.ok_or(FfiError::InvalidRequest("room not found"))?;
|
||||
|
||||
let room = room
|
||||
let ffi_room = ffi_room
|
||||
.downcast_ref::<server::room::FfiRoom>()
|
||||
.ok_or(FfiError::InvalidRequest("room is not ffi room"))?;
|
||||
|
||||
let session = room.session();
|
||||
let participants = session.participants();
|
||||
let room = ffi_room.room();
|
||||
let participants = room.participants();
|
||||
let participant = participants
|
||||
.get(participant_sid)
|
||||
.ok_or(FfiError::InvalidRequest("participant not found"))?;
|
||||
|
||||
@@ -160,10 +160,9 @@ impl FfiVideoSource {
|
||||
let source_inner = match source_type {
|
||||
proto::VideoSourceType::VideoSourceNative => {
|
||||
let video_source = NativeVideoSource::default();
|
||||
Ok(VideoSource::Native(video_source))
|
||||
VideoSource::Native(video_source)
|
||||
}
|
||||
_ => Err(FfiError::InvalidRequest("unsupported video source type")),
|
||||
}?;
|
||||
};
|
||||
|
||||
let video_source = Self {
|
||||
handle_id: server.next_id(),
|
||||
|
||||
Reference in New Issue
Block a user