From 3ea84b15179c97733f6b0ed452dbde6416062023 Mon Sep 17 00:00:00 2001 From: Daniel Abramov Date: Mon, 1 Jan 2024 23:02:02 +0100 Subject: [PATCH] add rustfmt.toml configuration and re-format everything + fix basic warnings (#279) --- .github/workflows/format.yml | 36 ++ libwebrtc/src/audio_source.rs | 10 +- libwebrtc/src/audio_stream.rs | 23 +- libwebrtc/src/audio_track.rs | 8 +- libwebrtc/src/data_channel.rs | 6 +- libwebrtc/src/ice_candidate.rs | 7 +- libwebrtc/src/lib.rs | 5 +- libwebrtc/src/media_stream.rs | 5 +- libwebrtc/src/media_stream_track.rs | 4 +- libwebrtc/src/native/audio_resampler.rs | 9 +- libwebrtc/src/native/audio_source.rs | 30 +- libwebrtc/src/native/audio_stream.rs | 19 +- libwebrtc/src/native/audio_track.rs | 5 +- libwebrtc/src/native/data_channel.rs | 27 +- libwebrtc/src/native/frame_cryptor.rs | 31 +- libwebrtc/src/native/ice_candidate.rs | 8 +- libwebrtc/src/native/media_stream.rs | 18 +- libwebrtc/src/native/media_stream_track.rs | 29 +- libwebrtc/src/native/mod.rs | 14 +- libwebrtc/src/native/peer_connection.rs | 236 +++++-------- .../src/native/peer_connection_factory.rs | 55 ++- libwebrtc/src/native/rtp_parameters.rs | 48 +-- libwebrtc/src/native/rtp_receiver.rs | 15 +- libwebrtc/src/native/rtp_sender.rs | 23 +- libwebrtc/src/native/rtp_transceiver.rs | 32 +- libwebrtc/src/native/session_description.rs | 12 +- libwebrtc/src/native/video_frame.rs | 90 ++--- libwebrtc/src/native/video_source.rs | 47 +-- libwebrtc/src/native/video_stream.rs | 24 +- libwebrtc/src/native/video_track.rs | 5 +- libwebrtc/src/peer_connection.rs | 39 ++- libwebrtc/src/peer_connection_factory.rs | 18 +- libwebrtc/src/prelude.rs | 55 +-- libwebrtc/src/rtp_sender.rs | 4 +- libwebrtc/src/rtp_transceiver.rs | 13 +- libwebrtc/src/session_description.rs | 8 +- libwebrtc/src/stats.rs | 10 +- libwebrtc/src/video_frame.rs | 35 +- libwebrtc/src/video_source.rs | 7 +- libwebrtc/src/video_stream.rs | 23 +- libwebrtc/src/video_track.rs | 8 +- livekit-api/src/access_token.rs | 27 +- livekit-api/src/services/egress.rs | 102 ++---- livekit-api/src/services/ingress.rs | 30 +- livekit-api/src/services/mod.rs | 20 +- livekit-api/src/services/room.rs | 29 +- livekit-api/src/services/twirp_client.rs | 21 +- livekit-api/src/signal_client/mod.rs | 88 ++--- .../src/signal_client/signal_stream.rs | 53 +-- livekit-api/src/webhooks.rs | 3 +- livekit-ffi/build.rs | 3 +- livekit-ffi/src/cabi.rs | 13 +- livekit-ffi/src/conversion/audio_frame.rs | 19 +- livekit-ffi/src/conversion/participant.rs | 3 +- livekit-ffi/src/conversion/room.rs | 57 ++-- livekit-ffi/src/conversion/stats.rs | 83 ++--- livekit-ffi/src/conversion/track.rs | 3 +- livekit-ffi/src/conversion/video_frame.rs | 29 +- livekit-ffi/src/lib.rs | 5 +- livekit-ffi/src/server/audio_source.rs | 15 +- livekit-ffi/src/server/audio_stream.rs | 37 +-- livekit-ffi/src/server/logger.rs | 11 +- livekit-ffi/src/server/mod.rs | 58 ++-- livekit-ffi/src/server/requests.rs | 164 ++++----- livekit-ffi/src/server/room.rs | 287 +++++----------- livekit-ffi/src/server/video_source.rs | 38 +-- livekit-ffi/src/server/video_stream.rs | 37 +-- livekit-protocol/src/debouncer.rs | 8 +- livekit-protocol/src/observer.rs | 18 +- livekit/src/prelude.rs | 18 +- livekit/src/proto.rs | 3 +- livekit/src/room/e2ee/manager.rs | 50 ++- livekit/src/room/mod.rs | 248 +++++--------- livekit/src/room/options.rs | 26 +- .../src/room/participant/local_participant.rs | 68 ++-- livekit/src/room/participant/mod.rs | 9 +- .../room/participant/remote_participant.rs | 33 +- livekit/src/room/publication/local.rs | 17 +- livekit/src/room/publication/mod.rs | 16 +- livekit/src/room/publication/remote.rs | 44 +-- livekit/src/room/track/audio_track.rs | 5 +- livekit/src/room/track/local_audio_track.rs | 13 +- livekit/src/room/track/local_track.rs | 8 +- livekit/src/room/track/local_video_track.rs | 13 +- livekit/src/room/track/mod.rs | 10 +- livekit/src/room/track/remote_audio_track.rs | 10 +- livekit/src/room/track/remote_track.rs | 12 +- livekit/src/room/track/remote_video_track.rs | 13 +- livekit/src/room/track/video_track.rs | 5 +- livekit/src/rtc_engine/lk_runtime.rs | 11 +- livekit/src/rtc_engine/mod.rs | 106 +++--- livekit/src/rtc_engine/peer_transport.rs | 35 +- livekit/src/rtc_engine/rtc_events.rs | 39 +-- livekit/src/rtc_engine/rtc_session.rs | 312 +++++++----------- rustfmt.toml | 10 + webrtc-sys/build.rs | 29 +- webrtc-sys/build/src/lib.rs | 25 +- webrtc-sys/src/audio_track.rs | 6 +- webrtc-sys/src/data_channel.rs | 3 +- webrtc-sys/src/frame_cryptor.rs | 3 +- webrtc-sys/src/jsep.rs | 13 +- webrtc-sys/src/lib.rs | 2 +- webrtc-sys/src/peer_connection.rs | 3 +- webrtc-sys/src/peer_connection_factory.rs | 28 +- webrtc-sys/src/rtc_error.rs | 24 +- webrtc-sys/src/rtp_receiver.rs | 3 +- webrtc-sys/src/rtp_sender.rs | 3 +- webrtc-sys/src/video_track.rs | 7 +- 108 files changed, 1373 insertions(+), 2272 deletions(-) create mode 100644 .github/workflows/format.yml create mode 100644 rustfmt.toml diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 00000000..d990bb82 --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,36 @@ +name: Rust Formatting + +on: + workflow_dispatch: + push: + branches: [main] + pull_request: + branches: [main] + types: + - opened + - reopened + - synchronize + - ready_for_review + +env: + CARGO_TERM_COLOR: always + +jobs: + formatting: + name: Check Formatting + runs-on: ubuntu-latest + if: github.event_name == 'push' || !github.event.pull_request.draft + + steps: + - name: Checkout the repo + uses: actions/checkout@v3 + + - name: Install Rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: nightly-2023-12-30 + components: rustfmt + + - name: Cargo fmt + run: | + cargo fmt -- --check diff --git a/libwebrtc/src/audio_source.rs b/libwebrtc/src/audio_source.rs index f72bb1fa..131c6d9e 100644 --- a/libwebrtc/src/audio_source.rs +++ b/libwebrtc/src/audio_source.rs @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::imp::audio_source as imp_as; use livekit_protocol::enum_dispatch; +use crate::imp::audio_source as imp_as; + #[derive(Default, Debug)] pub struct AudioSourceOptions { pub echo_cancellation: bool, @@ -41,9 +42,10 @@ impl RtcAudioSource { #[cfg(not(target_arch = "wasm32"))] pub mod native { + use std::fmt::{Debug, Formatter}; + use super::*; use crate::{audio_frame::AudioFrame, RtcError}; - use std::fmt::{Debug, Formatter}; #[derive(Clone)] pub struct NativeAudioSource { @@ -62,9 +64,7 @@ pub mod native { sample_rate: u32, num_channels: u32, ) -> NativeAudioSource { - Self { - handle: imp_as::NativeAudioSource::new(options, sample_rate, num_channels), - } + Self { handle: imp_as::NativeAudioSource::new(options, sample_rate, num_channels) } } pub async fn capture_frame(&self, frame: &AudioFrame<'_>) -> Result<(), RtcError> { diff --git a/libwebrtc/src/audio_stream.rs b/libwebrtc/src/audio_stream.rs index ae7e817b..95d3644e 100644 --- a/libwebrtc/src/audio_stream.rs +++ b/libwebrtc/src/audio_stream.rs @@ -16,31 +16,30 @@ use crate::imp::audio_stream as stream_imp; #[cfg(not(target_arch = "wasm32"))] pub mod native { - use super::stream_imp; - use crate::audio_frame::AudioFrame; - use crate::audio_track::RtcAudioTrack; - use std::fmt::{Debug, Formatter}; - use std::pin::Pin; - use std::task::{Context, Poll}; + use std::{ + fmt::{Debug, Formatter}, + pin::Pin, + task::{Context, Poll}, + }; + use tokio_stream::Stream; + use super::stream_imp; + use crate::{audio_frame::AudioFrame, audio_track::RtcAudioTrack}; + pub struct NativeAudioStream { pub(crate) handle: stream_imp::NativeAudioStream, } impl Debug for NativeAudioStream { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { - f.debug_struct("NativeAudioStream") - .field("track", &self.track()) - .finish() + f.debug_struct("NativeAudioStream").field("track", &self.track()).finish() } } impl NativeAudioStream { pub fn new(audio_track: RtcAudioTrack) -> Self { - Self { - handle: stream_imp::NativeAudioStream::new(audio_track), - } + Self { handle: stream_imp::NativeAudioStream::new(audio_track) } } pub fn track(&self) -> RtcAudioTrack { diff --git a/libwebrtc/src/audio_track.rs b/libwebrtc/src/audio_track.rs index 3c7281db..768df510 100644 --- a/libwebrtc/src/audio_track.rs +++ b/libwebrtc/src/audio_track.rs @@ -12,11 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::imp::audio_track as imp_at; -use crate::media_stream_track::media_stream_track; -use crate::media_stream_track::RtcTrackState; use std::fmt::Debug; +use crate::{ + imp::audio_track as imp_at, + media_stream_track::{media_stream_track, RtcTrackState}, +}; + #[derive(Clone)] pub struct RtcAudioTrack { pub(crate) handle: imp_at::RtcAudioTrack, diff --git a/libwebrtc/src/data_channel.rs b/libwebrtc/src/data_channel.rs index 49ca4db9..a8ac1f0e 100644 --- a/libwebrtc/src/data_channel.rs +++ b/libwebrtc/src/data_channel.rs @@ -12,11 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{imp::data_channel as dc_imp, rtp_parameters::Priority}; -use serde::Deserialize; use std::{fmt::Debug, str::Utf8Error}; + +use serde::Deserialize; use thiserror::Error; +use crate::{imp::data_channel as dc_imp, rtp_parameters::Priority}; + #[derive(Clone, Debug)] pub struct DataChannelInit { pub ordered: bool, diff --git a/libwebrtc/src/ice_candidate.rs b/libwebrtc/src/ice_candidate.rs index 7f1a2cc2..b237e022 100644 --- a/libwebrtc/src/ice_candidate.rs +++ b/libwebrtc/src/ice_candidate.rs @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{imp::ice_candidate as imp_ic, session_description::SdpParseError}; use std::fmt::Debug; +use crate::{imp::ice_candidate as imp_ic, session_description::SdpParseError}; + pub struct IceCandidate { pub(crate) handle: imp_ic::IceCandidate, } @@ -49,8 +50,6 @@ impl ToString for IceCandidate { impl Debug for IceCandidate { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("IceCandidate") - .field("candidate", &self.to_string()) - .finish() + f.debug_struct("IceCandidate").field("candidate", &self.to_string()).finish() } } diff --git a/libwebrtc/src/lib.rs b/libwebrtc/src/lib.rs index 4e954f52..919da36f 100644 --- a/libwebrtc/src/lib.rs +++ b/libwebrtc/src/lib.rs @@ -64,10 +64,9 @@ pub mod video_track; #[cfg(not(target_arch = "wasm32"))] pub mod native { - pub use crate::imp::audio_resampler; - pub use crate::imp::frame_cryptor; - pub use crate::imp::yuv_helper; pub use webrtc_sys::webrtc::ffi::create_random_uuid; + + pub use crate::imp::{audio_resampler, frame_cryptor, yuv_helper}; } #[cfg(target_os = "android")] diff --git a/libwebrtc/src/media_stream.rs b/libwebrtc/src/media_stream.rs index 56b34b74..b74e716c 100644 --- a/libwebrtc/src/media_stream.rs +++ b/libwebrtc/src/media_stream.rs @@ -12,11 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::audio_track::RtcAudioTrack; -use crate::imp::media_stream as imp_ms; -use crate::video_track::RtcVideoTrack; use std::fmt::Debug; +use crate::{audio_track::RtcAudioTrack, imp::media_stream as imp_ms, video_track::RtcVideoTrack}; + #[derive(Clone)] pub struct MediaStream { pub(crate) handle: imp_ms::MediaStream, diff --git a/libwebrtc/src/media_stream_track.rs b/libwebrtc/src/media_stream_track.rs index 5efcf789..f02676a7 100644 --- a/libwebrtc/src/media_stream_track.rs +++ b/libwebrtc/src/media_stream_track.rs @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::audio_track::RtcAudioTrack; -use crate::video_track::RtcVideoTrack; use livekit_protocol::enum_dispatch; +use crate::{audio_track::RtcAudioTrack, video_track::RtcVideoTrack}; + #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum RtcTrackState { Live, diff --git a/libwebrtc/src/native/audio_resampler.rs b/libwebrtc/src/native/audio_resampler.rs index 13b43e57..17913f97 100644 --- a/libwebrtc/src/native/audio_resampler.rs +++ b/libwebrtc/src/native/audio_resampler.rs @@ -21,9 +21,7 @@ pub struct AudioResampler { impl Default for AudioResampler { fn default() -> Self { - Self { - sys_handle: sys_ar::ffi::create_audio_resampler(), - } + Self { sys_handle: sys_ar::ffi::create_audio_resampler() } } } @@ -37,10 +35,7 @@ impl AudioResampler { dst_num_channels: u32, dst_sample_rate: u32, ) -> &'a [i16] { - assert!( - src.len() >= (samples_per_channel * num_channels) as usize, - "src buffer too small" - ); + assert!(src.len() >= (samples_per_channel * num_channels) as usize, "src buffer too small"); unsafe { let len = self.sys_handle.pin_mut().remix_and_resample( diff --git a/libwebrtc/src/native/audio_source.rs b/libwebrtc/src/native/audio_source.rs index 9c3c2385..b986747e 100644 --- a/libwebrtc/src/native/audio_source.rs +++ b/libwebrtc/src/native/audio_source.rs @@ -12,15 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{audio_frame::AudioFrame, audio_source::AudioSourceOptions, RtcError, RtcErrorType}; -use cxx::SharedPtr; use std::{sync::Arc, time::Duration}; + +use cxx::SharedPtr; use tokio::{ sync::{oneshot, Mutex as AsyncMutex, MutexGuard}, time::{interval, Instant, MissedTickBehavior}, }; use webrtc_sys::audio_track as sys_at; +use crate::{audio_frame::AudioFrame, audio_source::AudioSourceOptions, RtcError, RtcErrorType}; + #[derive(Clone)] pub struct NativeAudioSource { sys_handle: SharedPtr, @@ -107,8 +109,7 @@ impl NativeAudioSource { } pub fn set_audio_options(&self, options: AudioSourceOptions) { - self.sys_handle - .set_audio_options(&sys_at::ffi::AudioSourceOptions::from(options)) + self.sys_handle.set_audio_options(&sys_at::ffi::AudioSourceOptions::from(options)) } pub fn audio_options(&self) -> AudioSourceOptions { @@ -126,7 +127,8 @@ impl NativeAudioSource { // Implemented inside another functions to allow unit testing fn next_frame<'a>( &self, - inner: &'a mut MutexGuard<'_, AudioSourceInner>, // The lock musts be guarded by capture_frame + inner: &'a mut MutexGuard<'_, AudioSourceInner>, /* The lock musts be guarded by + * capture_frame */ frame: &'a AudioFrame<'_>, ) -> Option<&'a [i16]> { let available_data = inner.len + frame.data.len() - inner.read_offset; @@ -147,7 +149,8 @@ impl NativeAudioSource { &frame.data[start..end] }) } else { - // Save to buf and wait for the next capture_frame to give enough data to complete a 10ms frame + // Save to buf and wait for the next capture_frame to give enough data to complete a + // 10ms frame let remaining_data = frame.data.len() - inner.read_offset; // remaining data from frame.data let start = inner.len; let end = start + remaining_data; @@ -296,18 +299,9 @@ mod tests { let mut inner = source.inner.lock().await; let samples_10ms = source.sample_rate() as usize / 100 * source.num_channels() as usize; - assert_eq!( - source.next_frame(&mut inner, &audio_frame).unwrap().len(), - samples_10ms - ); - assert_eq!( - source.next_frame(&mut inner, &audio_frame).unwrap().len(), - samples_10ms - ); - assert_eq!( - source.next_frame(&mut inner, &audio_frame).unwrap().len(), - samples_10ms - ); + assert_eq!(source.next_frame(&mut inner, &audio_frame).unwrap().len(), samples_10ms); + assert_eq!(source.next_frame(&mut inner, &audio_frame).unwrap().len(), samples_10ms); + assert_eq!(source.next_frame(&mut inner, &audio_frame).unwrap().len(), samples_10ms); assert!(source.next_frame(&mut inner, &audio_frame).is_none()); let samples_5ms = source.sample_rate() as usize / 1000 * 5 * source.num_channels() as usize; diff --git a/libwebrtc/src/native/audio_stream.rs b/libwebrtc/src/native/audio_stream.rs index 20ef7bb0..b8622910 100644 --- a/libwebrtc/src/native/audio_stream.rs +++ b/libwebrtc/src/native/audio_stream.rs @@ -12,16 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::audio_frame::AudioFrame; -use crate::audio_track::RtcAudioTrack; +use std::{ + pin::Pin, + sync::Arc, + task::{Context, Poll}, +}; + use cxx::SharedPtr; -use std::pin::Pin; -use std::sync::Arc; -use std::task::{Context, Poll}; use tokio::sync::mpsc; use tokio_stream::Stream; use webrtc_sys::audio_track as sys_at; +use crate::{audio_frame::AudioFrame, audio_track::RtcAudioTrack}; + pub struct NativeAudioStream { native_sink: SharedPtr, audio_track: RtcAudioTrack, @@ -39,11 +42,7 @@ impl NativeAudioStream { let audio = unsafe { sys_at::ffi::media_to_audio(audio_track.sys_handle()) }; audio.add_sink(&native_sink); - Self { - native_sink, - audio_track, - frame_rx, - } + Self { native_sink, audio_track, frame_rx } } pub fn track(&self) -> RtcAudioTrack { diff --git a/libwebrtc/src/native/audio_track.rs b/libwebrtc/src/native/audio_track.rs index 584a0746..8718b709 100644 --- a/libwebrtc/src/native/audio_track.rs +++ b/libwebrtc/src/native/audio_track.rs @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::media_stream_track::impl_media_stream_track; -use crate::media_stream_track::RtcTrackState; use cxx::SharedPtr; use sys_at::ffi::audio_to_media; use webrtc_sys::audio_track as sys_at; +use super::media_stream_track::impl_media_stream_track; +use crate::media_stream_track::RtcTrackState; + #[derive(Clone)] pub struct RtcAudioTrack { pub(crate) sys_handle: SharedPtr, diff --git a/libwebrtc/src/native/data_channel.rs b/libwebrtc/src/native/data_channel.rs index 4f7b0f21..ba36f041 100644 --- a/libwebrtc/src/native/data_channel.rs +++ b/libwebrtc/src/native/data_channel.rs @@ -12,15 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::{str, sync::Arc}; + +use cxx::SharedPtr; +use parking_lot::Mutex; +use webrtc_sys::data_channel as sys_dc; + use crate::data_channel::{ DataBuffer, DataChannelError, DataChannelInit, DataChannelState, OnBufferedAmountChange, OnMessage, OnStateChange, }; -use cxx::SharedPtr; -use parking_lot::Mutex; -use std::str; -use std::sync::Arc; -use webrtc_sys::data_channel as sys_dc; impl From for DataChannelState { fn from(value: sys_dc::ffi::DataState) -> Self { @@ -60,10 +61,7 @@ pub struct DataChannel { impl DataChannel { pub fn configure(sys_handle: SharedPtr) -> Self { let observer = Arc::new(DataChannelObserver::default()); - let dc = Self { - sys_handle: sys_handle.clone(), - observer: observer.clone(), - }; + let dc = Self { sys_handle: sys_handle.clone(), observer: observer.clone() }; dc.sys_handle .register_observer(Box::new(sys_dc::DataChannelObserverWrapper::new(observer))); @@ -75,16 +73,9 @@ impl DataChannel { str::from_utf8(data)?; } - let buffer = sys_dc::ffi::DataBuffer { - ptr: data.as_ptr(), - len: data.len(), - binary, - }; + let buffer = sys_dc::ffi::DataBuffer { ptr: data.as_ptr(), len: data.len(), binary }; - self.sys_handle - .send(&buffer) - .then_some(()) - .ok_or(DataChannelError::Send) + self.sys_handle.send(&buffer).then_some(()).ok_or(DataChannelError::Send) } pub fn id(&self) -> i32 { diff --git a/libwebrtc/src/native/frame_cryptor.rs b/libwebrtc/src/native/frame_cryptor.rs index 18191a5a..8f64e771 100644 --- a/libwebrtc/src/native/frame_cryptor.rs +++ b/libwebrtc/src/native/frame_cryptor.rs @@ -1,10 +1,13 @@ +use std::sync::Arc; + use cxx::SharedPtr; use parking_lot::Mutex; -use std::sync::Arc; use webrtc_sys::frame_cryptor::{self as sys_fc}; -use crate::peer_connection_factory::PeerConnectionFactory; -use crate::{rtp_receiver::RtpReceiver, rtp_sender::RtpSender}; +use crate::{ + peer_connection_factory::PeerConnectionFactory, rtp_receiver::RtpReceiver, + rtp_sender::RtpSender, +}; pub type OnStateChange = Box; @@ -40,9 +43,7 @@ pub struct KeyProvider { impl KeyProvider { pub fn new(options: KeyProviderOptions) -> Self { - Self { - sys_handle: sys_fc::ffi::new_key_provider(options.into()), - } + Self { sys_handle: sys_fc::ffi::new_key_provider(options.into()) } } pub fn set_shared_key(&self, key_index: i32, key: Vec) -> bool { @@ -96,14 +97,9 @@ impl FrameCryptor { key_provider.sys_handle, sender.handle.sys_handle, ); - let fc = Self { - observer: observer.clone(), - sys_handle: sys_handle.clone(), - }; + let fc = Self { observer: observer.clone(), sys_handle: sys_handle.clone() }; fc.sys_handle - .register_observer(Box::new(sys_fc::RtcFrameCryptorObserverWrapper::new( - observer, - ))); + .register_observer(Box::new(sys_fc::RtcFrameCryptorObserverWrapper::new(observer))); fc } @@ -122,14 +118,9 @@ impl FrameCryptor { key_provider.sys_handle, receiver.handle.sys_handle, ); - let fc = Self { - observer: observer.clone(), - sys_handle: sys_handle.clone(), - }; + let fc = Self { observer: observer.clone(), sys_handle: sys_handle.clone() }; fc.sys_handle - .register_observer(Box::new(sys_fc::RtcFrameCryptorObserverWrapper::new( - observer, - ))); + .register_observer(Box::new(sys_fc::RtcFrameCryptorObserverWrapper::new(observer))); fc } diff --git a/libwebrtc/src/native/ice_candidate.rs b/libwebrtc/src/native/ice_candidate.rs index 8ebfab05..b26f10d3 100644 --- a/libwebrtc/src/native/ice_candidate.rs +++ b/libwebrtc/src/native/ice_candidate.rs @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::ice_candidate as ic; -use crate::session_description::SdpParseError; use cxx::SharedPtr; use webrtc_sys::jsep as sys_jsep; +use crate::{ice_candidate as ic, session_description::SdpParseError}; + #[derive(Clone)] pub struct IceCandidate { pub(crate) sys_handle: SharedPtr, @@ -35,9 +35,7 @@ impl IceCandidate { ); match res { - Ok(sys_handle) => Ok(ic::IceCandidate { - handle: IceCandidate { sys_handle }, - }), + Ok(sys_handle) => Ok(ic::IceCandidate { handle: IceCandidate { sys_handle } }), Err(e) => Err(unsafe { sys_jsep::ffi::SdpParseError::from(e.what()).into() }), } } diff --git a/libwebrtc/src/native/media_stream.rs b/libwebrtc/src/native/media_stream.rs index 81d3bbe0..c2259d12 100644 --- a/libwebrtc/src/native/media_stream.rs +++ b/libwebrtc/src/native/media_stream.rs @@ -12,13 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::audio_track; -use crate::imp::audio_track::RtcAudioTrack; -use crate::imp::video_track::RtcVideoTrack; -use crate::video_track; use cxx::SharedPtr; use webrtc_sys::media_stream as sys_ms; +use crate::{ + audio_track, + imp::{audio_track::RtcAudioTrack, video_track::RtcVideoTrack}, + video_track, +}; + #[derive(Clone)] pub struct MediaStream { pub(crate) sys_handle: SharedPtr, @@ -33,9 +35,7 @@ impl MediaStream { self.sys_handle .get_audio_tracks() .into_iter() - .map(|t| audio_track::RtcAudioTrack { - handle: RtcAudioTrack { sys_handle: t.ptr }, - }) + .map(|t| audio_track::RtcAudioTrack { handle: RtcAudioTrack { sys_handle: t.ptr } }) .collect() } @@ -43,9 +43,7 @@ impl MediaStream { self.sys_handle .get_video_tracks() .into_iter() - .map(|t| video_track::RtcVideoTrack { - handle: RtcVideoTrack { sys_handle: t.ptr }, - }) + .map(|t| video_track::RtcVideoTrack { handle: RtcVideoTrack { sys_handle: t.ptr } }) .collect() } } diff --git a/libwebrtc/src/native/media_stream_track.rs b/libwebrtc/src/native/media_stream_track.rs index 157a9cb0..4e96109a 100644 --- a/libwebrtc/src/native/media_stream_track.rs +++ b/libwebrtc/src/native/media_stream_track.rs @@ -12,17 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::audio_track; -use crate::imp::audio_track::RtcAudioTrack; -use crate::imp::video_track::RtcVideoTrack; -use crate::media_stream_track::MediaStreamTrack; -use crate::media_stream_track::RtcTrackState; -use crate::video_track; use cxx::SharedPtr; -use webrtc_sys::audio_track::ffi::media_to_audio; -use webrtc_sys::media_stream_track as sys_mst; -use webrtc_sys::video_track::ffi::media_to_video; -use webrtc_sys::{MEDIA_TYPE_AUDIO, MEDIA_TYPE_VIDEO}; +use webrtc_sys::{ + audio_track::ffi::media_to_audio, media_stream_track as sys_mst, + video_track::ffi::media_to_video, MEDIA_TYPE_AUDIO, MEDIA_TYPE_VIDEO, +}; + +use crate::{ + audio_track, + imp::{audio_track::RtcAudioTrack, video_track::RtcVideoTrack}, + media_stream_track::{MediaStreamTrack, RtcTrackState}, + video_track, +}; impl From for RtcTrackState { fn from(state: sys_mst::ffi::TrackState) -> Self { @@ -39,15 +40,11 @@ pub fn new_media_stream_track( ) -> MediaStreamTrack { if sys_handle.kind() == MEDIA_TYPE_AUDIO { MediaStreamTrack::Audio(audio_track::RtcAudioTrack { - handle: RtcAudioTrack { - sys_handle: unsafe { media_to_audio(sys_handle) }, - }, + handle: RtcAudioTrack { sys_handle: unsafe { media_to_audio(sys_handle) } }, }) } else if sys_handle.kind() == MEDIA_TYPE_VIDEO { MediaStreamTrack::Video(video_track::RtcVideoTrack { - handle: RtcVideoTrack { - sys_handle: unsafe { media_to_video(sys_handle) }, - }, + handle: RtcVideoTrack { sys_handle: unsafe { media_to_video(sys_handle) } }, }) } else { panic!("unknown track kind") diff --git a/libwebrtc/src/native/mod.rs b/libwebrtc/src/native/mod.rs index ec2ded7f..4abae953 100644 --- a/libwebrtc/src/native/mod.rs +++ b/libwebrtc/src/native/mod.rs @@ -19,6 +19,7 @@ pub mod audio_source; pub mod audio_stream; pub mod audio_track; pub mod data_channel; +pub mod frame_cryptor; pub mod ice_candidate; pub mod media_stream; pub mod media_stream_track; @@ -34,12 +35,10 @@ pub mod video_source; pub mod video_stream; pub mod video_track; pub mod yuv_helper; -pub mod frame_cryptor; -use crate::MediaType; -use crate::{RtcError, RtcErrorType}; -use webrtc_sys::rtc_error as sys_err; -use webrtc_sys::webrtc as sys_rtc; +use webrtc_sys::{rtc_error as sys_err, webrtc as sys_rtc}; + +use crate::{MediaType, RtcError, RtcErrorType}; impl From for RtcErrorType { fn from(value: sys_err::ffi::RtcErrorType) -> Self { @@ -52,10 +51,7 @@ impl From for RtcErrorType { impl From for RtcError { fn from(value: sys_err::ffi::RtcError) -> Self { - Self { - error_type: value.error_type.into(), - message: value.message, - } + Self { error_type: value.error_type.into(), message: value.message } } } diff --git a/libwebrtc/src/native/peer_connection.rs b/libwebrtc/src/native/peer_connection.rs index 9346b418..769df749 100644 --- a/libwebrtc/src/native/peer_connection.rs +++ b/libwebrtc/src/native/peer_connection.rs @@ -12,46 +12,42 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::data_channel::DataChannel; -use crate::data_channel::DataChannelInit; -use crate::ice_candidate::IceCandidate; -use crate::imp::data_channel as imp_dc; -use crate::imp::ice_candidate as imp_ic; -use crate::imp::media_stream as imp_ms; -use crate::imp::media_stream_track as imp_mst; -use crate::imp::rtp_receiver as imp_rr; -use crate::imp::rtp_sender as imp_rs; -use crate::imp::rtp_transceiver as imp_rt; -use crate::imp::session_description as imp_sdp; -use crate::media_stream::MediaStream; -use crate::media_stream_track::MediaStreamTrack; -use crate::peer_connection::{ - AnswerOptions, IceCandidateError, IceConnectionState, IceGatheringState, OfferOptions, - OnConnectionChange, OnDataChannel, OnIceCandidate, OnIceCandidateError, OnIceConnectionChange, - OnIceGatheringChange, OnNegotiationNeeded, OnSignalingChange, OnTrack, PeerConnectionState, - SignalingState, TrackEvent, -}; -use crate::peer_connection_factory::{ - ContinualGatheringPolicy, IceServer, IceTransportsType, RtcConfiguration, -}; -use crate::rtp_receiver::RtpReceiver; -use crate::rtp_sender::RtpSender; -use crate::rtp_transceiver::RtpTransceiver; -use crate::rtp_transceiver::RtpTransceiverInit; -use crate::stats::RtcStats; -use crate::MediaType; -use crate::RtcErrorType; -use crate::{session_description::SessionDescription, RtcError}; +use std::sync::Arc; + use cxx::SharedPtr; use parking_lot::Mutex; -use std::sync::Arc; -use tokio::sync::mpsc; -use tokio::sync::oneshot; -use webrtc_sys::data_channel as sys_dc; -use webrtc_sys::jsep as sys_jsep; -use webrtc_sys::peer_connection as sys_pc; -use webrtc_sys::peer_connection_factory as sys_pcf; -use webrtc_sys::rtc_error as sys_err; +use tokio::sync::{mpsc, oneshot}; +use webrtc_sys::{ + data_channel as sys_dc, jsep as sys_jsep, peer_connection as sys_pc, + peer_connection_factory as sys_pcf, rtc_error as sys_err, +}; + +use crate::{ + data_channel::{DataChannel, DataChannelInit}, + ice_candidate::IceCandidate, + imp::{ + data_channel as imp_dc, ice_candidate as imp_ic, media_stream as imp_ms, + media_stream_track as imp_mst, rtp_receiver as imp_rr, rtp_sender as imp_rs, + rtp_transceiver as imp_rt, session_description as imp_sdp, + }, + media_stream::MediaStream, + media_stream_track::MediaStreamTrack, + peer_connection::{ + AnswerOptions, IceCandidateError, IceConnectionState, IceGatheringState, OfferOptions, + OnConnectionChange, OnDataChannel, OnIceCandidate, OnIceCandidateError, + OnIceConnectionChange, OnIceGatheringChange, OnNegotiationNeeded, OnSignalingChange, + OnTrack, PeerConnectionState, SignalingState, TrackEvent, + }, + peer_connection_factory::{ + ContinualGatheringPolicy, IceServer, IceTransportsType, RtcConfiguration, + }, + rtp_receiver::RtpReceiver, + rtp_sender::RtpSender, + rtp_transceiver::{RtpTransceiver, RtpTransceiverInit}, + session_description::SessionDescription, + stats::RtcStats, + MediaType, RtcError, RtcErrorType, +}; impl From for sys_pc::ffi::RtcOfferAnswerOptions { fn from(options: OfferOptions) -> Self { @@ -185,10 +181,7 @@ impl PeerConnection { sys_handle: SharedPtr, observer: Arc, ) -> Self { - Self { - sys_handle, - observer, - } + Self { sys_handle, observer } } pub fn set_configuration(&self, config: RtcConfiguration) -> Result<(), RtcError> { @@ -256,19 +249,15 @@ impl PeerConnection { let (tx, rx) = oneshot::channel::>(); let ctx = Box::new(sys_pc::PeerContext(Box::new(tx))); - self.sys_handle - .set_local_description(desc.handle.sys_handle, ctx, |ctx, err| { - let tx = ctx - .0 - .downcast::>>() - .unwrap(); - - if err.ok() { - let _ = tx.send(Ok(())); - } else { - let _ = tx.send(Err(err.into())); - } - }); + self.sys_handle.set_local_description(desc.handle.sys_handle, ctx, |ctx, err| { + let tx = ctx.0.downcast::>>().unwrap(); + + if err.ok() { + let _ = tx.send(Ok(())); + } else { + let _ = tx.send(Err(err.into())); + } + }); rx.await.unwrap() } @@ -277,19 +266,15 @@ impl PeerConnection { let (tx, rx) = oneshot::channel::>(); let ctx = Box::new(sys_pc::PeerContext(Box::new(tx))); - self.sys_handle - .set_remote_description(desc.handle.sys_handle, ctx, |ctx, err| { - let tx = ctx - .0 - .downcast::>>() - .unwrap(); - - if err.ok() { - let _ = tx.send(Ok(())); - } else { - let _ = tx.send(Err(err.into())); - } - }); + self.sys_handle.set_remote_description(desc.handle.sys_handle, ctx, |ctx, err| { + let tx = ctx.0.downcast::>>().unwrap(); + + if err.ok() { + let _ = tx.send(Ok(())); + } else { + let _ = tx.send(Err(err.into())); + } + }); rx.await.map_err(|_| RtcError { error_type: RtcErrorType::Internal, @@ -301,19 +286,15 @@ impl PeerConnection { let (tx, rx) = oneshot::channel::>(); let ctx = Box::new(sys_pc::PeerContext(Box::new(tx))); - self.sys_handle - .add_ice_candidate(candidate.handle.sys_handle, ctx, |ctx, err| { - let tx = ctx - .0 - .downcast::>>() - .unwrap(); - - if err.ok() { - let _ = tx.send(Ok(())); - } else { - let _ = tx.send(Err(err.into())); - } - }); + self.sys_handle.add_ice_candidate(candidate.handle.sys_handle, ctx, |ctx, err| { + let tx = ctx.0.downcast::>>().unwrap(); + + if err.ok() { + let _ = tx.send(Ok(())); + } else { + let _ = tx.send(Err(err.into())); + } + }); rx.await.map_err(|_| RtcError { error_type: RtcErrorType::Internal, @@ -326,14 +307,12 @@ impl PeerConnection { label: &str, init: DataChannelInit, ) -> Result { - let res = self - .sys_handle - .create_data_channel(label.to_string(), init.into()); + let res = self.sys_handle.create_data_channel(label.to_string(), init.into()); match res { - Ok(sys_handle) => Ok(DataChannel { - handle: imp_dc::DataChannel::configure(sys_handle), - }), + Ok(sys_handle) => { + Ok(DataChannel { handle: imp_dc::DataChannel::configure(sys_handle) }) + } Err(e) => Err(unsafe { sys_err::ffi::RtcError::from(e.what()).into() }), } } @@ -347,9 +326,7 @@ impl PeerConnection { let res = self.sys_handle.add_track(track.sys_handle(), &stream_ids); match res { - Ok(sys_handle) => Ok(RtpSender { - handle: imp_rs::RtpSender { sys_handle }, - }), + Ok(sys_handle) => Ok(RtpSender { handle: imp_rs::RtpSender { sys_handle } }), Err(e) => unsafe { Err(sys_err::ffi::RtcError::from(e.what()).into()) }, } } @@ -359,14 +336,10 @@ impl PeerConnection { track: MediaStreamTrack, init: RtpTransceiverInit, ) -> Result { - let res = self - .sys_handle - .add_transceiver(track.sys_handle(), init.into()); + let res = self.sys_handle.add_transceiver(track.sys_handle(), init.into()); match res { - Ok(sys_handle) => Ok(RtpTransceiver { - handle: imp_rt::RtpTransceiver { sys_handle }, - }), + Ok(sys_handle) => Ok(RtpTransceiver { handle: imp_rt::RtpTransceiver { sys_handle } }), Err(e) => unsafe { Err(sys_err::ffi::RtcError::from(e.what()).into()) }, } } @@ -376,16 +349,12 @@ impl PeerConnection { media_type: MediaType, init: RtpTransceiverInit, ) -> Result { - let res = self - .sys_handle - .add_transceiver_for_media(media_type.into(), init.into()); + let res = self.sys_handle.add_transceiver_for_media(media_type.into(), init.into()); match res { - Ok(cxx_handle) => Ok(RtpTransceiver { - handle: imp_rt::RtpTransceiver { - sys_handle: cxx_handle, - }, - }), + Ok(cxx_handle) => { + Ok(RtpTransceiver { handle: imp_rt::RtpTransceiver { sys_handle: cxx_handle } }) + } Err(e) => unsafe { Err(sys_err::ffi::RtcError::from(e.what()).into()) }, } } @@ -420,9 +389,7 @@ impl PeerConnection { return None; } - Some(SessionDescription { - handle: imp_sdp::SessionDescription { sys_handle: sdp }, - }) + Some(SessionDescription { handle: imp_sdp::SessionDescription { sys_handle: sdp } }) } pub fn current_remote_description(&self) -> Option { @@ -431,9 +398,7 @@ impl PeerConnection { return None; } - Some(SessionDescription { - handle: imp_sdp::SessionDescription { sys_handle: sdp }, - }) + Some(SessionDescription { handle: imp_sdp::SessionDescription { sys_handle: sdp } }) } pub fn remove_track(&self, sender: RtpSender) -> Result<(), RtcError> { @@ -447,10 +412,7 @@ impl PeerConnection { let ctx = Box::new(sys_pc::PeerContext(Box::new(tx))); self.sys_handle.get_stats(ctx, |ctx, stats| { - let tx = ctx - .0 - .downcast::, RtcError>>>() - .unwrap(); + let tx = ctx.0.downcast::, RtcError>>>().unwrap(); if stats.is_empty() { let _ = tx.send(Ok(vec![])); @@ -472,11 +434,7 @@ impl PeerConnection { self.sys_handle .get_senders() .into_iter() - .map(|sender| RtpSender { - handle: imp_rs::RtpSender { - sys_handle: sender.ptr, - }, - }) + .map(|sender| RtpSender { handle: imp_rs::RtpSender { sys_handle: sender.ptr } }) .collect() } @@ -485,9 +443,7 @@ impl PeerConnection { .get_receivers() .into_iter() .map(|receiver| RtpReceiver { - handle: imp_rr::RtpReceiver { - sys_handle: receiver.ptr, - }, + handle: imp_rr::RtpReceiver { sys_handle: receiver.ptr }, }) .collect() } @@ -497,9 +453,7 @@ impl PeerConnection { .get_transceivers() .into_iter() .map(|transceiver| RtpTransceiver { - handle: imp_rt::RtpTransceiver { - sys_handle: transceiver.ptr, - }, + handle: imp_rt::RtpTransceiver { sys_handle: transceiver.ptr }, }) .collect() } @@ -567,9 +521,7 @@ impl sys_pcf::PeerConnectionObserver for PeerObserver { fn on_data_channel(&self, data_channel: SharedPtr) { if let Some(f) = self.data_channel_handler.lock().as_mut() { - f(DataChannel { - handle: imp_dc::DataChannel::configure(data_channel), - }); + f(DataChannel { handle: imp_dc::DataChannel::configure(data_channel) }); } } @@ -603,11 +555,7 @@ impl sys_pcf::PeerConnectionObserver for PeerObserver { fn on_ice_candidate(&self, candidate: SharedPtr) { if let Some(f) = self.ice_candidate_handler.lock().as_mut() { - f(IceCandidate { - handle: imp_ic::IceCandidate { - sys_handle: candidate, - }, - }); + f(IceCandidate { handle: imp_ic::IceCandidate { sys_handle: candidate } }); } } @@ -620,13 +568,7 @@ impl sys_pcf::PeerConnectionObserver for PeerObserver { error_text: String, ) { if let Some(f) = self.ice_candidate_error_handler.lock().as_mut() { - f(IceCandidateError { - address, - port, - url, - error_code, - error_text, - }); + f(IceCandidateError { address, port, url, error_code, error_text }); } } @@ -658,22 +600,14 @@ impl sys_pcf::PeerConnectionObserver for PeerObserver { let track = receiver.track(); f(TrackEvent { - receiver: RtpReceiver { - handle: imp_rr::RtpReceiver { - sys_handle: receiver, - }, - }, + receiver: RtpReceiver { handle: imp_rr::RtpReceiver { sys_handle: receiver } }, streams: streams .into_iter() - .map(|s| MediaStream { - handle: imp_ms::MediaStream { sys_handle: s.ptr }, - }) + .map(|s| MediaStream { handle: imp_ms::MediaStream { sys_handle: s.ptr } }) .collect(), track: imp_mst::new_media_stream_track(track), transceiver: RtpTransceiver { - handle: imp_rt::RtpTransceiver { - sys_handle: transceiver, - }, + handle: imp_rt::RtpTransceiver { sys_handle: transceiver }, }, }); } diff --git a/libwebrtc/src/native/peer_connection_factory.rs b/libwebrtc/src/native/peer_connection_factory.rs index 7ec81cb6..a8038570 100644 --- a/libwebrtc/src/native/peer_connection_factory.rs +++ b/libwebrtc/src/native/peer_connection_factory.rs @@ -12,26 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::audio_source::native::NativeAudioSource; -use crate::audio_track::RtcAudioTrack; -use crate::imp::audio_track as imp_at; -use crate::imp::peer_connection as imp_pc; -use crate::imp::video_track as imp_vt; -use crate::peer_connection::PeerConnection; -use crate::peer_connection_factory::RtcConfiguration; -use crate::rtp_parameters::RtpCapabilities; -use crate::video_source::native::NativeVideoSource; -use crate::video_track::RtcVideoTrack; -use crate::MediaType; -use crate::RtcError; -use cxx::SharedPtr; -use cxx::UniquePtr; +use std::sync::Arc; + +use cxx::{SharedPtr, UniquePtr}; use lazy_static::lazy_static; use parking_lot::Mutex; -use std::sync::Arc; -use webrtc_sys::peer_connection_factory as sys_pcf; -use webrtc_sys::rtc_error as sys_err; -use webrtc_sys::webrtc as sys_rtc; +use webrtc_sys::{peer_connection_factory as sys_pcf, rtc_error as sys_err, webrtc as sys_rtc}; + +use crate::{ + audio_source::native::NativeAudioSource, + audio_track::RtcAudioTrack, + imp::{audio_track as imp_at, peer_connection as imp_pc, video_track as imp_vt}, + peer_connection::PeerConnection, + peer_connection_factory::RtcConfiguration, + rtp_parameters::RtpCapabilities, + video_source::native::NativeVideoSource, + video_track::RtcVideoTrack, + MediaType, RtcError, +}; lazy_static! { static ref LOG_SINK: Mutex>> = Default::default(); @@ -47,18 +45,13 @@ impl Default for PeerConnectionFactory { let mut log_sink = LOG_SINK.lock(); if log_sink.is_none() { *log_sink = Some(sys_rtc::ffi::new_log_sink(|msg, _| { - let msg = msg - .strip_suffix("\r\n") - .or(msg.strip_suffix('\n')) - .unwrap_or(&msg); + let msg = msg.strip_suffix("\r\n").or(msg.strip_suffix('\n')).unwrap_or(&msg); log::debug!("{}", msg); })); } - Self { - sys_handle: sys_pcf::ffi::create_peer_connection_factory(), - } + Self { sys_handle: sys_pcf::ffi::create_peer_connection_factory() } } } @@ -70,9 +63,7 @@ impl PeerConnectionFactory { let observer = Arc::new(imp_pc::PeerObserver::default()); let res = self.sys_handle.create_peer_connection( config.into(), - Box::new(sys_pcf::PeerConnectionObserverWrapper::new( - observer.clone(), - )), + Box::new(sys_pcf::PeerConnectionObserverWrapper::new(observer.clone())), ); match res { @@ -104,15 +95,11 @@ impl PeerConnectionFactory { } pub fn get_rtp_sender_capabilities(&self, media_type: MediaType) -> RtpCapabilities { - self.sys_handle - .rtp_sender_capabilities(media_type.into()) - .into() + self.sys_handle.rtp_sender_capabilities(media_type.into()).into() } pub fn get_rtp_receiver_capabilities(&self, media_type: MediaType) -> RtpCapabilities { - self.sys_handle - .rtp_receiver_capabilities(media_type.into()) - .into() + self.sys_handle.rtp_receiver_capabilities(media_type.into()).into() } } diff --git a/libwebrtc/src/native/rtp_parameters.rs b/libwebrtc/src/native/rtp_parameters.rs index a752c864..30f206ae 100644 --- a/libwebrtc/src/native/rtp_parameters.rs +++ b/libwebrtc/src/native/rtp_parameters.rs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +use webrtc_sys::{rtp_parameters as sys_rp, webrtc as sys_webrtc}; + use crate::rtp_parameters::*; -use webrtc_sys::rtp_parameters as sys_rp; -use webrtc_sys::webrtc as sys_webrtc; impl From for Priority { fn from(value: sys_webrtc::ffi::Priority) -> Self { @@ -30,11 +30,7 @@ impl From for Priority { impl From for RtpHeaderExtensionParameters { fn from(value: sys_rp::ffi::RtpExtension) -> Self { - Self { - uri: value.uri, - id: value.id, - encrypted: value.encrypt, - } + Self { uri: value.uri, id: value.id, encrypted: value.encrypt } } } @@ -42,11 +38,7 @@ impl From for RtpParameters { fn from(value: sys_rp::ffi::RtpParameters) -> Self { Self { codecs: value.codecs.into_iter().map(Into::into).collect(), - header_extensions: value - .header_extensions - .into_iter() - .map(Into::into) - .collect(), + header_extensions: value.header_extensions.into_iter().map(Into::into).collect(), rtcp: value.rtcp.into(), } } @@ -65,10 +57,7 @@ impl From for RtpCodecParameters { impl From for RtcpParameters { fn from(value: sys_rp::ffi::RtcpParameters) -> Self { - Self { - cname: value.cname, - reduced_size: value.reduced_size, - } + Self { cname: value.cname, reduced_size: value.reduced_size } } } @@ -76,9 +65,7 @@ impl From for RtpEncodingParameters { fn from(value: sys_rp::ffi::RtpEncodingParameters) -> Self { Self { active: value.active, - max_bitrate: value - .has_max_bitrate_bps - .then_some(value.max_bitrate_bps as u64), + max_bitrate: value.has_max_bitrate_bps.then_some(value.max_bitrate_bps as u64), max_framerate: value.has_max_framerate.then_some(value.max_framerate), priority: value.network_priority.into(), rid: value.rid, @@ -120,10 +107,7 @@ impl From for RtpCodecCapability { impl From for RtpHeaderExtensionCapability { fn from(value: sys_rp::ffi::RtpHeaderExtensionCapability) -> Self { - Self { - direction: value.direction.into(), - uri: value.uri, - } + Self { direction: value.direction.into(), uri: value.uri } } } @@ -131,11 +115,7 @@ impl From for RtpCapabilities { fn from(value: sys_rp::ffi::RtpCapabilities) -> Self { Self { codecs: value.codecs.into_iter().map(Into::into).collect(), - header_extensions: value - .header_extensions - .into_iter() - .map(Into::into) - .collect(), + header_extensions: value.header_extensions.into_iter().map(Into::into).collect(), } } } @@ -153,11 +133,7 @@ impl From for sys_webrtc::ffi::Priority { impl From for sys_rp::ffi::RtpExtension { fn from(value: RtpHeaderExtensionParameters) -> Self { - Self { - uri: value.uri, - id: value.id, - encrypt: value.encrypted, - } + Self { uri: value.uri, id: value.id, encrypt: value.encrypted } } } @@ -165,11 +141,7 @@ impl From for sys_rp::ffi::RtpParameters { fn from(value: RtpParameters) -> Self { Self { codecs: value.codecs.into_iter().map(Into::into).collect(), - header_extensions: value - .header_extensions - .into_iter() - .map(Into::into) - .collect(), + header_extensions: value.header_extensions.into_iter().map(Into::into).collect(), encodings: Vec::new(), rtcp: value.rtcp.into(), transaction_id: "".to_string(), diff --git a/libwebrtc/src/native/rtp_receiver.rs b/libwebrtc/src/native/rtp_receiver.rs index c8e39d9a..14fc2fec 100644 --- a/libwebrtc/src/native/rtp_receiver.rs +++ b/libwebrtc/src/native/rtp_receiver.rs @@ -12,15 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::imp::media_stream_track::new_media_stream_track; -use crate::media_stream_track::MediaStreamTrack; -use crate::rtp_parameters::RtpParameters; -use crate::stats::RtcStats; -use crate::{RtcError, RtcErrorType}; use cxx::SharedPtr; use tokio::sync::oneshot; use webrtc_sys::rtp_receiver as sys_rr; +use crate::{ + imp::media_stream_track::new_media_stream_track, media_stream_track::MediaStreamTrack, + rtp_parameters::RtpParameters, stats::RtcStats, RtcError, RtcErrorType, +}; + #[derive(Clone)] pub struct RtpReceiver { pub(crate) sys_handle: SharedPtr, @@ -41,10 +41,7 @@ impl RtpReceiver { let ctx = Box::new(sys_rr::ReceiverContext(Box::new(tx))); self.sys_handle.get_stats(ctx, |ctx, stats| { - let tx = ctx - .0 - .downcast::, RtcError>>>() - .unwrap(); + let tx = ctx.0.downcast::, RtcError>>>().unwrap(); if stats.is_empty() { let _ = tx.send(Ok(vec![])); diff --git a/libwebrtc/src/native/rtp_sender.rs b/libwebrtc/src/native/rtp_sender.rs index 506c9343..dd5509bd 100644 --- a/libwebrtc/src/native/rtp_sender.rs +++ b/libwebrtc/src/native/rtp_sender.rs @@ -12,14 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::media_stream_track::new_media_stream_track; -use crate::media_stream_track::MediaStreamTrack; -use crate::stats::RtcStats; -use crate::{rtp_parameters::RtpParameters, RtcError, RtcErrorType}; use cxx::SharedPtr; use tokio::sync::oneshot; -use webrtc_sys::rtc_error as sys_err; -use webrtc_sys::rtp_sender as sys_rs; +use webrtc_sys::{rtc_error as sys_err, rtp_sender as sys_rs}; + +use super::media_stream_track::new_media_stream_track; +use crate::{ + media_stream_track::MediaStreamTrack, rtp_parameters::RtpParameters, stats::RtcStats, RtcError, + RtcErrorType, +}; #[derive(Clone)] pub struct RtpSender { @@ -41,10 +42,7 @@ impl RtpSender { let ctx = Box::new(sys_rs::SenderContext(Box::new(tx))); self.sys_handle.get_stats(ctx, |ctx, stats| { - let tx = ctx - .0 - .downcast::, RtcError>>>() - .unwrap(); + let tx = ctx.0.downcast::, RtcError>>>().unwrap(); if stats.is_empty() { let _ = tx.send(Ok(vec![])); @@ -63,10 +61,7 @@ impl RtpSender { } pub fn set_track(&self, track: Option) -> Result<(), RtcError> { - if !self - .sys_handle - .set_track(track.map_or(SharedPtr::null(), |t| t.sys_handle())) - { + if !self.sys_handle.set_track(track.map_or(SharedPtr::null(), |t| t.sys_handle())) { return Err(RtcError { error_type: RtcErrorType::InvalidState, message: "Failed to set track".to_string(), diff --git a/libwebrtc/src/native/rtp_transceiver.rs b/libwebrtc/src/native/rtp_transceiver.rs index 4dcb90d1..128b6659 100644 --- a/libwebrtc/src/native/rtp_transceiver.rs +++ b/libwebrtc/src/native/rtp_transceiver.rs @@ -12,18 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::imp::rtp_receiver::RtpReceiver; -use crate::imp::rtp_sender::RtpSender; -use crate::rtp_parameters::RtpCodecCapability; -use crate::rtp_receiver; -use crate::rtp_sender; -use crate::rtp_transceiver::RtpTransceiverDirection; -use crate::rtp_transceiver::RtpTransceiverInit; -use crate::RtcError; use cxx::SharedPtr; -use webrtc_sys::rtc_error as sys_err; -use webrtc_sys::rtp_transceiver as sys_rt; -use webrtc_sys::webrtc as sys_webrtc; +use webrtc_sys::{rtc_error as sys_err, rtp_transceiver as sys_rt, webrtc as sys_webrtc}; + +use crate::{ + imp::{rtp_receiver::RtpReceiver, rtp_sender::RtpSender}, + rtp_parameters::RtpCodecCapability, + rtp_receiver, rtp_sender, + rtp_transceiver::{RtpTransceiverDirection, RtpTransceiverInit}, + RtcError, +}; impl From for RtpTransceiverDirection { fn from(value: sys_webrtc::ffi::RtpTransceiverDirection) -> Self { @@ -79,19 +77,11 @@ impl RtpTransceiver { } pub fn sender(&self) -> rtp_sender::RtpSender { - rtp_sender::RtpSender { - handle: RtpSender { - sys_handle: self.sys_handle.sender(), - }, - } + rtp_sender::RtpSender { handle: RtpSender { sys_handle: self.sys_handle.sender() } } } pub fn receiver(&self) -> rtp_receiver::RtpReceiver { - rtp_receiver::RtpReceiver { - handle: RtpReceiver { - sys_handle: self.sys_handle.receiver(), - }, - } + rtp_receiver::RtpReceiver { handle: RtpReceiver { sys_handle: self.sys_handle.receiver() } } } pub fn set_codec_preferences(&self, codecs: Vec) -> Result<(), RtcError> { diff --git a/libwebrtc/src/native/session_description.rs b/libwebrtc/src/native/session_description.rs index 94809f11..cb28d108 100644 --- a/libwebrtc/src/native/session_description.rs +++ b/libwebrtc/src/native/session_description.rs @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::session_description::{self, SdpParseError, SdpType}; use cxx::UniquePtr; use webrtc_sys::jsep as sys_jsep; +use crate::session_description::{self, SdpParseError, SdpType}; + impl From for SdpType { fn from(sdp_type: sys_jsep::ffi::SdpType) -> Self { match sdp_type { @@ -41,10 +42,7 @@ impl From for sys_jsep::ffi::SdpType { impl From for SdpParseError { fn from(e: sys_jsep::ffi::SdpParseError) -> Self { - Self { - line: e.line, - description: e.description, - } + Self { line: e.line, description: e.description } } } @@ -79,8 +77,6 @@ impl ToString for SessionDescription { impl Clone for SessionDescription { fn clone(&self) -> Self { - SessionDescription { - sys_handle: self.sys_handle.clone(), - } + SessionDescription { sys_handle: self.sys_handle.clone() } } } diff --git a/libwebrtc/src/native/video_frame.rs b/libwebrtc/src/native/video_frame.rs index 3ef7735f..5393d77d 100644 --- a/libwebrtc/src/native/video_frame.rs +++ b/libwebrtc/src/native/video_frame.rs @@ -12,55 +12,44 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::yuv_helper; -use crate::video_frame::VideoRotation; -use crate::video_frame::{self as vf, VideoFormatType}; -use cxx::UniquePtr; use std::slice; -use webrtc_sys::video_frame as vf_sys; -use webrtc_sys::video_frame_buffer as vfb_sys; + +use cxx::UniquePtr; +use webrtc_sys::{video_frame as vf_sys, video_frame_buffer as vfb_sys}; + +use super::yuv_helper; +use crate::video_frame::{self as vf, VideoFormatType, VideoRotation}; /// We don't use vf::VideoFrameBuffer trait for the types inside this module to avoid confusion /// because directly using platform specific types is not valid (e.g user callback) -/// All the types inside this module are only used internally. For public types, see the top level video_frame.rs +/// All the types inside this module are only used internally. For public types, see the top level +/// video_frame.rs pub fn new_video_frame_buffer( mut sys_handle: UniquePtr, ) -> Box { unsafe { match sys_handle.buffer_type() { - vfb_sys::ffi::VideoFrameBufferType::Native => Box::new(vf::native::NativeBuffer { - handle: NativeBuffer { sys_handle }, - }), + vfb_sys::ffi::VideoFrameBufferType::Native => { + Box::new(vf::native::NativeBuffer { handle: NativeBuffer { sys_handle } }) + } vfb_sys::ffi::VideoFrameBufferType::I420 => Box::new(vf::I420Buffer { - handle: I420Buffer { - sys_handle: sys_handle.pin_mut().get_i420(), - }, + handle: I420Buffer { sys_handle: sys_handle.pin_mut().get_i420() }, }), vfb_sys::ffi::VideoFrameBufferType::I420A => Box::new(vf::I420ABuffer { - handle: I420ABuffer { - sys_handle: sys_handle.pin_mut().get_i420a(), - }, + handle: I420ABuffer { sys_handle: sys_handle.pin_mut().get_i420a() }, }), vfb_sys::ffi::VideoFrameBufferType::I422 => Box::new(vf::I422Buffer { - handle: I422Buffer { - sys_handle: sys_handle.pin_mut().get_i422(), - }, + handle: I422Buffer { sys_handle: sys_handle.pin_mut().get_i422() }, }), vfb_sys::ffi::VideoFrameBufferType::I444 => Box::new(vf::I444Buffer { - handle: I444Buffer { - sys_handle: sys_handle.pin_mut().get_i444(), - }, + handle: I444Buffer { sys_handle: sys_handle.pin_mut().get_i444() }, }), vfb_sys::ffi::VideoFrameBufferType::I010 => Box::new(vf::I010Buffer { - handle: I010Buffer { - sys_handle: sys_handle.pin_mut().get_i010(), - }, + handle: I010Buffer { sys_handle: sys_handle.pin_mut().get_i010() }, }), vfb_sys::ffi::VideoFrameBufferType::NV12 => Box::new(vf::NV12Buffer { - handle: NV12Buffer { - sys_handle: sys_handle.pin_mut().get_nv12(), - }, + handle: NV12Buffer { sys_handle: sys_handle.pin_mut().get_nv12() }, }), _ => unreachable!(), } @@ -172,9 +161,7 @@ impl NativeBuffer { } pub fn to_i420(&self) -> I420Buffer { - I420Buffer { - sys_handle: unsafe { self.sys_handle.to_i420() }, - } + I420Buffer { sys_handle: unsafe { self.sys_handle.to_i420() } } } pub fn to_argb( @@ -185,8 +172,7 @@ impl NativeBuffer { dst_width: i32, dst_height: i32, ) { - self.to_i420() - .to_argb(format, dst, dst_stride, dst_width, dst_height) + self.to_i420().to_argb(format, dst, dst_stride, dst_width, dst_height) } } @@ -386,8 +372,7 @@ impl I420ABuffer { dst_width: i32, dst_height: i32, ) { - self.to_i420() - .to_argb(format, dst, dst_stride, dst_width, dst_height) + self.to_i420().to_argb(format, dst, dst_stride, dst_width, dst_height) } pub fn data(&self) -> (&[u8], &[u8], &[u8], Option<&[u8]>) { @@ -500,8 +485,7 @@ impl I422Buffer { dst_width: i32, dst_height: i32, ) { - self.to_i420() - .to_argb(format, dst, dst_stride, dst_width, dst_height) + self.to_i420().to_argb(format, dst, dst_stride, dst_width, dst_height) } pub fn data(&self) -> (&[u8], &[u8], &[u8]) { @@ -606,8 +590,7 @@ impl I444Buffer { dst_width: i32, dst_height: i32, ) { - self.to_i420() - .to_argb(format, dst, dst_stride, dst_width, dst_height) + self.to_i420().to_argb(format, dst, dst_stride, dst_width, dst_height) } pub fn data(&self) -> (&[u8], &[u8], &[u8]) { @@ -714,8 +697,7 @@ impl I010Buffer { dst_width: i32, dst_height: i32, ) { - self.to_i420() - .to_argb(format, dst, dst_stride, dst_width, dst_height) + self.to_i420().to_argb(format, dst, dst_stride, dst_width, dst_height) } pub fn data(&self) -> (&[u16], &[u16], &[u16]) { @@ -756,35 +738,22 @@ impl NV12Buffer { pub fn sys_handle(&self) -> &vfb_sys::ffi::VideoFrameBuffer { unsafe { - &*recursive_cast!( - &*self.sys_handle, - nv12_to_biyuv8, - biyuv8_to_biyuv, - biyuv_to_vfb - ) + &*recursive_cast!(&*self.sys_handle, nv12_to_biyuv8, biyuv8_to_biyuv, biyuv_to_vfb) } } pub fn width(&self) -> u32 { unsafe { - let ptr = recursive_cast!( - &*self.sys_handle, - nv12_to_biyuv8, - biyuv8_to_biyuv, - biyuv_to_vfb - ); + let ptr = + recursive_cast!(&*self.sys_handle, nv12_to_biyuv8, biyuv8_to_biyuv, biyuv_to_vfb); (*ptr).width() } } pub fn height(&self) -> u32 { unsafe { - let ptr = recursive_cast!( - &*self.sys_handle, - nv12_to_biyuv8, - biyuv8_to_biyuv, - biyuv_to_vfb - ); + let ptr = + recursive_cast!(&*self.sys_handle, nv12_to_biyuv8, biyuv8_to_biyuv, biyuv_to_vfb); (*ptr).height() } } @@ -839,8 +808,7 @@ impl NV12Buffer { dst_width: i32, dst_height: i32, ) { - self.to_i420() - .to_argb(format, dst, dst_stride, dst_width, dst_height) + self.to_i420().to_argb(format, dst, dst_stride, dst_width, dst_height) } pub fn data(&self) -> (&[u8], &[u8]) { diff --git a/libwebrtc/src/native/video_source.rs b/libwebrtc/src/native/video_source.rs index 4e55048a..d6aee1cd 100644 --- a/libwebrtc/src/native/video_source.rs +++ b/libwebrtc/src/native/video_source.rs @@ -12,31 +12,29 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::video_frame::{I420Buffer, VideoBuffer, VideoFrame}; -use crate::video_source::VideoResolution; +use std::{ + sync::Arc, + time::{Duration, SystemTime, UNIX_EPOCH}, +}; + use cxx::SharedPtr; use parking_lot::Mutex; -use std::sync::Arc; -use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use webrtc_sys::video_frame as vf_sys; -use webrtc_sys::video_frame::ffi::VideoRotation; -use webrtc_sys::video_track as vt_sys; +use webrtc_sys::{video_frame as vf_sys, video_frame::ffi::VideoRotation, video_track as vt_sys}; + +use crate::{ + video_frame::{I420Buffer, VideoBuffer, VideoFrame}, + video_source::VideoResolution, +}; impl From for VideoResolution { fn from(res: vt_sys::ffi::VideoResolution) -> Self { - Self { - width: res.width, - height: res.height, - } + Self { width: res.width, height: res.height } } } impl From for vt_sys::ffi::VideoResolution { fn from(res: VideoResolution) -> Self { - Self { - width: res.width, - height: res.height, - } + Self { width: res.width, height: res.height } } } @@ -74,19 +72,13 @@ impl NativeVideoSource { } let mut builder = vf_sys::ffi::new_video_frame_builder(); - builder - .pin_mut() - .set_rotation(VideoRotation::VideoRotation0); - builder - .pin_mut() - .set_video_frame_buffer(i420.as_ref().sys_handle()); + builder.pin_mut().set_rotation(VideoRotation::VideoRotation0); + builder.pin_mut().set_video_frame_buffer(i420.as_ref().sys_handle()); let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); builder.pin_mut().set_timestamp_us(now.as_micros() as i64); - source - .sys_handle - .on_captured_frame(&builder.pin_mut().build()); + source.sys_handle.on_captured_frame(&builder.pin_mut().build()); } } }); @@ -104,9 +96,7 @@ impl NativeVideoSource { let mut builder = vf_sys::ffi::new_video_frame_builder(); builder.pin_mut().set_rotation(frame.rotation.into()); - builder - .pin_mut() - .set_video_frame_buffer(frame.buffer.as_ref().sys_handle()); + builder.pin_mut().set_video_frame_buffer(frame.buffer.as_ref().sys_handle()); if frame.timestamp_us == 0 { // If the timestamp is set to 0, default to now @@ -116,8 +106,7 @@ impl NativeVideoSource { builder.pin_mut().set_timestamp_us(frame.timestamp_us); } - self.sys_handle - .on_captured_frame(&builder.pin_mut().build()); + self.sys_handle.on_captured_frame(&builder.pin_mut().build()); } pub fn video_resolution(&self) -> VideoResolution { diff --git a/libwebrtc/src/native/video_stream.rs b/libwebrtc/src/native/video_stream.rs index 5902f5ab..d17357d7 100644 --- a/libwebrtc/src/native/video_stream.rs +++ b/libwebrtc/src/native/video_stream.rs @@ -12,17 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::video_frame::new_video_frame_buffer; -use crate::video_frame::{BoxVideoFrame, VideoFrame}; -use crate::video_track::RtcVideoTrack; +use std::{ + pin::Pin, + sync::Arc, + task::{Context, Poll}, +}; + use cxx::{SharedPtr, UniquePtr}; -use std::pin::Pin; -use std::sync::Arc; -use std::task::{Context, Poll}; use tokio::sync::mpsc; use tokio_stream::Stream; use webrtc_sys::video_track as sys_vt; +use super::video_frame::new_video_frame_buffer; +use crate::{ + video_frame::{BoxVideoFrame, VideoFrame}, + video_track::RtcVideoTrack, +}; + pub struct NativeVideoStream { native_sink: SharedPtr, video_track: RtcVideoTrack, @@ -40,11 +46,7 @@ impl NativeVideoStream { let video = unsafe { sys_vt::ffi::media_to_video(video_track.sys_handle()) }; video.add_sink(&native_sink); - Self { - native_sink, - video_track, - frame_rx, - } + Self { native_sink, video_track, frame_rx } } pub fn track(&self) -> RtcVideoTrack { diff --git a/libwebrtc/src/native/video_track.rs b/libwebrtc/src/native/video_track.rs index d31f4dca..a8bb7e0e 100644 --- a/libwebrtc/src/native/video_track.rs +++ b/libwebrtc/src/native/video_track.rs @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::media_stream_track::impl_media_stream_track; -use crate::media_stream_track::RtcTrackState; use cxx::SharedPtr; use sys_vt::ffi::video_to_media; use webrtc_sys::video_track as sys_vt; +use super::media_stream_track::impl_media_stream_track; +use crate::media_stream_track::RtcTrackState; + #[derive(Clone)] pub struct RtcVideoTrack { pub(crate) sys_handle: SharedPtr, diff --git a/libwebrtc/src/peer_connection.rs b/libwebrtc/src/peer_connection.rs index 15ba3d2e..1e36de19 100644 --- a/libwebrtc/src/peer_connection.rs +++ b/libwebrtc/src/peer_connection.rs @@ -12,20 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::data_channel::{DataChannel, DataChannelInit}; -use crate::ice_candidate::IceCandidate; -use crate::imp::peer_connection as imp_pc; -use crate::media_stream::MediaStream; -use crate::media_stream_track::MediaStreamTrack; -use crate::peer_connection_factory::RtcConfiguration; -use crate::rtp_receiver::RtpReceiver; -use crate::rtp_sender::RtpSender; -use crate::rtp_transceiver::{RtpTransceiver, RtpTransceiverInit}; -use crate::session_description::SessionDescription; -use crate::stats::RtcStats; -use crate::{MediaType, RtcError}; use std::fmt::Debug; +use crate::{ + data_channel::{DataChannel, DataChannelInit}, + ice_candidate::IceCandidate, + imp::peer_connection as imp_pc, + media_stream::MediaStream, + media_stream_track::MediaStreamTrack, + peer_connection_factory::RtcConfiguration, + rtp_receiver::RtpReceiver, + rtp_sender::RtpSender, + rtp_transceiver::{RtpTransceiver, RtpTransceiverInit}, + session_description::SessionDescription, + stats::RtcStats, + MediaType, RtcError, +}; + #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum PeerConnectionState { New, @@ -270,11 +273,11 @@ impl Debug for PeerConnection { #[cfg(test)] mod tests { - use crate::peer_connection::*; - use crate::peer_connection_factory::*; use log::trace; use tokio::sync::mpsc; + use crate::{peer_connection::*, peer_connection_factory::*}; + #[tokio::test] async fn create_pc() { let _ = env_logger::builder().is_test(true).try_init(); @@ -309,9 +312,7 @@ mod tests { alice_dc_tx.send(dc).unwrap(); }))); - let bob_dc = bob - .create_data_channel("test_dc", DataChannelInit::default()) - .unwrap(); + let bob_dc = bob.create_data_channel("test_dc", DataChannelInit::default()).unwrap(); let offer = bob.create_offer(OfferOptions::default()).await.unwrap(); trace!("Bob offer: {:?}", offer); @@ -332,9 +333,7 @@ mod tests { let (data_tx, mut data_rx) = mpsc::unbounded_channel::(); let alice_dc = alice_dc_rx.recv().await.unwrap(); alice_dc.on_message(Some(Box::new(move |buffer| { - data_tx - .send(String::from_utf8_lossy(buffer.data).to_string()) - .unwrap(); + data_tx.send(String::from_utf8_lossy(buffer.data).to_string()).unwrap(); }))); bob_dc.send(b"This is a test", true).unwrap(); diff --git a/libwebrtc/src/peer_connection_factory.rs b/libwebrtc/src/peer_connection_factory.rs index ea756b0a..7d90ae97 100644 --- a/libwebrtc/src/peer_connection_factory.rs +++ b/libwebrtc/src/peer_connection_factory.rs @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::imp::peer_connection_factory as imp_pcf; -use crate::peer_connection::PeerConnection; -use crate::rtp_parameters::RtpCapabilities; -use crate::MediaType; -use crate::RtcError; use std::fmt::Debug; +use crate::{ + imp::peer_connection_factory as imp_pcf, peer_connection::PeerConnection, + rtp_parameters::RtpCapabilities, MediaType, RtcError, +}; + #[derive(Debug, Clone)] pub struct IceServer { pub urls: Vec, @@ -86,10 +86,10 @@ impl PeerConnectionFactory { pub mod native { use super::PeerConnectionFactory; - use crate::audio_source::native::NativeAudioSource; - use crate::audio_track::RtcAudioTrack; - use crate::video_source::native::NativeVideoSource; - use crate::video_track::RtcVideoTrack; + use crate::{ + audio_source::native::NativeAudioSource, audio_track::RtcAudioTrack, + video_source::native::NativeVideoSource, video_track::RtcVideoTrack, + }; pub trait PeerConnectionFactoryExt { fn create_video_track(&self, label: &str, source: NativeVideoSource) -> RtcVideoTrack; diff --git a/libwebrtc/src/prelude.rs b/libwebrtc/src/prelude.rs index c8d3dd90..7c319389 100644 --- a/libwebrtc/src/prelude.rs +++ b/libwebrtc/src/prelude.rs @@ -12,31 +12,32 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub use crate::audio_frame::AudioFrame; -pub use crate::audio_source::{AudioSourceOptions, RtcAudioSource}; -pub use crate::audio_track::RtcAudioTrack; -pub use crate::data_channel::{ - DataBuffer, DataChannel, DataChannelError, DataChannelInit, DataChannelState, +pub use crate::{ + audio_frame::AudioFrame, + audio_source::{AudioSourceOptions, RtcAudioSource}, + audio_track::RtcAudioTrack, + data_channel::{DataBuffer, DataChannel, DataChannelError, DataChannelInit, DataChannelState}, + ice_candidate::IceCandidate, + media_stream::MediaStream, + media_stream_track::{MediaStreamTrack, RtcTrackState}, + peer_connection::{ + AnswerOptions, IceConnectionState, IceGatheringState, OfferOptions, PeerConnection, + PeerConnectionState, SignalingState, + }, + peer_connection_factory::{ + ContinualGatheringPolicy, IceServer, IceTransportsType, PeerConnectionFactory, + RtcConfiguration, + }, + rtp_parameters::*, + rtp_receiver::RtpReceiver, + rtp_sender::RtpSender, + rtp_transceiver::{RtpTransceiver, RtpTransceiverDirection, RtpTransceiverInit}, + session_description::{SdpType, SessionDescription}, + video_frame::{ + BoxVideoBuffer, BoxVideoFrame, I010Buffer, I420ABuffer, I420Buffer, I422Buffer, I444Buffer, + NV12Buffer, VideoBuffer, VideoBufferType, VideoFormatType, VideoFrame, VideoRotation, + }, + video_source::{RtcVideoSource, VideoResolution}, + video_track::RtcVideoTrack, + MediaType, RtcError, RtcErrorType, }; -pub use crate::ice_candidate::IceCandidate; -pub use crate::media_stream::MediaStream; -pub use crate::media_stream_track::{MediaStreamTrack, RtcTrackState}; -pub use crate::peer_connection::{ - AnswerOptions, IceConnectionState, IceGatheringState, OfferOptions, PeerConnection, - PeerConnectionState, SignalingState, -}; -pub use crate::peer_connection_factory::{ - ContinualGatheringPolicy, IceServer, IceTransportsType, PeerConnectionFactory, RtcConfiguration, -}; -pub use crate::rtp_parameters::*; -pub use crate::rtp_receiver::RtpReceiver; -pub use crate::rtp_sender::RtpSender; -pub use crate::rtp_transceiver::{RtpTransceiver, RtpTransceiverDirection, RtpTransceiverInit}; -pub use crate::session_description::{SdpType, SessionDescription}; -pub use crate::video_frame::{ - BoxVideoBuffer, BoxVideoFrame, I010Buffer, I420ABuffer, I420Buffer, I422Buffer, I444Buffer, - NV12Buffer, VideoBuffer, VideoBufferType, VideoFormatType, VideoFrame, VideoRotation, -}; -pub use crate::video_source::{RtcVideoSource, VideoResolution}; -pub use crate::video_track::RtcVideoTrack; -pub use crate::{MediaType, RtcError, RtcErrorType}; diff --git a/libwebrtc/src/rtp_sender.rs b/libwebrtc/src/rtp_sender.rs index 3301e253..0edb4132 100644 --- a/libwebrtc/src/rtp_sender.rs +++ b/libwebrtc/src/rtp_sender.rs @@ -48,8 +48,6 @@ impl RtpSender { impl Debug for RtpSender { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("RtpReceiver") - .field("cname", &self.parameters().rtcp.cname) - .finish() + f.debug_struct("RtpReceiver").field("cname", &self.parameters().rtcp.cname).finish() } } diff --git a/libwebrtc/src/rtp_transceiver.rs b/libwebrtc/src/rtp_transceiver.rs index 2ac65a04..ba270c56 100644 --- a/libwebrtc/src/rtp_transceiver.rs +++ b/libwebrtc/src/rtp_transceiver.rs @@ -12,13 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::imp::rtp_transceiver as imp_rt; -use crate::rtp_parameters::{RtpCodecCapability, RtpEncodingParameters}; -use crate::rtp_receiver::RtpReceiver; -use crate::rtp_sender::RtpSender; -use crate::RtcError; use std::fmt::Debug; +use crate::{ + imp::rtp_transceiver as imp_rt, + rtp_parameters::{RtpCodecCapability, RtpEncodingParameters}, + rtp_receiver::RtpReceiver, + rtp_sender::RtpSender, + RtcError, +}; + #[derive(Debug, Clone)] pub struct RtpTransceiverInit { pub direction: RtpTransceiverDirection, diff --git a/libwebrtc/src/session_description.rs b/libwebrtc/src/session_description.rs index 622156a9..9b638368 100644 --- a/libwebrtc/src/session_description.rs +++ b/libwebrtc/src/session_description.rs @@ -12,13 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::imp::session_description as sd_imp; use std::{ fmt::{Debug, Display}, str::FromStr, }; + use thiserror::Error; +use crate::imp::session_description as sd_imp; + #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum SdpType { Offer, @@ -83,8 +85,6 @@ impl ToString for SessionDescription { impl Debug for SessionDescription { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("SessionDescription") - .field("sdp_type", &self.sdp_type()) - .finish() + f.debug_struct("SessionDescription").field("sdp_type", &self.sdp_type()).finish() } } diff --git a/libwebrtc/src/stats.rs b/libwebrtc/src/stats.rs index 4e543f37..dae455e4 100644 --- a/libwebrtc/src/stats.rs +++ b/libwebrtc/src/stats.rs @@ -1,12 +1,14 @@ -use crate::data_channel::DataChannelState; -use serde::Deserialize; use std::collections::HashMap; +use serde::Deserialize; + +use crate::data_channel::DataChannelState; + /// Values from https://www.w3.org/TR/webrtc-stats/ (NOTE: Some of the structs are not in the SPEC /// but inside libwebrtc) /// serde will handle the magic of correctly deserializing the json into our structs. -/// The enums values are inside encapsulated inside option because we're not sure about their default values (So we -/// default to None instead of an arbitrary value) +/// The enums values are inside encapsulated inside option because we're not sure about their +/// default values (So we default to None instead of an arbitrary value) #[derive(Debug, Clone, Deserialize)] #[serde(tag = "type")] diff --git a/libwebrtc/src/video_frame.rs b/libwebrtc/src/video_frame.rs index dd8b9b1c..69420c2b 100644 --- a/libwebrtc/src/video_frame.rs +++ b/libwebrtc/src/video_frame.rs @@ -12,10 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::imp::video_frame as vf_imp; use std::fmt::Debug; + use thiserror::Error; +use crate::imp::video_frame as vf_imp; + #[derive(Debug, Error)] pub enum SinkError { #[error("platform error: {0}")] @@ -134,9 +136,7 @@ macro_rules! new_buffer_type { #[cfg(not(target_arch = "wasm32"))] fn to_i420(&self) -> I420Buffer { - I420Buffer { - handle: self.handle.to_i420(), - } + I420Buffer { handle: self.handle.to_i420() } } #[cfg(not(target_arch = "wasm32"))] @@ -218,11 +218,7 @@ impl I420Buffer { } pub fn strides(&self) -> (u32, u32, u32) { - ( - self.handle.stride_y(), - self.handle.stride_u(), - self.handle.stride_v(), - ) + (self.handle.stride_y(), self.handle.stride_u(), self.handle.stride_v()) } pub fn data(&self) -> (&[u8], &[u8], &[u8]) { @@ -304,11 +300,7 @@ impl I422Buffer { } pub fn strides(&self) -> (u32, u32, u32) { - ( - self.handle.stride_y(), - self.handle.stride_u(), - self.handle.stride_v(), - ) + (self.handle.stride_y(), self.handle.stride_u(), self.handle.stride_v()) } pub fn data(&self) -> (&[u8], &[u8], &[u8]) { @@ -351,11 +343,7 @@ impl I444Buffer { } pub fn strides(&self) -> (u32, u32, u32) { - ( - self.handle.stride_y(), - self.handle.stride_u(), - self.handle.stride_v(), - ) + (self.handle.stride_y(), self.handle.stride_u(), self.handle.stride_v()) } pub fn data(&self) -> (&[u8], &[u8], &[u8]) { @@ -398,11 +386,7 @@ impl I010Buffer { } pub fn strides(&self) -> (u32, u32, u32) { - ( - self.handle.stride_y(), - self.handle.stride_u(), - self.handle.stride_v(), - ) + (self.handle.stride_y(), self.handle.stride_u(), self.handle.stride_v()) } pub fn data(&self) -> (&[u16], &[u16], &[u16]) { @@ -459,9 +443,10 @@ impl NV12Buffer { #[cfg(not(target_arch = "wasm32"))] pub mod native { - use super::{vf_imp, I420Buffer, VideoBuffer, VideoBufferType, VideoFormatType}; use std::fmt::Debug; + use super::{vf_imp, I420Buffer, VideoBuffer, VideoBufferType, VideoFormatType}; + new_buffer_type!(NativeBuffer, Native, as_native); pub trait VideoFrameBufferExt: VideoBuffer { diff --git a/libwebrtc/src/video_source.rs b/libwebrtc/src/video_source.rs index 6791e79a..4efb9e36 100644 --- a/libwebrtc/src/video_source.rs +++ b/libwebrtc/src/video_source.rs @@ -40,9 +40,10 @@ impl RtcVideoSource { #[cfg(not(target_arch = "wasm32"))] pub mod native { + use std::fmt::{Debug, Formatter}; + use super::*; use crate::video_frame::{VideoBuffer, VideoFrame}; - use std::fmt::{Debug, Formatter}; #[derive(Clone)] pub struct NativeVideoSource { @@ -63,9 +64,7 @@ pub mod native { impl NativeVideoSource { pub fn new(resolution: VideoResolution) -> Self { - Self { - handle: vs_imp::NativeVideoSource::new(resolution), - } + Self { handle: vs_imp::NativeVideoSource::new(resolution) } } pub fn capture_frame>(&self, frame: &VideoFrame) { diff --git a/libwebrtc/src/video_stream.rs b/libwebrtc/src/video_stream.rs index 2dc58679..b1ea2e4f 100644 --- a/libwebrtc/src/video_stream.rs +++ b/libwebrtc/src/video_stream.rs @@ -19,31 +19,30 @@ use crate::imp::video_stream as stream_imp; #[cfg(not(target_arch = "wasm32"))] pub mod native { - use super::stream_imp; - use crate::video_frame::BoxVideoFrame; - use crate::video_track::RtcVideoTrack; - use std::fmt::Debug; - use std::pin::Pin; - use std::task::{Context, Poll}; + use std::{ + fmt::Debug, + pin::Pin, + task::{Context, Poll}, + }; + use tokio_stream::Stream; + use super::stream_imp; + use crate::{video_frame::BoxVideoFrame, video_track::RtcVideoTrack}; + pub struct NativeVideoStream { pub(crate) handle: stream_imp::NativeVideoStream, } impl Debug for NativeVideoStream { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - f.debug_struct("NativeVideoStream") - .field("track", &self.track()) - .finish() + f.debug_struct("NativeVideoStream").field("track", &self.track()).finish() } } impl NativeVideoStream { pub fn new(video_track: RtcVideoTrack) -> Self { - Self { - handle: stream_imp::NativeVideoStream::new(video_track), - } + Self { handle: stream_imp::NativeVideoStream::new(video_track) } } pub fn track(&self) -> RtcVideoTrack { diff --git a/libwebrtc/src/video_track.rs b/libwebrtc/src/video_track.rs index e3c2c515..6f440e78 100644 --- a/libwebrtc/src/video_track.rs +++ b/libwebrtc/src/video_track.rs @@ -12,11 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::imp::video_track as imp_vt; -use crate::media_stream_track::media_stream_track; -use crate::media_stream_track::RtcTrackState; use std::fmt::Debug; +use crate::{ + imp::video_track as imp_vt, + media_stream_track::{media_stream_track, RtcTrackState}, +}; + #[derive(Clone)] pub struct RtcVideoTrack { pub(crate) handle: imp_vt::RtcVideoTrack, diff --git a/livekit-api/src/access_token.rs b/livekit-api/src/access_token.rs index 64185817..c1b82f81 100644 --- a/livekit-api/src/access_token.rs +++ b/livekit-api/src/access_token.rs @@ -12,16 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::get_env_keys; +use std::{ + env, + fmt::Debug, + ops::Add, + time::{Duration, SystemTime, UNIX_EPOCH}, +}; + use jsonwebtoken::{self, DecodingKey, EncodingKey, Header}; use serde::{Deserialize, Serialize}; -use std::env; -use std::fmt::Debug; -use std::ops::Add; -use std::time::Duration; -use std::time::{SystemTime, UNIX_EPOCH}; use thiserror::Error; +use crate::get_env_keys; + pub const DEFAULT_TTL: Duration = Duration::from_secs(3600 * 6); // 6 hours #[derive(Debug, Error)] @@ -208,18 +211,13 @@ pub struct TokenVerifier { impl Debug for TokenVerifier { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("TokenVerifier") - .field("api_key", &self.api_key) - .finish() + f.debug_struct("TokenVerifier").field("api_key", &self.api_key).finish() } } impl TokenVerifier { pub fn with_api_key(api_key: &str, api_secret: &str) -> Self { - Self { - api_key: api_key.to_owned(), - api_secret: api_secret.to_owned(), - } + Self { api_key: api_key.to_owned(), api_secret: api_secret.to_owned() } } pub fn new() -> Result { @@ -245,9 +243,10 @@ impl TokenVerifier { #[cfg(test)] mod tests { - use super::{AccessToken, TokenVerifier, VideoGrants}; use std::time::Duration; + use super::{AccessToken, TokenVerifier, VideoGrants}; + const TEST_API_KEY: &str = "myapikey"; const TEST_API_SECRET: &str = "thiskeyistotallyunsafe"; diff --git a/livekit-api/src/services/egress.rs b/livekit-api/src/services/egress.rs index a6696c22..4c557be9 100644 --- a/livekit-api/src/services/egress.rs +++ b/livekit-api/src/services/egress.rs @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::{ServiceBase, ServiceResult, LIVEKIT_PACKAGE}; -use crate::services::twirp_client::TwirpClient; -use crate::{access_token::VideoGrants, get_env_keys}; use livekit_protocol as proto; +use super::{ServiceBase, ServiceResult, LIVEKIT_PACKAGE}; +use crate::{access_token::VideoGrants, get_env_keys, services::twirp_client::TwirpClient}; + #[derive(Default, Clone, Debug)] pub struct RoomCompositeOptions { pub layout: String, @@ -115,10 +115,7 @@ impl EgressClient { image_outputs, output: None, // Deprecated }, - self.base.auth_header(VideoGrants { - room_record: true, - ..Default::default() - })?, + self.base.auth_header(VideoGrants { room_record: true, ..Default::default() })?, ) .await .map_err(Into::into) @@ -149,10 +146,7 @@ impl EgressClient { output: None, // Deprecated await_start_signal: options.await_start_signal, }, - self.base.auth_header(VideoGrants { - room_record: true, - ..Default::default() - })?, + self.base.auth_header(VideoGrants { room_record: true, ..Default::default() })?, ) .await .map_err(Into::into) @@ -182,10 +176,7 @@ impl EgressClient { image_outputs, output: None, // Deprecated }, - self.base.auth_header(VideoGrants { - room_record: true, - ..Default::default() - })?, + self.base.auth_header(VideoGrants { room_record: true, ..Default::default() })?, ) .await .map_err(Into::into) @@ -213,10 +204,7 @@ impl EgressClient { }, track_id: track_id.to_string(), }, - self.base.auth_header(VideoGrants { - room_record: true, - ..Default::default() - })?, + self.base.auth_header(VideoGrants { room_record: true, ..Default::default() })?, ) .await .map_err(Into::into) @@ -235,10 +223,7 @@ impl EgressClient { egress_id: egress_id.to_owned(), layout: layout.to_owned(), }, - self.base.auth_header(VideoGrants { - room_record: true, - ..Default::default() - })?, + self.base.auth_header(VideoGrants { room_record: true, ..Default::default() })?, ) .await .map_err(Into::into) @@ -259,10 +244,7 @@ impl EgressClient { add_output_urls, remove_output_urls, }, - self.base.auth_header(VideoGrants { - room_record: true, - ..Default::default() - })?, + self.base.auth_header(VideoGrants { room_record: true, ..Default::default() })?, ) .await .map_err(Into::into) @@ -286,15 +268,8 @@ impl EgressClient { .request( SVC, "ListEgress", - proto::ListEgressRequest { - room_name, - egress_id, - active: options.active, - }, - self.base.auth_header(VideoGrants { - room_record: true, - ..Default::default() - })?, + proto::ListEgressRequest { room_name, egress_id, active: options.active }, + self.base.auth_header(VideoGrants { room_record: true, ..Default::default() })?, ) .await?; @@ -306,13 +281,8 @@ impl EgressClient { .request( SVC, "StopEgress", - proto::StopEgressRequest { - egress_id: egress_id.to_owned(), - }, - self.base.auth_header(VideoGrants { - room_record: true, - ..Default::default() - })?, + proto::StopEgressRequest { egress_id: egress_id.to_owned() }, + self.base.auth_header(VideoGrants { room_record: true, ..Default::default() })?, ) .await .map_err(Into::into) @@ -407,41 +377,19 @@ pub mod encoding { } } - pub const H264_720P_30: EncodingOptions = EncodingOptions { - width: 1280, - height: 720, - video_bitrate: 3000, - ..EncodingOptions::new() - }; - pub const H264_720P_60: EncodingOptions = EncodingOptions { - width: 1280, - height: 720, - framerate: 60, - ..EncodingOptions::new() - }; + pub const H264_720P_30: EncodingOptions = + EncodingOptions { width: 1280, height: 720, video_bitrate: 3000, ..EncodingOptions::new() }; + pub const H264_720P_60: EncodingOptions = + EncodingOptions { width: 1280, height: 720, framerate: 60, ..EncodingOptions::new() }; pub const H264_1080P_30: EncodingOptions = EncodingOptions::new(); - pub const H264_1080P_60: EncodingOptions = EncodingOptions { - framerate: 60, - video_bitrate: 6000, - ..EncodingOptions::new() - }; - pub const PORTRAIT_H264_720P_30: EncodingOptions = EncodingOptions { - width: 720, - height: 1280, - video_bitrate: 3000, - ..EncodingOptions::new() - }; - pub const PORTRAIT_H264_720P_60: EncodingOptions = EncodingOptions { - width: 720, - height: 1280, - framerate: 60, - ..EncodingOptions::new() - }; - pub const PORTRAIT_H264_1080P_30: EncodingOptions = EncodingOptions { - width: 1080, - height: 1920, - ..EncodingOptions::new() - }; + pub const H264_1080P_60: EncodingOptions = + EncodingOptions { framerate: 60, video_bitrate: 6000, ..EncodingOptions::new() }; + pub const PORTRAIT_H264_720P_30: EncodingOptions = + EncodingOptions { width: 720, height: 1280, video_bitrate: 3000, ..EncodingOptions::new() }; + pub const PORTRAIT_H264_720P_60: EncodingOptions = + EncodingOptions { width: 720, height: 1280, framerate: 60, ..EncodingOptions::new() }; + pub const PORTRAIT_H264_1080P_30: EncodingOptions = + EncodingOptions { width: 1080, height: 1920, ..EncodingOptions::new() }; pub const PORTRAIT_H264_1080P_60: EncodingOptions = EncodingOptions { width: 1080, height: 1920, diff --git a/livekit-api/src/services/ingress.rs b/livekit-api/src/services/ingress.rs index f3b030ac..98240965 100644 --- a/livekit-api/src/services/ingress.rs +++ b/livekit-api/src/services/ingress.rs @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::{ServiceBase, ServiceResult, LIVEKIT_PACKAGE}; -use crate::services::twirp_client::TwirpClient; -use crate::{access_token::VideoGrants, get_env_keys}; use livekit_protocol as proto; +use super::{ServiceBase, ServiceResult, LIVEKIT_PACKAGE}; +use crate::{access_token::VideoGrants, get_env_keys, services::twirp_client::TwirpClient}; + #[derive(Default, Clone, Debug)] pub struct IngressOptions { pub name: String, @@ -75,10 +75,7 @@ impl IngressClient { bypass_transcoding: false, // TODO Expose ..Default::default() }, - self.base.auth_header(VideoGrants { - ingress_admin: true, - ..Default::default() - })?, + self.base.auth_header(VideoGrants { ingress_admin: true, ..Default::default() })?, ) .await .map_err(Into::into) @@ -103,10 +100,7 @@ impl IngressClient { video: Some(options.video), bypass_transcoding: None, // TODO Expose }, - self.base.auth_header(VideoGrants { - ingress_admin: true, - ..Default::default() - })?, + self.base.auth_header(VideoGrants { ingress_admin: true, ..Default::default() })?, ) .await .map_err(Into::into) @@ -131,10 +125,7 @@ impl IngressClient { _ => Default::default(), }, }, - self.base.auth_header(VideoGrants { - ingress_admin: true, - ..Default::default() - })?, + self.base.auth_header(VideoGrants { ingress_admin: true, ..Default::default() })?, ) .await?; @@ -146,13 +137,8 @@ impl IngressClient { .request( SVC, "DeleteIngress", - proto::DeleteIngressRequest { - ingress_id: ingress_id.to_owned(), - }, - self.base.auth_header(VideoGrants { - ingress_admin: true, - ..Default::default() - })?, + proto::DeleteIngressRequest { ingress_id: ingress_id.to_owned() }, + self.base.auth_header(VideoGrants { ingress_admin: true, ..Default::default() })?, ) .await .map_err(Into::into) diff --git a/livekit-api/src/services/mod.rs b/livekit-api/src/services/mod.rs index db5dc2aa..b685f839 100644 --- a/livekit-api/src/services/mod.rs +++ b/livekit-api/src/services/mod.rs @@ -12,11 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::access_token::{AccessToken, AccessTokenError, VideoGrants}; -use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION}; use std::fmt::Debug; + +use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION}; use thiserror::Error; +use crate::access_token::{AccessToken, AccessTokenError, VideoGrants}; + pub mod egress; pub mod ingress; pub mod room; @@ -44,18 +46,13 @@ struct ServiceBase { impl Debug for ServiceBase { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("ServiceBase") - .field("api_key", &self.api_key) - .finish() + f.debug_struct("ServiceBase").field("api_key", &self.api_key).finish() } } impl ServiceBase { pub fn with_api_key(api_key: &str, api_secret: &str) -> Self { - Self { - api_key: api_key.to_owned(), - api_secret: api_secret.to_owned(), - } + Self { api_key: api_key.to_owned(), api_secret: api_secret.to_owned() } } pub fn auth_header(&self, grants: VideoGrants) -> Result { @@ -64,10 +61,7 @@ impl ServiceBase { .to_jwt()?; let mut headers = HeaderMap::new(); - headers.insert( - AUTHORIZATION, - HeaderValue::from_str(&format!("Bearer {}", token)).unwrap(), - ); + headers.insert(AUTHORIZATION, HeaderValue::from_str(&format!("Bearer {}", token)).unwrap()); Ok(headers) } } diff --git a/livekit-api/src/services/room.rs b/livekit-api/src/services/room.rs index 1ff754b6..26605393 100644 --- a/livekit-api/src/services/room.rs +++ b/livekit-api/src/services/room.rs @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::{ServiceBase, ServiceResult, LIVEKIT_PACKAGE}; -use crate::services::twirp_client::TwirpClient; -use crate::{access_token::VideoGrants, get_env_keys}; use livekit_protocol as proto; +use super::{ServiceBase, ServiceResult, LIVEKIT_PACKAGE}; +use crate::{access_token::VideoGrants, get_env_keys, services::twirp_client::TwirpClient}; + const SVC: &str = "RoomService"; #[derive(Debug, Clone, Default)] @@ -81,10 +81,7 @@ impl RoomClient { egress: options.egress, ..Default::default() }, - self.base.auth_header(VideoGrants { - room_create: true, - ..Default::default() - })?, + self.base.auth_header(VideoGrants { room_create: true, ..Default::default() })?, ) .await .map_err(Into::into) @@ -97,10 +94,7 @@ impl RoomClient { SVC, "ListRooms", proto::ListRoomsRequest { names }, - self.base.auth_header(VideoGrants { - room_list: true, - ..Default::default() - })?, + self.base.auth_header(VideoGrants { room_list: true, ..Default::default() })?, ) .await?; @@ -112,13 +106,8 @@ impl RoomClient { .request( SVC, "DeleteRoom", - proto::DeleteRoomRequest { - room: room.to_owned(), - }, - self.base.auth_header(VideoGrants { - room_create: true, - ..Default::default() - })?, + proto::DeleteRoomRequest { room: room.to_owned() }, + self.base.auth_header(VideoGrants { room_create: true, ..Default::default() })?, ) .await .map_err(Into::into) @@ -156,9 +145,7 @@ impl RoomClient { .request( SVC, "ListParticipants", - proto::ListParticipantsRequest { - room: room.to_owned(), - }, + proto::ListParticipantsRequest { room: room.to_owned() }, self.base.auth_header(VideoGrants { room_admin: true, room: room.to_owned(), diff --git a/livekit-api/src/services/twirp_client.rs b/livekit-api/src/services/twirp_client.rs index dd2a2e4b..80f61bab 100644 --- a/livekit-api/src/services/twirp_client.rs +++ b/livekit-api/src/services/twirp_client.rs @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::fmt::Display; + use reqwest::{ header::{HeaderMap, HeaderValue, CONTENT_TYPE}, StatusCode, }; use serde::Deserialize; -use std::fmt::Display; use thiserror::Error; pub const DEFAULT_PREFIX: &str = "/twirp"; @@ -95,23 +96,11 @@ impl TwirpClient { mut headers: HeaderMap, ) -> TwirpResult { let mut url = url::Url::parse(&self.host)?; - url.set_path(&format!( - "{}/{}.{}/{}", - self.prefix, self.pkg, service, method - )); + url.set_path(&format!("{}/{}.{}/{}", self.prefix, self.pkg, service, method)); - headers.insert( - CONTENT_TYPE, - HeaderValue::from_static("application/protobuf"), - ); + headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/protobuf")); - let resp = self - .client - .post(url) - .headers(headers) - .body(data.encode_to_vec()) - .send() - .await?; + let resp = self.client.post(url).headers(headers).body(data.encode_to_vec()).send().await?; if resp.status() == StatusCode::OK { Ok(R::decode(resp.bytes().await?)?) diff --git a/livekit-api/src/signal_client/mod.rs b/livekit-api/src/signal_client/mod.rs index 7e969eda..ab3a9ed6 100644 --- a/livekit-api/src/signal_client/mod.rs +++ b/livekit-api/src/signal_client/mod.rs @@ -12,23 +12,29 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::signal_client::signal_stream::SignalStream; +use std::{ + borrow::Cow, + fmt::Debug, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, + time::{Duration, SystemTime, UNIX_EPOCH}, +}; + use livekit_protocol as proto; use parking_lot::Mutex; use reqwest::StatusCode; -use std::borrow::Cow; -use std::fmt::Debug; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::Arc; -use std::time::{Duration, SystemTime, UNIX_EPOCH}; use thiserror::Error; -use tokio::sync::mpsc; -use tokio::sync::Mutex as AsyncMutex; -use tokio::sync::RwLock as AsyncRwLock; -use tokio::task::JoinHandle; -use tokio::time::{interval, sleep, Instant}; +use tokio::{ + sync::{mpsc, Mutex as AsyncMutex, RwLock as AsyncRwLock}, + task::JoinHandle, + time::{interval, sleep, Instant}, +}; use tokio_tungstenite::tungstenite::Error as WsError; +use crate::signal_client::signal_stream::SignalStream; + mod signal_stream; pub type SignalEmitter = mpsc::UnboundedSender; @@ -64,10 +70,7 @@ pub struct SignalOptions { impl Default for SignalOptions { fn default() -> Self { - Self { - auto_subscribe: true, - adaptive_stream: false, - } + Self { auto_subscribe: true, adaptive_stream: false } } } @@ -117,15 +120,7 @@ impl SignalClient { let (emitter, events) = mpsc::unbounded_channel(); let signal_task = tokio::spawn(signal_task(inner.clone(), emitter.clone(), stream_events)); - Ok(( - Self { - inner, - emitter, - handle: Mutex::new(Some(signal_task)), - }, - join_response, - events, - )) + Ok((Self { inner, emitter, handle: Mutex::new(Some(signal_task)) }, join_response, events)) } /// Restart the connection to the server @@ -134,11 +129,8 @@ impl SignalClient { self.close().await; let (reconnect_response, stream_events) = self.inner.restart().await?; - let signal_task = tokio::spawn(signal_task( - self.inner.clone(), - self.emitter.clone(), - stream_events, - )); + let signal_task = + tokio::spawn(signal_task(self.inner.clone(), self.emitter.clone(), stream_events)); *self.handle.lock() = Some(signal_task); Ok(reconnect_response) @@ -222,13 +214,7 @@ impl SignalInner { /// Validate the connection by calling rtc/validate async fn validate(mut ws_url: url::Url) -> SignalResult<()> { - ws_url - .set_scheme(if ws_url.scheme() == "wss" { - "https" - } else { - "http" - }) - .unwrap(); + ws_url.set_scheme(if ws_url.scheme() == "wss" { "https" } else { "http" }).unwrap(); if let Ok(mut segs) = ws_url.path_segments_mut() { segs.extend(&["rtc", "validate"]); @@ -267,10 +253,7 @@ impl SignalInner { let token = self.token.lock().clone(); let mut lk_url = get_livekit_url(&self.url, &token, &self.options).unwrap(); - lk_url - .query_pairs_mut() - .append_pair("reconnect", "1") - .append_pair("sid", sid); + lk_url.query_pairs_mut().append_pair("reconnect", "1").append_pair("sid", sid); let (new_stream, mut events) = SignalStream::connect(lk_url).await?; let reconnect_response = get_reconnect_response(&mut events).await?; @@ -334,9 +317,7 @@ async fn signal_task( emitter: SignalEmitter, // Public emitter mut internal_events: mpsc::UnboundedReceiver>, ) { - let mut ping_interval = interval(Duration::from_secs( - inner.join_response.ping_interval as u64, - )); + let mut ping_interval = interval(Duration::from_secs(inner.join_response.ping_interval as u64)); let timeout_duration = Duration::from_secs(inner.join_response.ping_timeout as u64); let ping_timeout = sleep(timeout_duration); tokio::pin!(ping_timeout); @@ -422,14 +403,8 @@ fn get_livekit_url(url: &str, token: &str, options: &SignalOptions) -> SignalRes .append_pair("sdk", "rust") .append_pair("access_token", token) .append_pair("protocol", PROTOCOL_VERSION.to_string().as_str()) - .append_pair( - "auto_subscribe", - if options.auto_subscribe { "1" } else { "0" }, - ) - .append_pair( - "adaptive_stream", - if options.adaptive_stream { "1" } else { "0" }, - ); + .append_pair("auto_subscribe", if options.auto_subscribe { "1" } else { "0" }) + .append_pair("adaptive_stream", if options.adaptive_stream { "1" } else { "0" }); Ok(lk_url) } @@ -449,14 +424,9 @@ macro_rules! get_async_message { Err(WsError::ConnectionClosed)? }; - tokio::time::timeout(JOIN_RESPONSE_TIMEOUT, join) - .await - .map_err(|_| { - SignalError::Timeout(format!( - "failed to receive {}", - std::any::type_name::<$ty>() - )) - })? + tokio::time::timeout(JOIN_RESPONSE_TIMEOUT, join).await.map_err(|_| { + SignalError::Timeout(format!("failed to receive {}", std::any::type_name::<$ty>())) + })? } }; } diff --git a/livekit-api/src/signal_client/signal_stream.rs b/livekit-api/src/signal_client/signal_stream.rs index eb771c24..d17475f9 100644 --- a/livekit-api/src/signal_client/signal_stream.rs +++ b/livekit-api/src/signal_client/signal_stream.rs @@ -12,16 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::{SignalError, SignalResult}; -use futures_util::stream::{SplitSink, SplitStream}; -use futures_util::{SinkExt, StreamExt}; +use futures_util::{ + stream::{SplitSink, SplitStream}, + SinkExt, StreamExt, +}; use livekit_protocol as proto; use prost::Message as ProtoMessage; -use tokio::net::TcpStream; -use tokio::sync::{mpsc, oneshot}; -use tokio::task::JoinHandle; -use tokio_tungstenite::tungstenite::Message; -use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream}; +use tokio::{ + net::TcpStream, + sync::{mpsc, oneshot}, + task::JoinHandle, +}; +use tokio_tungstenite::{connect_async, tungstenite::Message, MaybeTlsStream, WebSocketStream}; + +use super::{SignalError, SignalResult}; type WebSocket = WebSocketStream>; @@ -55,10 +59,7 @@ impl SignalStream { /// closed. pub async fn connect( mut url: url::Url, - ) -> SignalResult<( - Self, - mpsc::UnboundedReceiver>, - )> { + ) -> SignalResult<(Self, mpsc::UnboundedReceiver>)> { { // Don't log sensitive info let mut url = url.clone(); @@ -96,14 +97,7 @@ impl SignalStream { let write_handle = tokio::spawn(Self::write_task(internal_rx, ws_writer)); let read_handle = tokio::spawn(Self::read_task(internal_tx.clone(), ws_reader, emitter)); - Ok(( - Self { - internal_tx, - read_handle, - write_handle, - }, - events, - )) + Ok((Self { internal_tx, read_handle, write_handle }, events)) } /// Close the websocket @@ -118,10 +112,7 @@ impl SignalStream { /// It also waits for the message to be sent pub async fn send(&self, signal: proto::signal_request::Message) -> SignalResult<()> { let (send, recv) = oneshot::channel(); - let msg = InternalMessage::Signal { - signal, - response_chn: send, - }; + let msg = InternalMessage::Signal { signal, response_chn: send }; let _ = self.internal_tx.send(msg).await; recv.await.map_err(|_| SignalError::SendError)? } @@ -134,14 +125,8 @@ impl SignalStream { ) { while let Some(msg) = internal_rx.recv().await { match msg { - InternalMessage::Signal { - signal, - response_chn, - } => { - let data = proto::SignalRequest { - message: Some(signal), - } - .encode_to_vec(); + InternalMessage::Signal { signal, response_chn } => { + let data = proto::SignalRequest { message: Some(signal) }.encode_to_vec(); if let Err(err) = ws_writer.send(Message::Binary(data)).await { let _ = response_chn.send(Err(err.into())); @@ -181,9 +166,7 @@ impl SignalStream { let _ = emitter.send(Box::new(msg)); } Ok(Message::Ping(data)) => { - let _ = internal_tx - .send(InternalMessage::Pong { ping_data: data }) - .await; + let _ = internal_tx.send(InternalMessage::Pong { ping_data: data }).await; continue; } Ok(Message::Close(close)) => { diff --git a/livekit-api/src/webhooks.rs b/livekit-api/src/webhooks.rs index 884354b1..d87c7302 100644 --- a/livekit-api/src/webhooks.rs +++ b/livekit-api/src/webhooks.rs @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::access_token::{AccessTokenError, TokenVerifier}; use base64::Engine; use livekit_protocol as proto; use sha2::{Digest, Sha256}; use thiserror::Error; +use crate::access_token::{AccessTokenError, TokenVerifier}; + #[derive(Debug, Error)] pub enum WebhookError { #[error("invalid signature")] diff --git a/livekit-ffi/build.rs b/livekit-ffi/build.rs index 7fa2ec69..92af1ff6 100644 --- a/livekit-ffi/build.rs +++ b/livekit-ffi/build.rs @@ -12,8 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::env; -use std::path::Path; +use std::{env, path::Path}; fn main() { if env::var("DOCS_RS").is_ok() { diff --git a/livekit-ffi/src/cabi.rs b/livekit-ffi/src/cabi.rs index c48dea1c..bb51c7d6 100644 --- a/livekit-ffi/src/cabi.rs +++ b/livekit-ffi/src/cabi.rs @@ -1,11 +1,13 @@ +use std::sync::Arc; + +use prost::Message; +use server::FfiDataBuffer; + use crate::{ proto, server::{self, FfiConfig}, FfiHandleId, FFI_SERVER, }; -use prost::Message; -use server::FfiDataBuffer; -use std::sync::Arc; /// # SAFTEY: The "C" callback must be threadsafe and not block pub type FfiCallbackFn = unsafe extern "C" fn(*const u8, usize); @@ -58,10 +60,7 @@ pub unsafe extern "C" fn livekit_ffi_request( } let handle_id = FFI_SERVER.next_id(); - let ffi_data = FfiDataBuffer { - handle: handle_id, - data: Arc::new(res), - }; + let ffi_data = FfiDataBuffer { handle: handle_id, data: Arc::new(res) }; FFI_SERVER.store_handle(handle_id, ffi_data); handle_id diff --git a/livekit-ffi/src/conversion/audio_frame.rs b/livekit-ffi/src/conversion/audio_frame.rs index e37afde9..c25ff415 100644 --- a/livekit-ffi/src/conversion/audio_frame.rs +++ b/livekit-ffi/src/conversion/audio_frame.rs @@ -12,11 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::proto; -use crate::server::audio_source::FfiAudioSource; -use crate::server::audio_stream::FfiAudioStream; -use livekit::webrtc::audio_source::AudioSourceOptions; -use livekit::webrtc::prelude::*; +use livekit::webrtc::{audio_source::AudioSourceOptions, prelude::*}; + +use crate::{ + proto, + server::{audio_source::FfiAudioSource, audio_stream::FfiAudioStream}, +}; impl From for AudioSourceOptions { fn from(opts: proto::AudioSourceOptions) -> Self { @@ -41,16 +42,12 @@ impl From<&AudioFrame<'_>> for proto::AudioFrameBufferInfo { impl From<&FfiAudioSource> for proto::AudioSourceInfo { fn from(source: &FfiAudioSource) -> Self { - Self { - r#type: source.source_type as i32, - } + Self { r#type: source.source_type as i32 } } } impl From<&FfiAudioStream> for proto::AudioStreamInfo { fn from(stream: &FfiAudioStream) -> Self { - Self { - r#type: stream.stream_type as i32, - } + Self { r#type: stream.stream_type as i32 } } } diff --git a/livekit-ffi/src/conversion/participant.rs b/livekit-ffi/src/conversion/participant.rs index d9cea130..caf6de57 100644 --- a/livekit-ffi/src/conversion/participant.rs +++ b/livekit-ffi/src/conversion/participant.rs @@ -12,8 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::proto; -use crate::server::room::FfiParticipant; +use crate::{proto, server::room::FfiParticipant}; impl From<&FfiParticipant> for proto::ParticipantInfo { fn from(value: &FfiParticipant) -> Self { diff --git a/livekit-ffi/src/conversion/room.rs b/livekit-ffi/src/conversion/room.rs index c91a0f08..1dd1bd8a 100644 --- a/livekit-ffi/src/conversion/room.rs +++ b/livekit-ffi/src/conversion/room.rs @@ -12,17 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::proto; -use crate::server::room::FfiRoom; -use livekit::e2ee::key_provider::{KeyProvider, KeyProviderOptions}; -use livekit::e2ee::{E2eeOptions, EncryptionType}; -use livekit::options::{AudioEncoding, TrackPublishOptions, VideoEncoding}; -use livekit::prelude::*; -use livekit::webrtc::native::frame_cryptor::EncryptionState; -use livekit::webrtc::prelude::{ - ContinualGatheringPolicy, IceServer, IceTransportsType, RtcConfiguration, +use livekit::{ + e2ee::{ + key_provider::{KeyProvider, KeyProviderOptions}, + E2eeOptions, EncryptionType, + }, + options::{AudioEncoding, TrackPublishOptions, VideoEncoding}, + prelude::*, + webrtc::{ + native::frame_cryptor::EncryptionState, + prelude::{ContinualGatheringPolicy, IceServer, IceTransportsType, RtcConfiguration}, + }, }; +use crate::{proto, server::room::FfiRoom}; + impl From for proto::EncryptionState { fn from(value: EncryptionState) -> Self { match value { @@ -109,11 +113,7 @@ impl From for ContinualGatheringPolicy { impl From for IceServer { fn from(value: proto::IceServer) -> Self { - Self { - urls: value.urls, - username: value.username, - password: value.password, - } + Self { urls: value.urls, username: value.username, password: value.password } } } @@ -122,11 +122,9 @@ impl From for RtcConfiguration { let default = RoomOptions::default().rtc_config; // Always use RoomOptions as the default reference Self { - ice_transport_type: value - .ice_transport_type - .map_or(default.ice_transport_type, |x| { - proto::IceTransportType::try_from(x).unwrap().into() - }), + ice_transport_type: value.ice_transport_type.map_or(default.ice_transport_type, |x| { + proto::IceTransportType::try_from(x).unwrap().into() + }), continual_gathering_policy: value .continual_gathering_policy .map_or(default.continual_gathering_policy, |x| { @@ -156,10 +154,8 @@ impl From for RoomOptions { }) }); - let rtc_config = value - .rtc_config - .map(Into::into) - .unwrap_or(RoomOptions::default().rtc_config); + let rtc_config = + value.rtc_config.map(Into::into).unwrap_or(RoomOptions::default().rtc_config); Self { adaptive_stream: value.adaptive_stream, @@ -206,28 +202,19 @@ impl From for TrackPublishOptions { impl From for VideoEncoding { fn from(opts: proto::VideoEncoding) -> Self { - Self { - max_bitrate: opts.max_bitrate, - max_framerate: opts.max_framerate, - } + Self { max_bitrate: opts.max_bitrate, max_framerate: opts.max_framerate } } } impl From for AudioEncoding { fn from(opts: proto::AudioEncoding) -> Self { - Self { - max_bitrate: opts.max_bitrate, - } + Self { max_bitrate: opts.max_bitrate } } } impl From<&FfiRoom> for proto::RoomInfo { fn from(value: &FfiRoom) -> Self { let room = &value.inner.room; - Self { - sid: room.sid().into(), - name: room.name(), - metadata: room.metadata(), - } + Self { sid: room.sid().into(), name: room.name(), metadata: room.metadata() } } } diff --git a/livekit-ffi/src/conversion/stats.rs b/livekit-ffi/src/conversion/stats.rs index f4235311..56d97258 100644 --- a/livekit-ffi/src/conversion/stats.rs +++ b/livekit-ffi/src/conversion/stats.rs @@ -1,4 +1,3 @@ -use crate::proto; use livekit::webrtc::{ prelude::DataChannelState, stats::{ @@ -8,6 +7,8 @@ use livekit::webrtc::{ }, }; +use crate::proto; + impl From for proto::DataChannelState { fn from(value: DataChannelState) -> Self { match value { @@ -173,10 +174,7 @@ impl From for proto::RtcStats { impl From for proto::rtc_stats::Codec { fn from(value: rtc::CodecStats) -> Self { - Self { - rtc: Some(value.rtc.into()), - codec: Some(value.codec.into()), - } + Self { rtc: Some(value.rtc.into()), codec: Some(value.codec.into()) } } } @@ -237,73 +235,49 @@ impl From for proto::rtc_stats::MediaSource { impl From for proto::rtc_stats::MediaPlayout { fn from(value: rtc::MediaPlayoutStats) -> Self { - Self { - rtc: Some(value.rtc.into()), - audio_playout: Some(value.audio_playout.into()), - } + Self { rtc: Some(value.rtc.into()), audio_playout: Some(value.audio_playout.into()) } } } impl From for proto::rtc_stats::PeerConnection { fn from(value: rtc::PeerConnectionStats) -> Self { - Self { - rtc: Some(value.rtc.into()), - pc: Some(value.pc.into()), - } + Self { rtc: Some(value.rtc.into()), pc: Some(value.pc.into()) } } } impl From for proto::rtc_stats::DataChannel { fn from(value: rtc::DataChannelStats) -> Self { - Self { - rtc: Some(value.rtc.into()), - dc: Some(value.dc.into()), - } + Self { rtc: Some(value.rtc.into()), dc: Some(value.dc.into()) } } } impl From for proto::rtc_stats::Transport { fn from(value: rtc::TransportStats) -> Self { - Self { - rtc: Some(value.rtc.into()), - transport: Some(value.transport.into()), - } + Self { rtc: Some(value.rtc.into()), transport: Some(value.transport.into()) } } } impl From for proto::rtc_stats::CandidatePair { fn from(value: rtc::CandidatePairStats) -> Self { - Self { - rtc: Some(value.rtc.into()), - candidate_pair: Some(value.candidate_pair.into()), - } + Self { rtc: Some(value.rtc.into()), candidate_pair: Some(value.candidate_pair.into()) } } } impl From for proto::rtc_stats::LocalCandidate { fn from(value: rtc::LocalCandidateStats) -> Self { - Self { - rtc: Some(value.rtc.into()), - candidate: Some(value.local_candidate.into()), - } + Self { rtc: Some(value.rtc.into()), candidate: Some(value.local_candidate.into()) } } } impl From for proto::rtc_stats::RemoteCandidate { fn from(value: rtc::RemoteCandidateStats) -> Self { - Self { - rtc: Some(value.rtc.into()), - candidate: Some(value.remote_candidate.into()), - } + Self { rtc: Some(value.rtc.into()), candidate: Some(value.remote_candidate.into()) } } } impl From for proto::rtc_stats::Certificate { fn from(value: rtc::CertificateStats) -> Self { - Self { - rtc: Some(value.rtc.into()), - certificate: Some(value.certificate.into()), - } + Self { rtc: Some(value.rtc.into()), certificate: Some(value.certificate.into()) } } } @@ -311,10 +285,7 @@ impl From for proto::rtc_stats::Certificate { impl From for proto::RtcStatsData { fn from(value: rtc::dictionaries::RtcStats) -> Self { - Self { - id: value.id, - timestamp: value.timestamp, - } + Self { id: value.id, timestamp: value.timestamp } } } @@ -414,10 +385,7 @@ impl From for proto::InboundRtpStreamS impl From for proto::SentRtpStreamStats { fn from(value: rtc::dictionaries::SentRtpStreamStats) -> Self { - Self { - packets_sent: value.packets_sent, - bytes_sent: value.bytes_sent, - } + Self { packets_sent: value.packets_sent, bytes_sent: value.bytes_sent } } } @@ -487,10 +455,7 @@ impl From for proto::RemoteOutb impl From for proto::MediaSourceStats { fn from(value: rtc::dictionaries::MediaSourceStats) -> Self { - Self { - track_identifier: value.track_identifier, - kind: value.kind, - } + Self { track_identifier: value.track_identifier, kind: value.kind } } } @@ -567,12 +532,8 @@ impl From for proto::TransportStats { bytes_received: value.bytes_received, ice_role: proto::IceRole::from(value.ice_role) as i32, ice_local_username_fragment: value.ice_local_username_fragment, - dtls_state: value - .dtls_state - .map(|v| proto::DtlsTransportState::from(v) as i32), - ice_state: value - .ice_state - .map(|v| proto::IceTransportState::from(v) as i32), + dtls_state: value.dtls_state.map(|v| proto::DtlsTransportState::from(v) as i32), + ice_state: value.ice_state.map(|v| proto::IceTransportState::from(v) as i32), selected_candidate_pair_id: value.selected_candidate_pair_id, local_certificate_id: value.local_certificate_id, remote_certificate_id: value.remote_certificate_id, @@ -591,9 +552,7 @@ impl From for proto::CandidatePairStats { transport_id: value.transport_id, local_candidate_id: value.local_candidate_id, remote_candidate_id: value.remote_candidate_id, - state: value - .state - .map(|v| proto::IceCandidatePairState::from(v) as i32), + state: value.state.map(|v| proto::IceCandidatePairState::from(v) as i32), nominated: value.nominated, packets_sent: value.packets_sent, packets_received: value.packets_received, @@ -623,9 +582,7 @@ impl From for proto::IceCandidateStats { address: value.address, port: value.port, protocol: value.protocol, - candidate_type: value - .candidate_type - .map(|v| proto::IceCandidateType::from(v) as i32), + candidate_type: value.candidate_type.map(|v| proto::IceCandidateType::from(v) as i32), priority: value.priority, url: value.url, relay_protocol: value @@ -635,9 +592,7 @@ impl From for proto::IceCandidateStats { related_address: value.related_address, related_port: value.related_port, username_fragment: value.username_fragment, - tcp_type: value - .tcp_type - .map(|v| proto::IceTcpCandidateType::from(v) as i32), + tcp_type: value.tcp_type.map(|v| proto::IceTcpCandidateType::from(v) as i32), } } } diff --git a/livekit-ffi/src/conversion/track.rs b/livekit-ffi/src/conversion/track.rs index 145f6a6b..a839fa3f 100644 --- a/livekit-ffi/src/conversion/track.rs +++ b/livekit-ffi/src/conversion/track.rs @@ -12,11 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use livekit::prelude::*; + use crate::{ proto, server::room::{FfiPublication, FfiTrack}, }; -use livekit::prelude::*; impl From<&FfiPublication> for proto::TrackPublicationInfo { fn from(value: &FfiPublication) -> Self { diff --git a/livekit-ffi/src/conversion/video_frame.rs b/livekit-ffi/src/conversion/video_frame.rs index 1fe56ab7..988562a4 100644 --- a/livekit-ffi/src/conversion/video_frame.rs +++ b/livekit-ffi/src/conversion/video_frame.rs @@ -12,20 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::proto; -use crate::server::video_source::FfiVideoSource; -use crate::server::video_stream::FfiVideoStream; -use livekit::options::{VideoCodec, VideoResolution}; -use livekit::webrtc::prelude::*; -use livekit::webrtc::video_frame; -use livekit::webrtc::video_source::VideoResolution as VideoSourceResolution; +use livekit::{ + options::{VideoCodec, VideoResolution}, + webrtc::{prelude::*, video_frame, video_source::VideoResolution as VideoSourceResolution}, +}; + +use crate::{ + proto, + server::{video_source::FfiVideoSource, video_stream::FfiVideoStream}, +}; impl From for VideoSourceResolution { fn from(res: proto::VideoSourceResolution) -> Self { - Self { - width: res.width, - height: res.height, - } + Self { width: res.width, height: res.height } } } @@ -43,17 +42,13 @@ impl proto::VideoFrameInfo { impl From<&FfiVideoSource> for proto::VideoSourceInfo { fn from(source: &FfiVideoSource) -> Self { - Self { - r#type: source.source_type as i32, - } + Self { r#type: source.source_type as i32 } } } impl From<&FfiVideoStream> for proto::VideoStreamInfo { fn from(stream: &FfiVideoStream) -> Self { - Self { - r#type: stream.stream_type as i32, - } + Self { r#type: stream.stream_type as i32 } } } diff --git a/livekit-ffi/src/lib.rs b/livekit-ffi/src/lib.rs index 3fbf12b8..0e042633 100644 --- a/livekit-ffi/src/lib.rs +++ b/livekit-ffi/src/lib.rs @@ -12,11 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::borrow::Cow; + use lazy_static::lazy_static; use livekit::prelude::*; -use prost::Message; -use server::FfiDataBuffer; -use std::{borrow::Cow, sync::Arc}; use thiserror::Error; mod conversion; diff --git a/livekit-ffi/src/server/audio_source.rs b/livekit-ffi/src/server/audio_source.rs index c1c6e48d..da263011 100644 --- a/livekit-ffi/src/server/audio_source.rs +++ b/livekit-ffi/src/server/audio_source.rs @@ -14,9 +14,10 @@ use std::{borrow::Cow, slice}; +use livekit::webrtc::prelude::*; + use super::FfiHandle; use crate::{proto, server, FfiError, FfiHandleId, FfiResult}; -use livekit::webrtc::prelude::*; pub struct FfiAudioSource { pub handle_id: FfiHandleId, @@ -46,19 +47,11 @@ impl FfiAudioSource { ); RtcAudioSource::Native(audio_source) } - _ => { - return Err(FfiError::InvalidRequest( - "unsupported audio source type".into(), - )) - } + _ => return Err(FfiError::InvalidRequest("unsupported audio source type".into())), }; let handle_id = server.next_id(); - let source = Self { - handle_id, - source_type, - source: source_inner, - }; + let source = Self { handle_id, source_type, source: source_inner }; let info = proto::AudioSourceInfo::from(&source); server.store_handle(source.handle_id, source); diff --git a/livekit-ffi/src/server/audio_stream.rs b/livekit-ffi/src/server/audio_stream.rs index 2d07e6f9..5fcd4488 100644 --- a/livekit-ffi/src/server/audio_stream.rs +++ b/livekit-ffi/src/server/audio_stream.rs @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::room::FfiTrack; -use super::FfiHandle; -use crate::{proto, server, FfiError, FfiHandleId, FfiResult}; use futures_util::StreamExt; -use livekit::webrtc::audio_stream::native::NativeAudioStream; -use livekit::webrtc::prelude::*; +use livekit::webrtc::{audio_stream::native::NativeAudioStream, prelude::*}; use tokio::sync::oneshot; +use super::{room::FfiTrack, FfiHandle}; +use crate::{proto, server, FfiError, FfiHandleId, FfiResult}; + pub struct FfiAudioStream { pub handle_id: FfiHandleId, pub stream_type: proto::AudioStreamType, @@ -43,9 +42,7 @@ impl FfiAudioStream { server: &'static server::FfiServer, new_stream: proto::NewAudioStreamRequest, ) -> FfiResult { - let ffi_track = server - .retrieve_handle::(new_stream.track_handle)? - .clone(); + let ffi_track = server.retrieve_handle::(new_stream.track_handle)?.clone(); let rtc_track = ffi_track.track.rtc_track(); let MediaStreamTrack::Audio(rtc_track) = rtc_track else { @@ -58,11 +55,7 @@ impl FfiAudioStream { let audio_stream = match stream_type { #[cfg(not(target_arch = "wasm32"))] proto::AudioStreamType::AudioStreamNative => { - let audio_stream = Self { - handle_id, - stream_type, - close_tx, - }; + let audio_stream = Self { handle_id, stream_type, close_tx }; let native_stream = NativeAudioStream::new(rtc_track); server.async_runtime.spawn(Self::native_audio_stream_task( @@ -73,11 +66,7 @@ impl FfiAudioStream { )); Ok::(audio_stream) } - _ => { - return Err(FfiError::InvalidRequest( - "unsupported audio stream type".into(), - )) - } + _ => return Err(FfiError::InvalidRequest("unsupported audio stream type".into())), }?; // Store AudioStreamInfothe new audio stream and return the info @@ -130,14 +119,10 @@ impl FfiAudioStream { } if let Err(err) = server - .send_event(proto::ffi_event::Message::AudioStreamEvent( - proto::AudioStreamEvent { - stream_handle: stream_handle_id, - message: Some(proto::audio_stream_event::Message::Eos( - proto::AudioStreamEos {}, - )), - }, - )) + .send_event(proto::ffi_event::Message::AudioStreamEvent(proto::AudioStreamEvent { + stream_handle: stream_handle_id, + message: Some(proto::audio_stream_event::Message::Eos(proto::AudioStreamEos {})), + })) .await { log::warn!("failed to send audio EOS: {}", err); diff --git a/livekit-ffi/src/server/logger.rs b/livekit-ffi/src/server/logger.rs index b4c777a3..6262bd0f 100644 --- a/livekit-ffi/src/server/logger.rs +++ b/livekit-ffi/src/server/logger.rs @@ -1,11 +1,14 @@ -use crate::proto; -use crate::FFI_SERVER; +use std::{ + sync::atomic::{AtomicBool, Ordering}, + time::Duration, +}; + use env_logger; use log::{self, Log}; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::time::Duration; use tokio::sync::{mpsc, oneshot}; +use crate::{proto, FFI_SERVER}; + pub const FLUSH_INTERVAL: Duration = Duration::from_secs(1); pub const BATCH_SIZE: usize = 32; diff --git a/livekit-ffi/src/server/mod.rs b/livekit-ffi/src/server/mod.rs index 9eaed35d..fb0373ec 100644 --- a/livekit-ffi/src/server/mod.rs +++ b/livekit-ffi/src/server/mod.rs @@ -12,20 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::proto::FfiEvent; -use crate::{proto, INVALID_HANDLE}; -use crate::{FfiError, FfiHandleId, FfiResult}; -use dashmap::mapref::one::MappedRef; -use dashmap::DashMap; +use std::{ + sync::{ + atomic::{AtomicU64, Ordering}, + Arc, + }, + thread, + time::Duration, +}; + +use dashmap::{mapref::one::MappedRef, DashMap}; use downcast_rs::{impl_downcast, Downcast}; -use livekit::webrtc::native::audio_resampler::AudioResampler; -use livekit::webrtc::prelude::*; -use parking_lot::deadlock; -use parking_lot::Mutex; -use std::sync::atomic::{AtomicU64, Ordering}; -use std::sync::Arc; -use std::thread; -use std::time::Duration; +use livekit::webrtc::{native::audio_resampler::AudioResampler, prelude::*}; +use parking_lot::{deadlock, Mutex}; + +use crate::{proto, proto::FfiEvent, FfiError, FfiHandleId, FfiResult, INVALID_HANDLE}; pub mod audio_source; pub mod audio_stream; @@ -73,14 +74,10 @@ pub struct FfiServer { impl Default for FfiServer { fn default() -> Self { - let async_runtime = tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap(); - - let logger = Box::leak(Box::new(logger::FfiLogger::new( - async_runtime.handle().clone(), - ))); + let async_runtime = + tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap(); + + let logger = Box::leak(Box::new(logger::FfiLogger::new(async_runtime.handle().clone()))); log::set_logger(logger).unwrap(); log::set_max_level(log::LevelFilter::Trace); @@ -145,15 +142,14 @@ impl FfiServer { } pub async fn send_event(&self, message: proto::ffi_event::Message) -> FfiResult<()> { - let cb = self.config.lock().as_ref().map_or_else( - || Err(FfiError::NotConfigured), - |c| Ok(c.callback_fn.clone()), - )?; + let cb = self + .config + .lock() + .as_ref() + .map_or_else(|| Err(FfiError::NotConfigured), |c| Ok(c.callback_fn.clone()))?; let cb_task = self.async_runtime.spawn_blocking(move || { - cb(proto::FfiEvent { - message: Some(message), - }); + cb(proto::FfiEvent { message: Some(message) }); }); tokio::select! { @@ -188,10 +184,8 @@ impl FfiServer { return Err(FfiError::InvalidRequest("handle is invalid".into())); } - let handle = self - .ffi_handles - .get(&id) - .ok_or(FfiError::InvalidRequest("handle not found".into()))?; + let handle = + self.ffi_handles.get(&id).ok_or(FfiError::InvalidRequest("handle not found".into()))?; if !handle.is::() { let tyname = std::any::type_name::(); diff --git a/livekit-ffi/src/server/requests.rs b/livekit-ffi/src/server/requests.rs index fe0905dc..56fd5cbf 100644 --- a/livekit-ffi/src/server/requests.rs +++ b/livekit-ffi/src/server/requests.rs @@ -12,18 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::room::{FfiParticipant, FfiPublication, FfiTrack}; +use std::{slice, sync::Arc}; + +use livekit::{ + prelude::*, + webrtc::{ + native::{audio_resampler, yuv_helper}, + prelude::*, + video_frame::{BoxVideoBuffer, I420Buffer}, + }, +}; +use parking_lot::Mutex; + use super::{ - audio_source, audio_stream, room, video_source, video_stream, FfiError, FfiResult, FfiServer, + audio_source, audio_stream, room, + room::{FfiParticipant, FfiPublication, FfiTrack}, + video_source, video_stream, FfiError, FfiResult, FfiServer, }; use crate::proto; -use livekit::prelude::*; -use livekit::webrtc::native::{audio_resampler, yuv_helper}; -use livekit::webrtc::prelude::*; -use livekit::webrtc::video_frame::{BoxVideoBuffer, I420Buffer}; -use parking_lot::Mutex; -use std::slice; -use std::sync::Arc; /// Dispose the server, close all rooms and clean up all handles /// It is not mandatory to call this function. @@ -59,17 +65,15 @@ fn on_disconnect( ) -> FfiResult { let async_id = server.next_id(); server.async_runtime.spawn(async move { - let ffi_room = server - .retrieve_handle::(disconnect.room_handle) - .unwrap() - .clone(); + let ffi_room = + server.retrieve_handle::(disconnect.room_handle).unwrap().clone(); ffi_room.close().await; let _ = server - .send_event(proto::ffi_event::Message::Disconnect( - proto::DisconnectCallback { async_id }, - )) + .send_event(proto::ffi_event::Message::Disconnect(proto::DisconnectCallback { + async_id, + })) .await; }); @@ -82,9 +86,8 @@ fn on_publish_track( server: &'static FfiServer, publish: proto::PublishTrackRequest, ) -> FfiResult { - let ffi_participant = server - .retrieve_handle::(publish.local_participant_handle)? - .clone(); + let ffi_participant = + server.retrieve_handle::(publish.local_participant_handle)?.clone(); Ok(ffi_participant.room.publish_track(server, publish)) } @@ -94,9 +97,8 @@ fn on_unpublish_track( server: &'static FfiServer, unpublish: proto::UnpublishTrackRequest, ) -> FfiResult { - let ffi_participant = server - .retrieve_handle::(unpublish.local_participant_handle)? - .clone(); + let ffi_participant = + server.retrieve_handle::(unpublish.local_participant_handle)?.clone(); Ok(ffi_participant.room.unpublish_track(server, unpublish)) } @@ -122,9 +124,7 @@ fn on_set_subscribed( server.retrieve_handle::(set_subscribed.publication_handle)?; let TrackPublication::Remote(publication) = &ffi_publication.publication else { - return Err(FfiError::InvalidRequest( - "publication is not a RemotePublication".into(), - )); + return Err(FfiError::InvalidRequest("publication is not a RemotePublication".into())); }; let _guard = server.async_runtime.enter(); @@ -140,9 +140,7 @@ fn on_update_local_metadata( .retrieve_handle::(update_local_metadata.local_participant_handle)? .clone(); - Ok(ffi_participant - .room - .update_local_metadata(server, update_local_metadata)) + Ok(ffi_participant.room.update_local_metadata(server, update_local_metadata)) } fn on_update_local_name( @@ -153,9 +151,7 @@ fn on_update_local_name( .retrieve_handle::(update_local_name.local_participant_handle)? .clone(); - Ok(ffi_participant - .room - .update_local_name(server, update_local_name)) + Ok(ffi_participant.room.update_local_name(server, update_local_name)) } /// Create a new video track from a source @@ -170,10 +166,7 @@ fn on_create_video_track( let handle_id = server.next_id(); let video_track = LocalVideoTrack::create_video_track(&create.name, source); - let ffi_track = FfiTrack { - handle: handle_id, - track: Track::LocalVideo(video_track), - }; + let ffi_track = FfiTrack { handle: handle_id, track: Track::LocalVideo(video_track) }; let track_info = proto::TrackInfo::from(&ffi_track); server.store_handle(handle_id, ffi_track); @@ -198,10 +191,7 @@ fn on_create_audio_track( let handle_id = server.next_id(); let audio_track = LocalAudioTrack::create_audio_track(&create.name, source); - let ffi_track = FfiTrack { - handle: handle_id, - track: Track::LocalAudio(audio_track), - }; + let ffi_track = FfiTrack { handle: handle_id, track: Track::LocalAudio(audio_track) }; let track_info = proto::TrackInfo::from(&ffi_track); server.store_handle(handle_id, ffi_track); @@ -218,9 +208,7 @@ fn on_get_stats( server: &'static FfiServer, get_stats: proto::GetStatsRequest, ) -> FfiResult { - let ffi_track = server - .retrieve_handle::(get_stats.track_handle)? - .clone(); + let ffi_track = server.retrieve_handle::(get_stats.track_handle)?.clone(); let async_id = server.next_id(); @@ -228,24 +216,20 @@ fn on_get_stats( match ffi_track.track.get_stats().await { Ok(stats) => { let _ = server - .send_event(proto::ffi_event::Message::GetStats( - proto::GetStatsCallback { - async_id, - error: None, - stats: stats.into_iter().map(Into::into).collect(), - }, - )) + .send_event(proto::ffi_event::Message::GetStats(proto::GetStatsCallback { + async_id, + error: None, + stats: stats.into_iter().map(Into::into).collect(), + })) .await; } Err(err) => { let _ = server - .send_event(proto::ffi_event::Message::GetStats( - proto::GetStatsCallback { - async_id, - error: Some(err.to_string()), - stats: Vec::default(), - }, - )) + .send_event(proto::ffi_event::Message::GetStats(proto::GetStatsCallback { + async_id, + error: Some(err.to_string()), + stats: Vec::default(), + })) .await; } } @@ -261,11 +245,7 @@ fn on_alloc_video_buffer( ) -> FfiResult { let buffer: BoxVideoBuffer = match alloc.r#type() { proto::VideoFrameBufferType::I420 => Box::new(I420Buffer::new(alloc.width, alloc.height)), - _ => { - return Err(FfiError::InvalidRequest( - "frame type is not supported".into(), - )) - } + _ => return Err(FfiError::InvalidRequest("frame type is not supported".into())), }; let handle_id = server.next_id(); @@ -286,9 +266,7 @@ fn on_new_video_stream( new_stream: proto::NewVideoStreamRequest, ) -> FfiResult { let stream_info = video_stream::FfiVideoStream::setup(server, new_stream)?; - Ok(proto::NewVideoStreamResponse { - stream: Some(stream_info), - }) + Ok(proto::NewVideoStreamResponse { stream: Some(stream_info) }) } /// Create a new video source, used to publish data to a track @@ -297,9 +275,7 @@ fn on_new_video_source( new_source: proto::NewVideoSourceRequest, ) -> FfiResult { let source_info = video_source::FfiVideoSource::setup(server, new_source)?; - Ok(proto::NewVideoSourceResponse { - source: Some(source_info), - }) + Ok(proto::NewVideoSourceResponse { source: Some(source_info) }) } /// Push a frame to a source, libwebrtc will then decide if the frame should be dropped or not @@ -322,9 +298,7 @@ unsafe fn on_to_i420( server: &'static FfiServer, to_i420: proto::ToI420Request, ) -> FfiResult { - let from = to_i420 - .from - .ok_or(FfiError::InvalidRequest("from is empty".into()))?; + let from = to_i420.from.ok_or(FfiError::InvalidRequest("from is empty".into()))?; #[rustfmt::skip] let i420 = match from { @@ -439,10 +413,8 @@ unsafe fn on_to_argb( _server: &'static FfiServer, to_argb: proto::ToArgbRequest, ) -> FfiResult { - let buffer = to_argb - .buffer - .as_ref() - .ok_or(FfiError::InvalidRequest("buffer is empty".into()))?; + let buffer = + to_argb.buffer.as_ref().ok_or(FfiError::InvalidRequest("buffer is empty".into()))?; let argb = slice::from_raw_parts_mut( to_argb.dst_ptr as *mut u8, @@ -457,9 +429,7 @@ unsafe fn on_to_argb( match buffer.buffer_type() { proto::VideoFrameBufferType::I420 => { let Some(proto::video_frame_buffer_info::Buffer::Yuv(yuv)) = &buffer.buffer else { - return Err(FfiError::InvalidRequest( - "invalid i420 buffer description".into(), - )); + return Err(FfiError::InvalidRequest("invalid i420 buffer description".into())); }; #[rustfmt::skip] @@ -488,11 +458,7 @@ unsafe fn on_to_argb( } } } - _ => { - return Err(FfiError::InvalidRequest( - "to_argb buffer type is not supported".into(), - )) - } + _ => return Err(FfiError::InvalidRequest("to_argb buffer type is not supported".into())), } Ok(proto::ToArgbResponse::default()) @@ -503,11 +469,7 @@ fn on_alloc_audio_buffer( server: &'static FfiServer, alloc: proto::AllocAudioBufferRequest, ) -> FfiResult { - let frame = AudioFrame::new( - alloc.sample_rate, - alloc.num_channels, - alloc.samples_per_channel, - ); + let frame = AudioFrame::new(alloc.sample_rate, alloc.num_channels, alloc.samples_per_channel); let handle_id = server.next_id(); let buffer_info = proto::AudioFrameBufferInfo::from(&frame); @@ -527,9 +489,7 @@ fn on_new_audio_stream( new_stream: proto::NewAudioStreamRequest, ) -> FfiResult { let stream_info = audio_stream::FfiAudioStream::setup(server, new_stream)?; - Ok(proto::NewAudioStreamResponse { - stream: Some(stream_info), - }) + Ok(proto::NewAudioStreamResponse { stream: Some(stream_info) }) } /// Create a new audio source (used to publish audio frames to a track) @@ -538,9 +498,7 @@ fn on_new_audio_source( new_source: proto::NewAudioSourceRequest, ) -> FfiResult { let source_info = audio_source::FfiAudioSource::setup(server, new_source)?; - Ok(proto::NewAudioSourceResponse { - source: Some(source_info), - }) + Ok(proto::NewAudioSourceResponse { source: Some(source_info) }) } /// Push a frame to a source @@ -580,9 +538,7 @@ fn remix_and_resample( .retrieve_handle::>>(remix.resampler_handle)? .clone(); - let buffer = remix - .buffer - .ok_or(FfiError::InvalidRequest("buffer is empty".into()))?; + let buffer = remix.buffer.ok_or(FfiError::InvalidRequest("buffer is empty".into()))?; let data = unsafe { let len = (buffer.num_channels * buffer.samples_per_channel) as usize; @@ -629,9 +585,7 @@ fn on_e2ee_request( let ffi_room = server.retrieve_handle::(request.room_handle)?; let e2ee_manager = ffi_room.inner.room.e2ee_manager(); - let request = request - .message - .ok_or(FfiError::InvalidRequest("message is empty".into()))?; + let request = request.message.ok_or(FfiError::InvalidRequest("message is empty".into()))?; let msg = match request { proto::e2ee_request::Message::ManagerSetEnabled(request) => { @@ -654,9 +608,7 @@ fn on_e2ee_request( .collect(); proto::e2ee_response::Message::ManagerGetFrameCryptors( - proto::E2eeManagerGetFrameCryptorsResponse { - frame_cryptors: proto_frame_cryptors, - }, + proto::E2eeManagerGetFrameCryptorsResponse { frame_cryptors: proto_frame_cryptors }, ) } proto::e2ee_request::Message::CryptorSetEnabled(request) => { @@ -740,9 +692,7 @@ fn on_get_session_stats( server: &'static FfiServer, get_session_stats: proto::GetSessionStatsRequest, ) -> FfiResult { - let ffi_room = server - .retrieve_handle::(get_session_stats.room_handle)? - .clone(); + let ffi_room = server.retrieve_handle::(get_session_stats.room_handle)?.clone(); let async_id = server.next_id(); server.async_runtime.spawn(async move { @@ -789,9 +739,7 @@ pub fn handle_request( server: &'static FfiServer, request: proto::FfiRequest, ) -> FfiResult { - let request = request - .message - .ok_or(FfiError::InvalidRequest("message is empty".into()))?; + let request = request.message.ok_or(FfiError::InvalidRequest("message is empty".into()))?; let mut res = proto::FfiResponse::default(); diff --git a/livekit-ffi/src/server/room.rs b/livekit-ffi/src/server/room.rs index 2022757b..83487e41 100644 --- a/livekit-ffi/src/server/room.rs +++ b/livekit-ffi/src/server/room.rs @@ -12,19 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::server::{FfiHandle, FfiServer}; -use crate::{proto, FfiError, FfiHandleId, FfiResult}; +use std::{collections::HashSet, slice, sync::Arc, time::Duration}; + use livekit::prelude::*; use parking_lot::Mutex; -use std::collections::HashSet; -use std::slice; -use std::sync::Arc; -use std::time::Duration; -use tokio::sync::{broadcast, mpsc}; -use tokio::sync::{oneshot, Mutex as AsyncMutex}; -use tokio::task::JoinHandle; +use tokio::{ + sync::{broadcast, mpsc, oneshot, Mutex as AsyncMutex}, + task::JoinHandle, +}; use super::FfiDataBuffer; +use crate::{ + proto, + server::{FfiHandle, FfiServer}, + FfiError, FfiHandleId, FfiResult, +}; #[derive(Clone)] pub struct FfiParticipant { @@ -97,9 +99,8 @@ impl FfiRoom { Ok((room, mut events)) => { // Successfully connected to the room // Forward the initial state for the FfiClient - let Some(RoomEvent::Connected { - participants_with_tracks, - }) = events.recv().await + let Some(RoomEvent::Connected { participants_with_tracks }) = + events.recv().await else { unreachable!("Connected event should always be the first event"); }; @@ -120,14 +121,14 @@ impl FfiRoom { build_initial_states(server, &inner, participants_with_tracks); // Send callback - let ffi_room = Self { - inner: inner.clone(), - handle: Default::default(), - }; + let ffi_room = Self { inner: inner.clone(), handle: Default::default() }; server.store_handle(ffi_room.inner.handle_id, ffi_room.clone()); - // Keep the lock until the handle is "Some" (So it is OK for the client to request a disconnect quickly after connecting) - // (When requesting a disconnect, the handle will still be locked and the disconnect will wait for the lock to be released and gracefully close the room) + // Keep the lock until the handle is "Some" (So it is OK for the client to + // request a disconnect quickly after connecting) + // (When requesting a disconnect, the handle will still be locked and the + // disconnect will wait for the lock to be released and gracefully close the + // room) let mut handle = ffi_room.handle.lock().await; let room_info = proto::RoomInfo::from(&ffi_room); @@ -154,11 +155,7 @@ impl FfiRoom { let data_handle = tokio::spawn(data_task(server, inner.clone(), data_rx, close_rx)); // Publish data - *handle = Some(Handle { - event_handle, - data_handle, - close_tx, - }); + *handle = Some(Handle { event_handle, data_handle, close_tx }); } Err(e) => { // Failed to connect to the room, send an error message to the FfiClient @@ -220,12 +217,10 @@ impl RoomInner { server.async_runtime.spawn(async move { let cb = proto::PublishDataCallback { async_id, - error: Some(format!("failed to send data, room closed: {}", err).into()), + error: Some(format!("failed to send data, room closed: {}", err)), }; - let _ = server - .send_event(proto::ffi_event::Message::PublishData(cb)) - .await; + let _ = server.send_event(proto::ffi_event::Message::PublishData(cb)).await; }); } @@ -244,9 +239,7 @@ impl RoomInner { let inner = self.clone(); server.async_runtime.spawn(async move { let publish_res = async { - let ffi_track = server - .retrieve_handle::(publish.track_handle)? - .clone(); + let ffi_track = server.retrieve_handle::(publish.track_handle)?.clone(); let track = LocalTrack::try_from(ffi_track.track.clone()) .map_err(|_| FfiError::InvalidRequest("track is not a LocalTrack".into()))?; @@ -285,10 +278,7 @@ impl RoomInner { )) .await; - inner - .pending_published_tracks - .lock() - .insert(publication.sid()); + inner.pending_published_tracks.lock().insert(publication.sid()); } Err(err) => { // Failed to publish the track @@ -310,7 +300,8 @@ impl RoomInner { /// Unpublish a track and make sure to sync the async callback /// with the LocalTrackUnpublished event. - /// Contrary to publish_track, the LocalTrackUnpublished event must be sent *before* the async callback. + /// Contrary to publish_track, the LocalTrackUnpublished event must be sent *before* the async + /// callback. pub fn unpublish_track( self: &Arc, server: &'static FfiServer, @@ -379,11 +370,7 @@ impl RoomInner { let async_id = server.next_id(); let inner = self.clone(); server.async_runtime.spawn(async move { - let _ = inner - .room - .local_participant() - .update_name(update_local_name.name) - .await; + let _ = inner.room.local_participant().update_name(update_local_name.name).await; let _ = server .send_event(proto::ffi_event::Message::UpdateLocalName( @@ -437,9 +424,7 @@ async fn room_task( mut events: mpsc::UnboundedReceiver, mut close_rx: broadcast::Receiver<()>, ) { - let present_state = Arc::new(Mutex::new(ActualState { - reconnecting: false, - })); + let present_state = Arc::new(Mutex::new(ActualState { reconnecting: false })); loop { tokio::select! { @@ -511,24 +496,19 @@ async fn forward_event( } RoomEvent::ParticipantDisconnected(participant) => { let _ = send_event(proto::room_event::Message::ParticipantDisconnected( - proto::ParticipantDisconnected { - participant_sid: participant.sid().into(), - }, + proto::ParticipantDisconnected { participant_sid: participant.sid().into() }, )) .await; } - RoomEvent::LocalTrackPublished { - publication, - track: _, - participant: _, - } => { + RoomEvent::LocalTrackPublished { publication, track: _, participant: _ } => { let sid = publication.sid(); // If we're currently reconnecting, users can't publish tracks, if we receive this // event it means the RoomEngine is republishing tracks to finish the reconnection // process. (So we're not waiting for any PublishCallback) if !present_state.lock().reconnecting { // Make sure to send the event *after* the async callback of the PublishTrackRequest - // Wait for the PublishTrack callback to be sent (waiting time is really short, so it is fine to not spawn a new task) + // Wait for the PublishTrack callback to be sent (waiting time is really short, so + // it is fine to not spawn a new task) loop { if inner.pending_published_tracks.lock().remove(&sid) { break; @@ -545,32 +525,19 @@ async fn forward_event( server.store_handle(ffi_publication.handle, ffi_publication); let _ = send_event(proto::room_event::Message::LocalTrackPublished( - proto::LocalTrackPublished { - track_sid: sid.to_string(), - }, + proto::LocalTrackPublished { track_sid: sid.to_string() }, )) .await; } - RoomEvent::LocalTrackUnpublished { - publication, - participant: _, - } => { + RoomEvent::LocalTrackUnpublished { publication, participant: _ } => { let _ = send_event(proto::room_event::Message::LocalTrackUnpublished( - proto::LocalTrackUnpublished { - publication_sid: publication.sid().into(), - }, + proto::LocalTrackUnpublished { publication_sid: publication.sid().into() }, )) .await; - inner - .pending_unpublished_tracks - .lock() - .insert(publication.sid()); + inner.pending_unpublished_tracks.lock().insert(publication.sid()); } - RoomEvent::TrackPublished { - publication, - participant, - } => { + RoomEvent::TrackPublished { publication, participant } => { let handle_id = server.next_id(); let ffi_publication = FfiPublication { handle: handle_id, @@ -580,59 +547,41 @@ async fn forward_event( let publication_info = proto::TrackPublicationInfo::from(&ffi_publication); server.store_handle(ffi_publication.handle, ffi_publication); - let _ = send_event(proto::room_event::Message::TrackPublished( - proto::TrackPublished { - participant_sid: participant.sid().to_string(), - publication: Some(proto::OwnedTrackPublication { - handle: Some(proto::FfiOwnedHandle { id: handle_id }), - info: Some(publication_info), - }), - }, - )) + let _ = send_event(proto::room_event::Message::TrackPublished(proto::TrackPublished { + participant_sid: participant.sid().to_string(), + publication: Some(proto::OwnedTrackPublication { + handle: Some(proto::FfiOwnedHandle { id: handle_id }), + info: Some(publication_info), + }), + })) .await; } - RoomEvent::TrackUnpublished { - publication, - participant, - } => { - let _ = send_event(proto::room_event::Message::TrackUnpublished( - proto::TrackUnpublished { + RoomEvent::TrackUnpublished { publication, participant } => { + let _ = + send_event(proto::room_event::Message::TrackUnpublished(proto::TrackUnpublished { participant_sid: participant.sid().to_string(), publication_sid: publication.sid().into(), - }, - )) - .await; + })) + .await; } - RoomEvent::TrackSubscribed { - track, - publication: _, - participant, - } => { + RoomEvent::TrackSubscribed { track, publication: _, participant } => { let handle_id = server.next_id(); - let ffi_track = FfiTrack { - handle: handle_id, - track: track.into(), - }; + let ffi_track = FfiTrack { handle: handle_id, track: track.into() }; let track_info = proto::TrackInfo::from(&ffi_track); server.store_handle(ffi_track.handle, ffi_track); - let _ = send_event(proto::room_event::Message::TrackSubscribed( - proto::TrackSubscribed { + let _ = + send_event(proto::room_event::Message::TrackSubscribed(proto::TrackSubscribed { participant_sid: participant.sid().to_string(), track: Some(proto::OwnedTrack { handle: Some(proto::FfiOwnedHandle { id: handle_id }), info: Some(track_info), }), - }, - )) - .await; + })) + .await; } - RoomEvent::TrackUnsubscribed { - track, - publication: _, - participant, - } => { + RoomEvent::TrackUnsubscribed { track, publication: _, participant } => { let _ = send_event(proto::room_event::Message::TrackUnsubscribed( proto::TrackUnsubscribed { participant_sid: participant.sid().to_string(), @@ -641,11 +590,7 @@ async fn forward_event( )) .await; } - RoomEvent::TrackSubscriptionFailed { - participant, - error, - track_sid, - } => { + RoomEvent::TrackSubscriptionFailed { participant, error, track_sid } => { let _ = send_event(proto::room_event::Message::TrackSubscriptionFailed( proto::TrackSubscriptionFailed { participant_sid: participant.sid().to_string(), @@ -655,42 +600,27 @@ async fn forward_event( )) .await; } - RoomEvent::TrackMuted { - participant, - publication, - } => { + RoomEvent::TrackMuted { participant, publication } => { let _ = send_event(proto::room_event::Message::TrackMuted(proto::TrackMuted { participant_sid: participant.sid().to_string(), track_sid: publication.sid().into(), })) .await; } - RoomEvent::TrackUnmuted { - participant, - publication, - } => { - let _ = send_event(proto::room_event::Message::TrackUnmuted( - proto::TrackUnmuted { - participant_sid: participant.sid().to_string(), - track_sid: publication.sid().into(), - }, - )) + RoomEvent::TrackUnmuted { participant, publication } => { + let _ = send_event(proto::room_event::Message::TrackUnmuted(proto::TrackUnmuted { + participant_sid: participant.sid().to_string(), + track_sid: publication.sid().into(), + })) .await; } - RoomEvent::RoomMetadataChanged { - old_metadata: _, - metadata, - } => { + RoomEvent::RoomMetadataChanged { old_metadata: _, metadata } => { let _ = send_event(proto::room_event::Message::RoomMetadataChanged( proto::RoomMetadataChanged { metadata }, )) .await; } - RoomEvent::ParticipantMetadataChanged { - participant, - old_metadata: _, - metadata, - } => { + RoomEvent::ParticipantMetadataChanged { participant, old_metadata: _, metadata } => { let _ = send_event(proto::room_event::Message::ParticipantMetadataChanged( proto::ParticipantMetadataChanged { participant_sid: participant.sid().to_string(), @@ -699,11 +629,7 @@ async fn forward_event( )) .await; } - RoomEvent::ParticipantNameChanged { - participant, - old_name: _, - name, - } => { + RoomEvent::ParticipantNameChanged { participant, old_name: _, name } => { let _ = send_event(proto::room_event::Message::ParticipantNameChanged( proto::ParticipantNameChanged { participant_sid: participant.sid().to_string(), @@ -713,20 +639,14 @@ async fn forward_event( .await; } RoomEvent::ActiveSpeakersChanged { speakers } => { - let participant_sids = speakers - .iter() - .map(|p| p.sid().to_string()) - .collect::>(); + let participant_sids = speakers.iter().map(|p| p.sid().to_string()).collect::>(); let _ = send_event(proto::room_event::Message::ActiveSpeakersChanged( proto::ActiveSpeakersChanged { participant_sids }, )) .await; } - RoomEvent::ConnectionQualityChanged { - quality, - participant, - } => { + RoomEvent::ConnectionQualityChanged { quality, participant } => { let _ = send_event(proto::room_event::Message::ConnectionQualityChanged( proto::ConnectionQualityChanged { participant_sid: participant.sid().to_string(), @@ -735,43 +655,28 @@ async fn forward_event( )) .await; } - RoomEvent::DataReceived { - payload, - kind, - participant, - topic, - } => { + RoomEvent::DataReceived { payload, kind, participant, topic } => { let handle_id = server.next_id(); let buffer_info = proto::BufferInfo { data_ptr: payload.as_ptr() as u64, data_len: payload.len() as u64, }; - server.store_handle( - handle_id, - FfiDataBuffer { - handle: handle_id, - data: payload, - }, - ); - let _ = send_event(proto::room_event::Message::DataReceived( - proto::DataReceived { - data: Some(proto::OwnedBuffer { - handle: Some(proto::FfiOwnedHandle { id: handle_id }), - data: Some(buffer_info), - }), - participant_sid: participant.map(|p| p.sid().to_string()), - kind: proto::DataPacketKind::from(kind).into(), - topic, - }, - )) + server.store_handle(handle_id, FfiDataBuffer { handle: handle_id, data: payload }); + let _ = send_event(proto::room_event::Message::DataReceived(proto::DataReceived { + data: Some(proto::OwnedBuffer { + handle: Some(proto::FfiOwnedHandle { id: handle_id }), + data: Some(buffer_info), + }), + participant_sid: participant.map(|p| p.sid().to_string()), + kind: proto::DataPacketKind::from(kind).into(), + topic, + })) .await; } RoomEvent::ConnectionStateChanged(state) => { let _ = send_event(proto::room_event::Message::ConnectionStateChanged( - proto::ConnectionStateChanged { - state: proto::ConnectionState::from(state).into(), - }, + proto::ConnectionStateChanged { state: proto::ConnectionState::from(state).into() }, )) .await; } @@ -779,33 +684,26 @@ async fn forward_event( // Ignore here, we're already sent the event on connect (see above) } RoomEvent::Disconnected { reason: _ } => { - let _ = send_event(proto::room_event::Message::Disconnected( - proto::Disconnected {}, - )) - .await; + let _ = + send_event(proto::room_event::Message::Disconnected(proto::Disconnected {})).await; } RoomEvent::Reconnecting => { present_state.lock().reconnecting = true; - let _ = send_event(proto::room_event::Message::Reconnecting( - proto::Reconnecting {}, - )) - .await; + let _ = + send_event(proto::room_event::Message::Reconnecting(proto::Reconnecting {})).await; } RoomEvent::Reconnected => { present_state.lock().reconnecting = false; - let _ = send_event(proto::room_event::Message::Reconnected( - proto::Reconnected {}, - )) - .await; + let _ = + send_event(proto::room_event::Message::Reconnected(proto::Reconnected {})).await; } RoomEvent::E2eeStateChanged { participant, state } => { - let _ = send_event(proto::room_event::Message::E2eeStateChanged( - proto::E2eeStateChanged { + let _ = + send_event(proto::room_event::Message::E2eeStateChanged(proto::E2eeStateChanged { participant_sid: participant.sid().to_string(), state: proto::EncryptionState::from(state).into(), - }, - )) - .await; + })) + .await; } _ => { log::warn!("unhandled room event: {:?}", event); @@ -817,10 +715,7 @@ fn build_initial_states( server: &'static FfiServer, inner: &Arc, participants_with_tracks: Vec<(RemoteParticipant, Vec)>, -) -> ( - proto::OwnedParticipant, - Vec, -) { +) -> (proto::OwnedParticipant, Vec) { let local_participant = inner.room.local_participant(); // Is it too late to get the local participant info here? let handle_id = server.next_id(); let local_participant = FfiParticipant { diff --git a/livekit-ffi/src/server/video_source.rs b/livekit-ffi/src/server/video_source.rs index 3d68f138..4f38a0f1 100644 --- a/livekit-ffi/src/server/video_source.rs +++ b/livekit-ffi/src/server/video_source.rs @@ -13,11 +13,14 @@ // limitations under the License. use std::slice; -use crate::{proto, server, FfiError, FfiHandleId, FfiResult}; -use livekit::webrtc::prelude::*; -use livekit::webrtc::video_frame::{BoxVideoBuffer, VideoFrame}; + +use livekit::webrtc::{ + prelude::*, + video_frame::{BoxVideoBuffer, VideoFrame}, +}; use super::FfiHandle; +use crate::{proto, server, FfiError, FfiHandleId, FfiResult}; pub struct FfiVideoSource { pub handle_id: FfiHandleId, @@ -45,19 +48,11 @@ impl FfiVideoSource { ); RtcVideoSource::Native(video_source) } - _ => { - return Err(FfiError::InvalidRequest( - "unsupported video source type".into(), - )) - } + _ => return Err(FfiError::InvalidRequest("unsupported video source type".into())), }; let handle_id = server.next_id(); - let video_source = Self { - handle_id, - source_type, - source: source_inner, - }; + let video_source = Self { handle_id, source_type, source: source_inner }; let source_info = proto::VideoSourceInfo::from(&video_source); server.store_handle(handle_id, video_source); @@ -72,17 +67,14 @@ impl FfiVideoSource { server: &'static server::FfiServer, capture: proto::CaptureVideoFrameRequest, ) -> FfiResult<()> { - match self.source { #[cfg(not(target_arch = "wasm32"))] RtcVideoSource::Native(ref source) => { - let frame_info = capture - .frame - .ok_or(FfiError::InvalidRequest("frame is empty".into()))?; + let frame_info = + capture.frame.ok_or(FfiError::InvalidRequest("frame is empty".into()))?; - let from = capture - .from - .ok_or(FfiError::InvalidRequest("capture from is empty".into()))?; + let from = + capture.from.ok_or(FfiError::InvalidRequest("capture from is empty".into()))?; // copy the provided buffer #[rustfmt::skip] @@ -91,7 +83,7 @@ impl FfiVideoSource { match &info.buffer { Some(proto::video_frame_buffer_info::Buffer::Yuv(yuv)) => { match info.buffer_type() { - proto::VideoFrameBufferType::I420 + proto::VideoFrameBufferType::I420 | proto::VideoFrameBufferType::I420a | proto::VideoFrameBufferType::I422 | proto::VideoFrameBufferType::I444 => { @@ -106,7 +98,7 @@ impl FfiVideoSource { proto::VideoFrameBufferType::I420 | proto::VideoFrameBufferType::I420a => { let mut i420 = I420Buffer::with_strides(info.width, info.height, yuv.stride_y, yuv.stride_u, yuv.stride_v); let (dy, du, dv) = i420.data_mut(); - + dy.copy_from_slice(y); du.copy_from_slice(u); dv.copy_from_slice(v); @@ -163,7 +155,7 @@ impl FfiVideoSource { dy.copy_from_slice(y); duv.copy_from_slice(uv); - Box::new(nv12) as BoxVideoBuffer + Box::new(nv12) as BoxVideoBuffer } else { return Err(FfiError::InvalidRequest("invalid biyuv description".into())) } diff --git a/livekit-ffi/src/server/video_stream.rs b/livekit-ffi/src/server/video_stream.rs index 8a4c3b4e..23560701 100644 --- a/livekit-ffi/src/server/video_stream.rs +++ b/livekit-ffi/src/server/video_stream.rs @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::room::FfiTrack; -use super::FfiHandle; -use crate::{proto, server, FfiError, FfiHandleId, FfiResult}; use futures_util::StreamExt; -use livekit::webrtc::prelude::*; -use livekit::webrtc::video_stream::native::NativeVideoStream; +use livekit::webrtc::{prelude::*, video_stream::native::NativeVideoStream}; use tokio::sync::oneshot; +use super::{room::FfiTrack, FfiHandle}; +use crate::{proto, server, FfiError, FfiHandleId, FfiResult}; + pub struct FfiVideoStream { pub handle_id: FfiHandleId, pub stream_type: proto::VideoStreamType, @@ -43,9 +42,7 @@ impl FfiVideoStream { server: &'static server::FfiServer, new_stream: proto::NewVideoStreamRequest, ) -> FfiResult { - let ffi_track = server - .retrieve_handle::(new_stream.track_handle)? - .clone(); + let ffi_track = server.retrieve_handle::(new_stream.track_handle)?.clone(); let rtc_track = ffi_track.track.rtc_track(); let MediaStreamTrack::Video(rtc_track) = rtc_track else { @@ -58,11 +55,7 @@ impl FfiVideoStream { let stream = match stream_type { #[cfg(not(target_arch = "wasm32"))] proto::VideoStreamType::VideoStreamNative => { - let video_stream = Self { - handle_id, - close_tx, - stream_type, - }; + let video_stream = Self { handle_id, close_tx, stream_type }; server.async_runtime.spawn(Self::native_video_stream_task( server, handle_id, @@ -71,11 +64,7 @@ impl FfiVideoStream { )); Ok::(video_stream) } - _ => { - return Err(FfiError::InvalidRequest( - "unsupported video stream type".into(), - )) - } + _ => return Err(FfiError::InvalidRequest("unsupported video stream type".into())), }?; // Store the new video stream and return the info @@ -132,14 +121,10 @@ impl FfiVideoStream { } if let Err(err) = server - .send_event(proto::ffi_event::Message::VideoStreamEvent( - proto::VideoStreamEvent { - stream_handle, - message: Some(proto::video_stream_event::Message::Eos( - proto::VideoStreamEos {}, - )), - }, - )) + .send_event(proto::ffi_event::Message::VideoStreamEvent(proto::VideoStreamEvent { + stream_handle, + message: Some(proto::video_stream_event::Message::Eos(proto::VideoStreamEos {})), + })) .await { log::warn!("failed to send video EOS: {}", err); diff --git a/livekit-protocol/src/debouncer.rs b/livekit-protocol/src/debouncer.rs index 9359e914..eea1fe10 100644 --- a/livekit-protocol/src/debouncer.rs +++ b/livekit-protocol/src/debouncer.rs @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use futures_util::Future; use std::time::Duration; + +use futures_util::Future; use thiserror::Error; use tokio::sync::{mpsc, oneshot}; @@ -35,10 +36,7 @@ where let (tx, rx) = mpsc::unbounded_channel(); let (cancel_tx, cancel_rx) = oneshot::channel(); tokio::spawn(debounce_task(duration, future, rx, cancel_rx)); - Debouncer { - tx, - cancel_tx: Some(cancel_tx), - } + Debouncer { tx, cancel_tx: Some(cancel_tx) } } async fn debounce_task( diff --git a/livekit-protocol/src/observer.rs b/livekit-protocol/src/observer.rs index 24d925ed..a736a8b0 100644 --- a/livekit-protocol/src/observer.rs +++ b/livekit-protocol/src/observer.rs @@ -12,11 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use futures_util::sink::Sink; -use futures_util::task::{Context, Poll}; +use std::{pin::Pin, sync::Arc}; + +use futures_util::{ + sink::Sink, + task::{Context, Poll}, +}; use parking_lot::Mutex; -use std::pin::Pin; -use std::sync::Arc; use tokio::sync::mpsc; #[derive(Clone, Debug)] @@ -32,9 +34,7 @@ where T: Clone, { fn default() -> Self { - Self { - senders: Default::default(), - } + Self { senders: Default::default() } } } @@ -49,9 +49,7 @@ where } pub fn dispatch(&self, msg: &T) { - self.senders - .lock() - .retain(|sender| sender.send(msg.clone()).is_ok()); + self.senders.lock().retain(|sender| sender.send(msg.clone()).is_ok()); } pub fn clear(&self) { diff --git a/livekit/src/prelude.rs b/livekit/src/prelude.rs index 0668b9de..0e9eae6c 100644 --- a/livekit/src/prelude.rs +++ b/livekit/src/prelude.rs @@ -12,18 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub use crate::participant::{ConnectionQuality, LocalParticipant, Participant, RemoteParticipant}; - pub use crate::{ + id::*, + participant::{ConnectionQuality, LocalParticipant, Participant, RemoteParticipant}, + publication::{LocalTrackPublication, RemoteTrackPublication, TrackPublication}, + track::{ + AudioTrack, LocalAudioTrack, LocalTrack, LocalVideoTrack, RemoteAudioTrack, RemoteTrack, + RemoteVideoTrack, StreamState, Track, TrackDimension, TrackKind, TrackSource, VideoTrack, + }, ConnectionState, DataPacket, DataPacketKind, Room, RoomError, RoomEvent, RoomOptions, RoomResult, }; - -pub use crate::publication::{LocalTrackPublication, RemoteTrackPublication, TrackPublication}; - -pub use crate::track::{ - AudioTrack, LocalAudioTrack, LocalTrack, LocalVideoTrack, RemoteAudioTrack, RemoteTrack, - RemoteVideoTrack, StreamState, Track, TrackDimension, TrackKind, TrackSource, VideoTrack, -}; - -pub use crate::id::*; diff --git a/livekit/src/proto.rs b/livekit/src/proto.rs index 40b52571..260d150a 100644 --- a/livekit/src/proto.rs +++ b/livekit/src/proto.rs @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{e2ee::EncryptionType, participant, track, DataPacketKind}; use livekit_protocol::*; +use crate::{e2ee::EncryptionType, participant, track, DataPacketKind}; + // Conversions impl From for participant::ConnectionQuality { fn from(value: ConnectionQuality) -> Self { diff --git a/livekit/src/room/e2ee/manager.rs b/livekit/src/room/e2ee/manager.rs index ac2f8a30..bab97e0a 100644 --- a/livekit/src/room/e2ee/manager.rs +++ b/livekit/src/room/e2ee/manager.rs @@ -12,18 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::key_provider::KeyProvider; -use super::EncryptionType; -use crate::e2ee::E2eeOptions; -use crate::id::{ParticipantIdentity, TrackSid}; -use crate::participant::{LocalParticipant, RemoteParticipant}; -use crate::prelude::{LocalTrack, LocalTrackPublication, RemoteTrack, RemoteTrackPublication}; -use crate::rtc_engine::lk_runtime::LkRuntime; -use libwebrtc::native::frame_cryptor::{EncryptionAlgorithm, EncryptionState, FrameCryptor}; -use libwebrtc::{rtp_receiver::RtpReceiver, rtp_sender::RtpSender}; +use std::{collections::HashMap, sync::Arc}; + +use libwebrtc::{ + native::frame_cryptor::{EncryptionAlgorithm, EncryptionState, FrameCryptor}, + rtp_receiver::RtpReceiver, + rtp_sender::RtpSender, +}; use parking_lot::Mutex; -use std::collections::HashMap; -use std::sync::Arc; + +use super::{key_provider::KeyProvider, EncryptionType}; +use crate::{ + e2ee::E2eeOptions, + id::{ParticipantIdentity, TrackSid}, + participant::{LocalParticipant, RemoteParticipant}, + prelude::{LocalTrack, LocalTrackPublication, RemoteTrack, RemoteTrackPublication}, + rtc_engine::lk_runtime::LkRuntime, +}; type StateChangedHandler = Box; @@ -40,7 +45,8 @@ pub struct E2eeManager { } impl E2eeManager { - /// E2eeOptions is an optional parameter. We may support to reconfigure e2ee after connect in the future. + /// E2eeOptions is an optional parameter. We may support to reconfigure e2ee after connect in + /// the future. pub(crate) fn new(options: Option) -> Self { Self { inner: Arc::new(Mutex::new(ManagerInner { @@ -94,9 +100,7 @@ impl E2eeManager { self.setup_cryptor(&frame_cryptor); let mut inner = self.inner.lock(); - inner - .frame_cryptors - .insert((identity, publication.sid()), frame_cryptor.clone()); + inner.frame_cryptors.insert((identity, publication.sid()), frame_cryptor.clone()); } /// Called by the room @@ -120,16 +124,14 @@ impl E2eeManager { self.setup_cryptor(&frame_cryptor); let mut inner = self.inner.lock(); - inner - .frame_cryptors - .insert((identity, publication.sid()), frame_cryptor.clone()); + inner.frame_cryptors.insert((identity, publication.sid()), frame_cryptor.clone()); } fn setup_cryptor(&self, frame_cryptor: &FrameCryptor) { let state_changed = self.state_changed.clone(); frame_cryptor.on_state_change(Some(Box::new(move |participant_identity, state| { if let Some(state_changed) = state_changed.lock().as_ref() { - state_changed(participant_identity.try_into().unwrap(), state); + state_changed(participant_identity.into(), state); } }))); } @@ -179,11 +181,7 @@ impl E2eeManager { pub fn encryption_type(&self) -> EncryptionType { let inner = self.inner.lock(); - inner - .options - .as_ref() - .map(|opts| opts.encryption_type) - .unwrap_or(EncryptionType::None) + inner.options.as_ref().map(|opts| opts.encryption_type).unwrap_or(EncryptionType::None) } fn setup_rtp_sender( @@ -228,8 +226,6 @@ impl E2eeManager { log::debug!("removing frame cryptor for {}", participant_identity); let mut inner = self.inner.lock(); - inner - .frame_cryptors - .remove(&(participant_identity, track_sid)); + inner.frame_cryptors.remove(&(participant_identity, track_sid)); } } diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index 28ed2e8c..22fd985a 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -12,34 +12,39 @@ // See the License for the specific language governing permissions and // limitations under the License. -use self::e2ee::manager::E2eeManager; -use self::e2ee::E2eeOptions; -use crate::participant::ConnectionQuality; -use crate::prelude::*; -use crate::rtc_engine::{EngineError, EngineOptions, SessionStats}; -use crate::rtc_engine::{EngineEvent, EngineEvents, EngineResult, RtcEngine}; -use libwebrtc::native::frame_cryptor::EncryptionState; -use libwebrtc::prelude::{ - ContinualGatheringPolicy, IceTransportsType, MediaStream, MediaStreamTrack, RtcConfiguration, +use std::{collections::HashMap, fmt::Debug, sync::Arc, time::Duration}; + +use libwebrtc::{ + native::frame_cryptor::EncryptionState, + prelude::{ + ContinualGatheringPolicy, IceTransportsType, MediaStream, MediaStreamTrack, + RtcConfiguration, + }, + rtp_transceiver::RtpTransceiver, + RtcError, }; -use libwebrtc::rtp_transceiver::RtpTransceiver; -use libwebrtc::RtcError; use livekit_api::signal_client::SignalOptions; use livekit_protocol as proto; use livekit_protocol::observer::Dispatcher; use parking_lot::RwLock; +pub use proto::DisconnectReason; use proto::SignalTarget; -use std::collections::HashMap; -use std::fmt::Debug; -use std::sync::Arc; -use std::time::Duration; use thiserror::Error; -use tokio::sync::Mutex as AsyncMutex; -use tokio::sync::{mpsc, oneshot}; -use tokio::task::JoinHandle; +use tokio::{ + sync::{mpsc, oneshot, Mutex as AsyncMutex}, + task::JoinHandle, +}; +use self::e2ee::{manager::E2eeManager, E2eeOptions}; pub use crate::rtc_engine::SimulateScenario; -pub use proto::DisconnectReason; +use crate::{ + participant::ConnectionQuality, + prelude::*, + rtc_engine::{ + EngineError, EngineEvent, EngineEvents, EngineOptions, EngineResult, RtcEngine, + SessionStats, + }, +}; pub mod e2ee; pub mod id; @@ -143,7 +148,8 @@ pub enum RoomEvent { ConnectionStateChanged(ConnectionState), Connected { /// Initial participants & their tracks prior to joining the room - /// We're not returning this directly inside Room::connect because it is unlikely to be used + /// We're not returning this directly inside Room::connect because it is unlikely to be + /// used participants_with_tracks: Vec<(RemoteParticipant, Vec)>, }, Disconnected { @@ -205,7 +211,8 @@ impl Default for RoomOptions { // Explicitly set the default values rtc_config: RtcConfiguration { - ice_servers: vec![], // When empty, this will automatically be filled by the JoinResponse + ice_servers: vec![], /* When empty, this will automatically be filled by the + * JoinResponse */ continual_gathering_policy: ContinualGatheringPolicy::GatherContinually, ice_transport_type: IceTransportsType::All, }, @@ -304,10 +311,7 @@ impl Room { local_participant.on_track_muted({ let dispatcher = dispatcher.clone(); move |participant, publication| { - let event = RoomEvent::TrackMuted { - participant, - publication, - }; + let event = RoomEvent::TrackMuted { participant, publication }; dispatcher.dispatch(&event); } }); @@ -315,10 +319,7 @@ impl Room { local_participant.on_track_unmuted({ let dispatcher = dispatcher.clone(); move |participant, publication| { - let event = RoomEvent::TrackUnmuted { - participant, - publication, - }; + let event = RoomEvent::TrackUnmuted { participant, publication }; dispatcher.dispatch(&event); } }); @@ -326,11 +327,8 @@ impl Room { local_participant.on_metadata_changed({ let dispatcher = dispatcher.clone(); move |participant, old_metadata, metadata| { - let event = RoomEvent::ParticipantMetadataChanged { - participant, - old_metadata, - metadata, - }; + let event = + RoomEvent::ParticipantMetadataChanged { participant, old_metadata, metadata }; dispatcher.dispatch(&event); } }); @@ -338,11 +336,7 @@ impl Room { local_participant.on_name_changed({ let dispatcher = dispatcher.clone(); move |participant, old_name, name| { - let event = RoomEvent::ParticipantNameChanged { - participant, - old_name, - name, - }; + let event = RoomEvent::ParticipantNameChanged { participant, old_name, name }; dispatcher.dispatch(&event); } }); @@ -370,11 +364,7 @@ impl Room { move |participant_identity, state| { // Forward e2ee events to the room // (Ignore if the participant is not in the room anymore) - log::info!( - "e2ee state changed for {}: {:?}", - participant_identity, - state - ); + log::info!("e2ee state changed for {}: {:?}", participant_identity, state); let participant = if participant_identity.as_str() == inner.local_participant.identity().as_str() @@ -407,8 +397,8 @@ impl Room { } // Get the initial states (Can be useful on some usecases, like the FfiServer) - // Getting them here ensure nothing happening before (Like a new participant joining) because the room task - // is not started yet + // Getting them here ensure nothing happening before (Like a new participant joining) + // because the room task is not started yet let participants = inner.participants.read().0.clone(); let participants_with_tracks = participants .into_values() @@ -416,9 +406,7 @@ impl Room { .collect(); let events = inner.dispatcher.register(); - inner.dispatcher.dispatch(&RoomEvent::Connected { - participants_with_tracks, - }); + inner.dispatcher.dispatch(&RoomEvent::Connected { participants_with_tracks }); inner.update_connection_state(ConnectionState::Connected); let (close_emitter, close_receiver) = oneshot::channel(); @@ -427,10 +415,7 @@ impl Room { Ok(( Self { inner, - handle: AsyncMutex::new(Some(RoomHandle { - session_task, - close_emitter, - })), + handle: AsyncMutex::new(Some(RoomHandle { session_task, close_emitter })), }, events, )) @@ -561,30 +546,22 @@ impl RoomSession { async fn on_engine_event(self: &Arc, event: EngineEvent) -> RoomResult<()> { match event { EngineEvent::ParticipantUpdate { updates } => self.handle_participant_update(updates), - EngineEvent::MediaTrack { - track, - stream, - transceiver, - } => self.handle_media_track(track, stream, transceiver), + EngineEvent::MediaTrack { track, stream, transceiver } => { + self.handle_media_track(track, stream, transceiver) + } EngineEvent::RoomUpdate { room } => self.handle_room_update(room), EngineEvent::Resuming(tx) => self.handle_resuming(tx), EngineEvent::Resumed(tx) => self.handle_resumed(tx), - EngineEvent::SignalResumed { - reconnect_response, - tx, - } => self.handle_signal_resumed(reconnect_response, tx), + EngineEvent::SignalResumed { reconnect_response, tx } => { + self.handle_signal_resumed(reconnect_response, tx) + } EngineEvent::Restarting(tx) => self.handle_restarting(tx), EngineEvent::Restarted(tx) => self.handle_restarted(tx), EngineEvent::SignalRestarted { join_response, tx } => { self.handle_signal_restarted(join_response, tx) } EngineEvent::Disconnected { reason } => self.handle_disconnected(reason), - EngineEvent::Data { - payload, - topic, - kind, - participant_sid, - } => { + EngineEvent::Data { payload, topic, kind, participant_sid } => { self.handle_data(payload, topic, kind, participant_sid); } EngineEvent::SpeakersChanged { speakers } => self.handle_speakers_changed(speakers), @@ -611,8 +588,7 @@ impl RoomSession { } info.state = state; - self.dispatcher - .dispatch(&RoomEvent::ConnectionStateChanged(state)); + self.dispatcher.dispatch(&RoomEvent::ConnectionStateChanged(state)); true } @@ -638,18 +614,17 @@ impl RoomSession { { if remote_participant.sid() != participant_sid { // Same identity but different sid, disconnect, remove the old participant - self.clone() - .handle_participant_disconnect(remote_participant); + self.clone().handle_participant_disconnect(remote_participant); } } let remote_participant = self.get_participant_by_sid(&participant_sid); if pi.state == proto::participant_info::State::Disconnected as i32 { if let Some(remote_participant) = remote_participant { - self.clone() - .handle_participant_disconnect(remote_participant) + self.clone().handle_participant_disconnect(remote_participant) } else { - // Ignore, just received the ParticipantInfo but the participant is already disconnected + // Ignore, just received the ParticipantInfo but the participant is already + // disconnected } } else if let Some(remote_participant) = remote_participant { remote_participant.update_info(pi.clone()); @@ -694,16 +669,12 @@ impl RoomSession { if let Some(remote_participant) = remote_participant { tokio::spawn(async move { - remote_participant - .add_subscribed_media_track(track_sid, track, transceiver) - .await; + remote_participant.add_subscribed_media_track(track_sid, track, transceiver).await; }); } else { - // The server should send participant updates before sending a new offer, this should happen - log::error!( - "received track from an unknown participant: {:?}", - participant_sid - ); + // The server should send participant updates before sending a new offer, this should + // happen + log::error!("received track from an unknown participant: {:?}", participant_sid); } } @@ -735,8 +706,7 @@ impl RoomSession { speakers.sort_by(|a, b| a.audio_level().partial_cmp(&b.audio_level()).unwrap()); *self.active_speakers.write() = speakers.clone(); - self.dispatcher - .dispatch(&RoomEvent::ActiveSpeakersChanged { speakers }); + self.dispatcher.dispatch(&RoomEvent::ActiveSpeakersChanged { speakers }); } /// Handle a connection quality update @@ -756,11 +726,7 @@ impl RoomSession { }; participant.set_connection_quality(quality); - self.dispatcher - .dispatch(&RoomEvent::ConnectionQualityChanged { - participant, - quality, - }); + self.dispatcher.dispatch(&RoomEvent::ConnectionQualityChanged { participant, quality }); } } @@ -768,12 +734,7 @@ impl RoomSession { let auto_subscribe = self.options.auto_subscribe; let session = self.rtc_engine.session(); - if session - .subscriber() - .peer_connection() - .current_local_description() - .is_none() - { + if session.subscriber().peer_connection().current_local_description().is_none() { log::warn!("skipping sendSyncState, no subscriber answer"); return; } @@ -787,26 +748,16 @@ impl RoomSession { } } - let answer = session - .subscriber() - .peer_connection() - .current_local_description() - .unwrap(); + let answer = session.subscriber().peer_connection().current_local_description().unwrap(); - let offer = session - .subscriber() - .peer_connection() - .current_remote_description() - .unwrap(); + let offer = session.subscriber().peer_connection().current_remote_description().unwrap(); let mut dcs = Vec::with_capacity(4); if session.has_published() { - let lossy_dc = session - .data_channel(SignalTarget::Publisher, DataPacketKind::Lossy) - .unwrap(); - let reliable_dc = session - .data_channel(SignalTarget::Publisher, DataPacketKind::Reliable) - .unwrap(); + let lossy_dc = + session.data_channel(SignalTarget::Publisher, DataPacketKind::Lossy).unwrap(); + let reliable_dc = + session.data_channel(SignalTarget::Publisher, DataPacketKind::Reliable).unwrap(); dcs.push(proto::DataChannelInfo { label: lossy_dc.label(), @@ -860,9 +811,7 @@ impl RoomSession { }; log::info!("sending sync state {:?}", sync_state); - self.rtc_engine - .send_request(proto::signal_request::Message::SyncState(sync_state)) - .await; + self.rtc_engine.send_request(proto::signal_request::Message::SyncState(sync_state)).await; } fn handle_room_update(self: &Arc, room: proto::Room) { @@ -901,7 +850,8 @@ impl RoomSession { async move { session.send_sync_state().await; - // Always send the sync state before continuing the reconnection (e.g: publisher offer) + // Always send the sync state before continuing the reconnection (e.g: publisher + // offer) let _ = tx.send(()); } }); @@ -911,8 +861,7 @@ impl RoomSession { // Remove existing participants/subscriptions on full reconnect let participants = self.participants.read().0.clone(); for (_, participant) in participants.iter() { - self.clone() - .handle_participant_disconnect(participant.clone()); + self.clone().handle_participant_disconnect(participant.clone()); } if self.update_connection_state(ConnectionState::Reconnecting) { @@ -941,14 +890,14 @@ impl RoomSession { let lp = session.local_participant.clone(); let republish = async move { - // Only "really" used to send LocalTrackUnpublished event (Since we don't really need - // to remove the RtpSender since we know we are using a new RtcSession, + // Only "really" used to send LocalTrackUnpublished event (Since we don't + // really need to remove the RtpSender since we know + // we are using a new RtcSession, // so new PeerConnetions) let _ = lp.unpublish_track(&publication.sid()).await; - if let Err(err) = lp - .publish_track(track.clone(), publication.publish_options()) - .await + if let Err(err) = + lp.publish_track(track.clone(), publication.publish_options()).await { log::error!( "failed to republish track {} after rtc_engine restarted: {}", @@ -975,8 +924,7 @@ impl RoomSession { join_response: proto::JoinResponse, tx: oneshot::Sender<()>, ) { - self.local_participant - .update_info(join_response.participant.unwrap()); // The sid may have changed + self.local_participant.update_info(join_response.participant.unwrap()); // The sid may have changed self.handle_participant_update(join_response.other_participants); self.handle_room_update(join_response.room.unwrap()); @@ -987,8 +935,7 @@ impl RoomSession { fn handle_disconnected(&self, reason: DisconnectReason) { log::info!("disconnected from room: {:?}", reason); if self.update_connection_state(ConnectionState::Disconnected) { - self.dispatcher - .dispatch(&RoomEvent::Disconnected { reason }); + self.dispatcher.dispatch(&RoomEvent::Disconnected { reason }); } } @@ -999,10 +946,8 @@ impl RoomSession { kind: DataPacketKind, participant_sid: Option, ) { - let participant = participant_sid - .as_ref() - .map(|sid| self.get_participant_by_sid(sid)) - .unwrap_or(None); + let participant = + participant_sid.as_ref().map(|sid| self.get_participant_by_sid(sid)).unwrap_or(None); if participant.is_none() && participant_sid.is_some() { // We received a data packet from a participant that is not in the participants list @@ -1038,20 +983,14 @@ impl RoomSession { participant.on_track_published({ let dispatcher = self.dispatcher.clone(); move |participant, publication| { - dispatcher.dispatch(&RoomEvent::TrackPublished { - participant, - publication, - }); + dispatcher.dispatch(&RoomEvent::TrackPublished { participant, publication }); } }); participant.on_track_unpublished({ let dispatcher = self.dispatcher.clone(); move |participant, publication| { - dispatcher.dispatch(&RoomEvent::TrackUnpublished { - participant, - publication, - }); + dispatcher.dispatch(&RoomEvent::TrackUnpublished { participant, publication }); } }); @@ -1099,10 +1038,7 @@ impl RoomSession { participant.on_track_muted({ let dispatcher = self.dispatcher.clone(); move |participant, publication| { - let event = RoomEvent::TrackMuted { - participant, - publication, - }; + let event = RoomEvent::TrackMuted { participant, publication }; dispatcher.dispatch(&event); } }); @@ -1110,10 +1046,7 @@ impl RoomSession { participant.on_track_unmuted({ let dispatcher = self.dispatcher.clone(); move |participant, publication| { - let event = RoomEvent::TrackUnmuted { - participant, - publication, - }; + let event = RoomEvent::TrackUnmuted { participant, publication }; dispatcher.dispatch(&event); } }); @@ -1121,11 +1054,8 @@ impl RoomSession { participant.on_metadata_changed({ let dispatcher = self.dispatcher.clone(); move |participant, old_metadata, metadata| { - let event = RoomEvent::ParticipantMetadataChanged { - participant, - old_metadata, - metadata, - }; + let event = + RoomEvent::ParticipantMetadataChanged { participant, old_metadata, metadata }; dispatcher.dispatch(&event); } }); @@ -1133,11 +1063,7 @@ impl RoomSession { participant.on_name_changed({ let dispatcher = self.dispatcher.clone(); move |participant, old_name, name| { - let event = RoomEvent::ParticipantNameChanged { - participant, - old_name, - name, - }; + let event = RoomEvent::ParticipantNameChanged { participant, old_name, name }; dispatcher.dispatch(&event); } }); @@ -1151,10 +1077,7 @@ impl RoomSession { /// A participant has disconnected /// Cleanup the participant and emit an event fn handle_participant_disconnect(self: Arc, remote_participant: RemoteParticipant) { - log::info!( - "handle_participant_disconnect: {}", - remote_participant.sid() - ); + log::info!("handle_participant_disconnect: {}", remote_participant.sid()); for (sid, _) in remote_participant.tracks() { remote_participant.unpublish_track(&sid); } @@ -1162,8 +1085,7 @@ impl RoomSession { let mut participants = self.participants.write(); participants.0.remove(&remote_participant.sid()); participants.1.remove(&remote_participant.identity()); - self.dispatcher - .dispatch(&RoomEvent::ParticipantDisconnected(remote_participant)); + self.dispatcher.dispatch(&RoomEvent::ParticipantDisconnected(remote_participant)); } fn get_participant_by_sid(&self, sid: &ParticipantSid) -> Option { diff --git a/livekit/src/room/options.rs b/livekit/src/room/options.rs index a3475575..168f56a5 100644 --- a/livekit/src/room/options.rs +++ b/livekit/src/room/options.rs @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::prelude::*; use libwebrtc::prelude::*; use livekit_protocol as proto; +use crate::prelude::*; + #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum VideoCodec { VP8, @@ -68,9 +69,7 @@ pub struct AudioPreset { impl AudioPreset { pub const fn new(max_bitrate: u64) -> Self { - Self { - encoding: AudioEncoding { max_bitrate }, - } + Self { encoding: AudioEncoding { max_bitrate } } } } @@ -103,14 +102,7 @@ impl Default for TrackPublishOptions { impl VideoPreset { pub const fn new(width: u32, height: u32, max_bitrate: u64, max_framerate: f64) -> Self { - Self { - width, - height, - encoding: VideoEncoding { - max_bitrate, - max_framerate, - }, - } + Self { width, height, encoding: VideoEncoding { max_bitrate, max_framerate } } } pub fn resolution(&self) -> VideoResolution { @@ -316,14 +308,8 @@ pub mod audio { pub const MUSIC_HIGH_QUALITY: AudioPreset = AudioPreset::new(64_000); pub const MUSIC_HIGH_QUALITY_STEREO: AudioPreset = AudioPreset::new(96_000); - pub const PRESETS: &[AudioPreset] = &[ - TELEPHONE, - SPEECH, - MUSIC, - MUSIC_STEREO, - MUSIC_HIGH_QUALITY, - MUSIC_HIGH_QUALITY_STEREO, - ]; + pub const PRESETS: &[AudioPreset] = + &[TELEPHONE, SPEECH, MUSIC, MUSIC_STEREO, MUSIC_HIGH_QUALITY, MUSIC_HIGH_QUALITY_STEREO]; } pub mod video { diff --git a/livekit/src/room/participant/local_participant.rs b/livekit/src/room/participant/local_participant.rs index db47e209..0b7bbab5 100644 --- a/livekit/src/room/participant/local_participant.rs +++ b/livekit/src/room/participant/local_participant.rs @@ -12,23 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::ConnectionQuality; -use super::ParticipantInner; -use crate::e2ee::EncryptionType; -use crate::options; -use crate::options::compute_video_encodings; -use crate::options::video_layers_from_encodings; -use crate::options::TrackPublishOptions; -use crate::prelude::*; -use crate::rtc_engine::RtcEngine; -use crate::DataPacket; -use crate::DataPacketKind; +use std::{collections::HashMap, fmt::Debug, sync::Arc}; + use libwebrtc::rtp_parameters::RtpEncodingParameters; use livekit_protocol as proto; use parking_lot::Mutex; -use std::collections::HashMap; -use std::fmt::Debug; -use std::sync::Arc; + +use super::{ConnectionQuality, ParticipantInner}; +use crate::{ + e2ee::EncryptionType, + options, + options::{compute_video_encodings, video_layers_from_encodings, TrackPublishOptions}, + prelude::*, + rtc_engine::RtcEngine, + DataPacket, +}; type LocalTrackPublishedHandler = Box; type LocalTrackUnpublishedHandler = Box; @@ -71,10 +69,7 @@ impl LocalParticipant { ) -> Self { Self { inner: super::new_inner(rtc_engine, sid, identity, name, metadata), - local: Arc::new(LocalInfo { - events: LocalEvents::default(), - encryption_type, - }), + local: Arc::new(LocalInfo { events: LocalEvents::default(), encryption_type }), } } @@ -195,10 +190,8 @@ impl LocalParticipant { } LocalTrack::Audio(_audio_track) => { // Setup audio encoding - let audio_encoding = options - .audio_encoding - .as_ref() - .unwrap_or(&options::audio::SPEECH.encoding); + let audio_encoding = + options.audio_encoding.as_ref().unwrap_or(&options::audio::SPEECH.encoding); encodings.push(RtpEncodingParameters { max_bitrate: Some(audio_encoding.max_bitrate), @@ -210,11 +203,8 @@ impl LocalParticipant { let publication = LocalTrackPublication::new(track_info.clone(), track.clone()); track.update_info(track_info); // Update sid + source - let transceiver = self - .inner - .rtc_engine - .create_sender(track.clone(), options.clone(), encodings) - .await?; + let transceiver = + self.inner.rtc_engine.create_sender(track.clone(), options.clone(), encodings).await?; track.set_transceiver(Some(transceiver)); @@ -236,10 +226,7 @@ impl LocalParticipant { self.inner .rtc_engine .send_request(proto::signal_request::Message::UpdateMetadata( - proto::UpdateParticipantMetadata { - metadata, - name: self.name(), - }, + proto::UpdateParticipantMetadata { metadata, name: self.name() }, )) .await; Ok(()) @@ -249,10 +236,7 @@ impl LocalParticipant { self.inner .rtc_engine .send_request(proto::signal_request::Message::UpdateMetadata( - proto::UpdateParticipantMetadata { - metadata: self.metadata(), - name, - }, + proto::UpdateParticipantMetadata { metadata: self.metadata(), name }, )) .await; Ok(()) @@ -288,24 +272,16 @@ impl LocalParticipant { pub async fn publish_data(&self, packet: DataPacket) -> RoomResult<()> { let data = proto::DataPacket { - kind: DataPacketKind::from(packet.kind) as i32, + kind: packet.kind as i32, value: Some(proto::data_packet::Value::User(proto::UserPacket { payload: packet.payload, topic: packet.topic, - destination_sids: packet - .destination_sids - .into_iter() - .map(Into::into) - .collect(), + destination_sids: packet.destination_sids.into_iter().map(Into::into).collect(), ..Default::default() })), }; - self.inner - .rtc_engine - .publish_data(&data, packet.kind) - .await - .map_err(Into::into) + self.inner.rtc_engine.publish_data(&data, packet.kind).await.map_err(Into::into) } pub fn get_track_publication(&self, sid: &TrackSid) -> Option { diff --git a/livekit/src/room/participant/mod.rs b/livekit/src/room/participant/mod.rs index 86f89399..b3daa07a 100644 --- a/livekit/src/room/participant/mod.rs +++ b/livekit/src/room/participant/mod.rs @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::prelude::*; -use crate::rtc_engine::RtcEngine; +use std::{collections::HashMap, fmt::Debug, sync::Arc}; + use livekit_protocol as proto; use livekit_protocol::enum_dispatch; use parking_lot::{Mutex, RwLock}; -use std::collections::HashMap; -use std::fmt::Debug; -use std::sync::Arc; + +use crate::{prelude::*, rtc_engine::RtcEngine}; mod local_participant; mod remote_participant; diff --git a/livekit/src/room/participant/remote_participant.rs b/livekit/src/room/participant/remote_participant.rs index 76f9e6c1..03e480e1 100644 --- a/livekit/src/room/participant/remote_participant.rs +++ b/livekit/src/room/participant/remote_participant.rs @@ -12,20 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::TrackKind; -use super::{ConnectionQuality, ParticipantInner}; -use crate::prelude::*; -use crate::rtc_engine::RtcEngine; -use crate::track::TrackError; +use std::{ + collections::{HashMap, HashSet}, + fmt::Debug, + sync::Arc, + time::Duration, +}; + use libwebrtc::prelude::*; use livekit_protocol as proto; use parking_lot::Mutex; -use std::collections::{HashMap, HashSet}; -use std::fmt::Debug; -use std::sync::Arc; -use std::time::Duration; use tokio::time::timeout; +use super::{ConnectionQuality, ParticipantInner, TrackKind}; +use crate::{prelude::*, rtc_engine::RtcEngine, track::TrackError}; + const ADD_TRACK_TIMEOUT: Duration = Duration::from_secs(5); type TrackPublishedHandler = Box; @@ -77,10 +78,7 @@ impl RemoteParticipant { ) -> Self { Self { inner: super::new_inner(rtc_engine, sid, identity, name, metadata), - remote: Arc::new(RemoteInfo { - events: Default::default(), - auto_subscribe, - }), + remote: Arc::new(RemoteInfo { events: Default::default(), auto_subscribe }), } } @@ -151,7 +149,8 @@ impl RemoteParticipant { self.add_publication(TrackPublication::Remote(remote_publication.clone())); track.enable(); - remote_publication.set_track(Some(track)); // This will fire TrackSubscribed on the publication + remote_publication.set_track(Some(track)); // This will fire TrackSubscribed on the + // publication } else { log::error!("could not find published track with sid: {:?}", sid); @@ -184,11 +183,7 @@ impl RemoteParticipant { } pub(crate) fn update_info(&self, info: proto::ParticipantInfo) { - super::update_info( - &self.inner, - &Participant::Remote(self.clone()), - info.clone(), - ); + super::update_info(&self.inner, &Participant::Remote(self.clone()), info.clone()); let mut valid_tracks = HashSet::::new(); for track in info.tracks { diff --git a/livekit/src/room/publication/local.rs b/livekit/src/room/publication/local.rs index 79aabe96..fddbad62 100644 --- a/livekit/src/room/publication/local.rs +++ b/livekit/src/room/publication/local.rs @@ -12,15 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::TrackPublicationInner; -use crate::e2ee::EncryptionType; -use crate::options::TrackPublishOptions; -use crate::prelude::*; +use std::{fmt::Debug, sync::Arc}; use livekit_protocol as proto; use parking_lot::Mutex; -use std::fmt::Debug; -use std::sync::Arc; + +use super::TrackPublicationInner; +use crate::{e2ee::EncryptionType, options::TrackPublishOptions, prelude::*}; #[derive(Default)] struct LocalInfo { @@ -117,12 +115,7 @@ impl LocalTrackPublication { } pub fn track(&self) -> Option { - self.inner - .info - .read() - .track - .clone() - .map(|track| track.try_into().unwrap()) + self.inner.info.read().track.clone().map(|track| track.try_into().unwrap()) } pub fn mime_type(&self) -> String { diff --git a/livekit/src/room/publication/mod.rs b/livekit/src/room/publication/mod.rs index 428489d7..c4db8c59 100644 --- a/livekit/src/room/publication/mod.rs +++ b/livekit/src/room/publication/mod.rs @@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::track::TrackDimension; -use crate::track::Track; -use crate::{e2ee::EncryptionType, prelude::*}; +use std::sync::Arc; + use livekit_protocol as proto; use livekit_protocol::enum_dispatch; use parking_lot::{Mutex, RwLock}; -use std::sync::Arc; + +use super::track::TrackDimension; +use crate::{e2ee::EncryptionType, prelude::*, track::Track}; mod local; mod remote; @@ -116,7 +117,7 @@ pub(super) fn new_inner( let info = PublicationInfo { track, proto_info: info.clone(), - source: info.source().try_into().unwrap(), + source: info.source().into(), kind: info.r#type().try_into().unwrap(), encryption_type: info.encryption().into(), name: info.name, @@ -127,10 +128,7 @@ pub(super) fn new_inner( muted: info.muted, }; - Arc::new(TrackPublicationInner { - info: RwLock::new(info), - events: Default::default(), - }) + Arc::new(TrackPublicationInner { info: RwLock::new(info), events: Default::default() }) } pub(super) fn update_info( diff --git a/livekit/src/room/publication/remote.rs b/livekit/src/room/publication/remote.rs index 134da5f1..89b563b3 100644 --- a/livekit/src/room/publication/remote.rs +++ b/livekit/src/room/publication/remote.rs @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::{PermissionStatus, SubscriptionStatus, TrackPublication, TrackPublicationInner}; -use crate::e2ee::EncryptionType; -use crate::prelude::*; +use std::{fmt::Debug, sync::Arc}; + use livekit_protocol as proto; use parking_lot::{Mutex, RwLock}; -use std::fmt::Debug; -use std::sync::Arc; + +use super::{PermissionStatus, SubscriptionStatus, TrackPublication, TrackPublicationInner}; +use crate::{e2ee::EncryptionType, prelude::*}; type SubscribedHandler = Box; type UnsubscribedHandler = Box; @@ -72,10 +72,7 @@ impl RemoteTrackPublication { Self { inner: super::new_inner(info, track.map(Into::into)), remote: Arc::new(RemoteInner { - info: RwLock::new(RemoteInfo { - subscribed: auto_subscribe, - allowed: true, - }), + info: RwLock::new(RemoteInfo { subscribed: auto_subscribe, allowed: true }), events: Default::default(), }), } @@ -114,12 +111,8 @@ impl RemoteTrackPublication { pub(crate) fn emit_subscription_update(&self, old_subscription_state: SubscriptionStatus) { if old_subscription_state != self.subscription_status() { - if let Some(subscription_status_changed) = self - .remote - .events - .subscription_status_changed - .lock() - .as_ref() + if let Some(subscription_status_changed) = + self.remote.events.subscription_status_changed.lock().as_ref() { subscription_status_changed( self.clone(), @@ -150,11 +143,7 @@ impl RemoteTrackPublication { } pub(crate) fn update_info(&self, new_info: proto::TrackInfo) { - super::update_info( - &self.inner, - &TrackPublication::Remote(self.clone()), - new_info.clone(), - ); + super::update_info(&self.inner, &TrackPublication::Remote(self.clone()), new_info.clone()); let mut info = self.inner.info.write(); let muted = info.muted; @@ -234,12 +223,8 @@ impl RemoteTrackPublication { self.set_track(None); // Request to send an update to the SFU - if let Some(subscription_update_needed) = self - .remote - .events - .subscription_update_needed - .lock() - .as_ref() + if let Some(subscription_update_needed) = + self.remote.events.subscription_update_needed.lock().as_ref() { subscription_update_needed(self.clone(), subscribed); } @@ -305,12 +290,7 @@ impl RemoteTrackPublication { } pub fn track(&self) -> Option { - self.inner - .info - .read() - .track - .clone() - .map(|track| track.try_into().unwrap()) + self.inner.info.read().track.clone().map(|track| track.try_into().unwrap()) } pub fn mime_type(&self) -> String { diff --git a/livekit/src/room/track/audio_track.rs b/livekit/src/room/track/audio_track.rs index add58a4a..a864490c 100644 --- a/livekit/src/room/track/audio_track.rs +++ b/livekit/src/room/track/audio_track.rs @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::track_dispatch; -use crate::prelude::*; use libwebrtc::prelude::*; use livekit_protocol as proto; use livekit_protocol::enum_dispatch; +use super::track_dispatch; +use crate::prelude::*; + #[derive(Clone, Debug)] pub enum AudioTrack { Local(LocalAudioTrack), diff --git a/livekit/src/room/track/local_audio_track.rs b/livekit/src/room/track/local_audio_track.rs index d37f538c..e9432871 100644 --- a/livekit/src/room/track/local_audio_track.rs +++ b/livekit/src/room/track/local_audio_track.rs @@ -12,15 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::TrackInner; -use crate::prelude::*; -use crate::rtc_engine::lk_runtime::LkRuntime; use core::panic; -use libwebrtc::prelude::*; -use libwebrtc::stats::RtcStats; +use std::{fmt::Debug, sync::Arc}; + +use libwebrtc::{prelude::*, stats::RtcStats}; use livekit_protocol as proto; -use std::fmt::Debug; -use std::sync::Arc; + +use super::TrackInner; +use crate::{prelude::*, rtc_engine::lk_runtime::LkRuntime}; #[derive(Clone)] pub struct LocalAudioTrack { diff --git a/livekit/src/room/track/local_track.rs b/livekit/src/room/track/local_track.rs index 79c85d30..c154bca5 100644 --- a/livekit/src/room/track/local_track.rs +++ b/livekit/src/room/track/local_track.rs @@ -14,13 +14,13 @@ use std::sync::Arc; -use super::{track_dispatch, TrackInner}; -use crate::prelude::*; -use libwebrtc::prelude::*; -use libwebrtc::stats::RtcStats; +use libwebrtc::{prelude::*, stats::RtcStats}; use livekit_protocol as proto; use livekit_protocol::enum_dispatch; +use super::{track_dispatch, TrackInner}; +use crate::prelude::*; + #[derive(Clone, Debug)] pub enum LocalTrack { Audio(LocalAudioTrack), diff --git a/livekit/src/room/track/local_video_track.rs b/livekit/src/room/track/local_video_track.rs index 9202cde0..8b23cc08 100644 --- a/livekit/src/room/track/local_video_track.rs +++ b/livekit/src/room/track/local_video_track.rs @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::TrackInner; -use crate::prelude::*; -use crate::rtc_engine::lk_runtime::LkRuntime; -use libwebrtc::prelude::*; -use libwebrtc::stats::RtcStats; +use std::{fmt::Debug, sync::Arc}; + +use libwebrtc::{prelude::*, stats::RtcStats}; use livekit_protocol as proto; -use std::fmt::Debug; -use std::sync::Arc; + +use super::TrackInner; +use crate::{prelude::*, rtc_engine::lk_runtime::LkRuntime}; #[derive(Clone)] pub struct LocalVideoTrack { diff --git a/livekit/src/room/track/mod.rs b/livekit/src/room/track/mod.rs index 7954b7d3..00c0de7e 100644 --- a/livekit/src/room/track/mod.rs +++ b/livekit/src/room/track/mod.rs @@ -12,16 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::prelude::*; -use libwebrtc::prelude::*; -use libwebrtc::stats::RtcStats; +use std::{fmt::Debug, sync::Arc}; + +use libwebrtc::{prelude::*, stats::RtcStats}; use livekit_protocol as proto; use livekit_protocol::enum_dispatch; use parking_lot::{Mutex, RwLock}; -use std::fmt::Debug; -use std::sync::Arc; use thiserror::Error; +use crate::prelude::*; + mod audio_track; mod local_audio_track; mod local_track; diff --git a/livekit/src/room/track/remote_audio_track.rs b/livekit/src/room/track/remote_audio_track.rs index 9a5e4965..f6591a44 100644 --- a/livekit/src/room/track/remote_audio_track.rs +++ b/livekit/src/room/track/remote_audio_track.rs @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::{fmt::Debug, sync::Arc}; + +use libwebrtc::{prelude::*, stats::RtcStats}; +use livekit_protocol as proto; + use super::{remote_track, TrackInner}; use crate::prelude::*; -use libwebrtc::prelude::*; -use libwebrtc::stats::RtcStats; -use livekit_protocol as proto; -use std::fmt::Debug; -use std::sync::Arc; #[derive(Clone)] pub struct RemoteAudioTrack { diff --git a/livekit/src/room/track/remote_track.rs b/livekit/src/room/track/remote_track.rs index 75fd877e..f99737f7 100644 --- a/livekit/src/room/track/remote_track.rs +++ b/livekit/src/room/track/remote_track.rs @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::track_dispatch; -use super::TrackInner; -use crate::prelude::*; -use libwebrtc::prelude::*; -use libwebrtc::stats::RtcStats; +use std::sync::Arc; + +use libwebrtc::{prelude::*, stats::RtcStats}; use livekit_protocol as proto; use livekit_protocol::enum_dispatch; -use std::sync::Arc; + +use super::{track_dispatch, TrackInner}; +use crate::prelude::*; #[derive(Clone, Debug)] pub enum RemoteTrack { diff --git a/livekit/src/room/track/remote_video_track.rs b/livekit/src/room/track/remote_video_track.rs index f051ade4..17d655e7 100644 --- a/livekit/src/room/track/remote_video_track.rs +++ b/livekit/src/room/track/remote_video_track.rs @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::remote_track; -use super::TrackInner; -use crate::prelude::*; -use libwebrtc::prelude::*; -use libwebrtc::stats::RtcStats; +use std::{fmt::Debug, sync::Arc}; + +use libwebrtc::{prelude::*, stats::RtcStats}; use livekit_protocol as proto; -use std::fmt::Debug; -use std::sync::Arc; + +use super::{remote_track, TrackInner}; +use crate::prelude::*; #[derive(Clone)] pub struct RemoteVideoTrack { diff --git a/livekit/src/room/track/video_track.rs b/livekit/src/room/track/video_track.rs index 2b650a8b..edd3e517 100644 --- a/livekit/src/room/track/video_track.rs +++ b/livekit/src/room/track/video_track.rs @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::track_dispatch; -use crate::prelude::*; use libwebrtc::prelude::*; use livekit_protocol as proto; use livekit_protocol::enum_dispatch; +use super::track_dispatch; +use crate::prelude::*; + #[derive(Clone, Debug)] pub enum VideoTrack { Local(LocalVideoTrack), diff --git a/livekit/src/rtc_engine/lk_runtime.rs b/livekit/src/rtc_engine/lk_runtime.rs index 4fea0217..4f18c30f 100644 --- a/livekit/src/rtc_engine/lk_runtime.rs +++ b/livekit/src/rtc_engine/lk_runtime.rs @@ -12,11 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::{ + fmt::{Debug, Formatter}, + sync::{Arc, Weak}, +}; + use lazy_static::lazy_static; use libwebrtc::prelude::*; use parking_lot::Mutex; -use std::fmt::{Debug, Formatter}; -use std::sync::{Arc, Weak}; lazy_static! { static ref LK_RUNTIME: Mutex> = Mutex::new(Weak::new()); @@ -39,9 +42,7 @@ impl LkRuntime { lk_runtime } else { log::debug!("LkRuntime::new()"); - let new_runtime = Arc::new(Self { - pc_factory: PeerConnectionFactory::default(), - }); + let new_runtime = Arc::new(Self { pc_factory: PeerConnectionFactory::default() }); *lk_runtime_ref = Arc::downgrade(&new_runtime); new_runtime } diff --git a/livekit/src/rtc_engine/mod.rs b/livekit/src/rtc_engine/mod.rs index 4bdf52f2..25d2bc2a 100644 --- a/livekit/src/rtc_engine/mod.rs +++ b/livekit/src/rtc_engine/mod.rs @@ -12,30 +12,34 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::id::ParticipantSid; -use crate::options::TrackPublishOptions; -use crate::prelude::LocalTrack; -use crate::room::DisconnectReason; -use crate::rtc_engine::lk_runtime::LkRuntime; -use crate::rtc_engine::rtc_session::{RtcSession, SessionEvent, SessionEvents}; -use crate::DataPacketKind; +use std::{borrow::Cow, fmt::Debug, sync::Arc, time::Duration}; + use libwebrtc::prelude::*; use livekit_api::signal_client::{SignalError, SignalOptions}; use livekit_protocol as proto; -use parking_lot::RwLock; -use parking_lot::RwLockReadGuard; -use std::borrow::Cow; -use std::fmt::Debug; -use std::sync::Arc; -use std::time::Duration; +use parking_lot::{RwLock, RwLockReadGuard}; use thiserror::Error; -use tokio::sync::{mpsc, oneshot}; -use tokio::sync::{Mutex as AsyncMutex, Notify}; -use tokio::sync::{RwLock as AsyncRwLock, RwLockReadGuard as AsyncRwLockReadGuard}; -use tokio::task::JoinHandle; -use tokio::time::{interval, Interval}; +use tokio::{ + sync::{ + mpsc, oneshot, Mutex as AsyncMutex, Notify, RwLock as AsyncRwLock, + RwLockReadGuard as AsyncRwLockReadGuard, + }, + task::JoinHandle, + time::{interval, Interval}, +}; pub use self::rtc_session::SessionStats; +use crate::{ + id::ParticipantSid, + options::TrackPublishOptions, + prelude::LocalTrack, + room::DisconnectReason, + rtc_engine::{ + lk_runtime::LkRuntime, + rtc_session::{RtcSession, SessionEvent, SessionEvents}, + }, + DataPacketKind, +}; pub mod lk_runtime; mod peer_transport; @@ -139,7 +143,8 @@ struct EngineHandle { } struct EngineInner { - // Keep a strong reference to LkRuntime to avoid creating a new RtcRuntime or PeerConnection factory accross multiple Rtc sessions + // Keep a strong reference to LkRuntime to avoid creating a new RtcRuntime or PeerConnection + // factory accross multiple Rtc sessions #[allow(dead_code)] lk_runtime: Arc, engine_tx: EngineEmitter, @@ -367,13 +372,7 @@ impl EngineInner { async fn on_session_event(self: &Arc, event: SessionEvent) -> EngineResult<()> { match event { - SessionEvent::Close { - source, - reason, - can_reconnect, - retry_now, - full_reconnect, - } => { + SessionEvent::Close { source, reason, can_reconnect, retry_now, full_reconnect } => { log::info!("received session close: {}, {:?}", source, reason); if can_reconnect { self.reconnection_needed(retry_now, full_reconnect); @@ -388,12 +387,7 @@ impl EngineInner { }); } } - SessionEvent::Data { - participant_sid, - payload, - topic, - kind, - } => { + SessionEvent::Data { participant_sid, payload, topic, kind } => { let _ = self.engine_tx.send(EngineEvent::Data { participant_sid, payload, @@ -401,31 +395,17 @@ impl EngineInner { kind, }); } - SessionEvent::MediaTrack { - track, - stream, - transceiver, - } => { - let _ = self.engine_tx.send(EngineEvent::MediaTrack { - track, - stream, - transceiver, - }); + SessionEvent::MediaTrack { track, stream, transceiver } => { + let _ = self.engine_tx.send(EngineEvent::MediaTrack { track, stream, transceiver }); } SessionEvent::ParticipantUpdate { updates } => { - let _ = self - .engine_tx - .send(EngineEvent::ParticipantUpdate { updates }); + let _ = self.engine_tx.send(EngineEvent::ParticipantUpdate { updates }); } SessionEvent::SpeakersChanged { speakers } => { - let _ = self - .engine_tx - .send(EngineEvent::SpeakersChanged { speakers }); + let _ = self.engine_tx.send(EngineEvent::SpeakersChanged { speakers }); } SessionEvent::ConnectionQuality { updates } => { - let _ = self - .engine_tx - .send(EngineEvent::ConnectionQuality { updates }); + let _ = self.engine_tx.send(EngineEvent::ConnectionQuality { updates }); } SessionEvent::RoomUpdate { room } => { let _ = self.engine_tx.send(EngineEvent::RoomUpdate { room }); @@ -532,7 +512,8 @@ impl EngineInner { /// We first try to resume the connection, if it fails, we start a full reconnect. /// NOTE: The reconnect_task must be canncellation safe async fn reconnect_task(self: &Arc) -> EngineResult<()> { - // Get the latest connection info from the signal_client (including the refreshed token because the initial join token may have expired) + // Get the latest connection info from the signal_client (including the refreshed token + // because the initial join token may have expired) let (url, token) = { let running_handle = self.running_handle.read(); let signal_client = running_handle.session.signal_client(); @@ -549,9 +530,7 @@ impl EngineInner { }; if is_closed { - return Err(EngineError::Connection( - "attempt canncelled, engine is closed".into(), - )); + return Err(EngineError::Connection("attempt canncelled, engine is closed".into())); } if full_reconnect { @@ -562,9 +541,8 @@ impl EngineInner { } log::error!("restarting connection... attempt: {}", i); - if let Err(err) = self - .try_restart_connection(&url, &token, self.options.clone()) - .await + if let Err(err) = + self.try_restart_connection(&url, &token, self.options.clone()).await { log::error!("restarting connection failed: {}", err); } else { @@ -604,7 +582,8 @@ impl EngineInner { } /// Try to recover the connection by doing a full reconnect. - /// It recreates a new RtcSession (new peer connection, new signal client, new data channels, etc...) + /// It recreates a new RtcSession (new peer connection, new signal client, new data channels, + /// etc...) async fn try_restart_connection( self: &Arc, url: &str, @@ -631,9 +610,7 @@ impl EngineInner { // On SignalRestarted, the room will try to unpublish the local tracks // NOTE: Doing operations that use rtc_session will not use the new one let (tx, rx) = oneshot::channel(); - let _ = self - .engine_tx - .send(EngineEvent::SignalRestarted { join_response, tx }); + let _ = self.engine_tx.send(EngineEvent::SignalRestarted { join_response, tx }); let _ = rx.await; new_session.wait_pc_connection().await?; @@ -659,10 +636,7 @@ impl EngineInner { let reconnect_response = session.restart().await?; let (tx, rx) = oneshot::channel(); - let _ = self.engine_tx.send(EngineEvent::SignalResumed { - reconnect_response, - tx, - }); + let _ = self.engine_tx.send(EngineEvent::SignalResumed { reconnect_response, tx }); // With SignalResumed, the room will send a SyncState message to the server let _ = rx.await; diff --git a/livekit/src/rtc_engine/peer_transport.rs b/livekit/src/rtc_engine/peer_transport.rs index 15b02934..9546ba3e 100644 --- a/livekit/src/rtc_engine/peer_transport.rs +++ b/livekit/src/rtc_engine/peer_transport.rs @@ -12,11 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::{ + fmt::{Debug, Formatter}, + sync::Arc, +}; + use libwebrtc::prelude::*; use livekit_protocol as proto; use parking_lot::Mutex; -use std::fmt::{Debug, Formatter}; -use std::sync::Arc; use tokio::sync::Mutex as AsyncMutex; use super::EngineResult; @@ -38,9 +41,7 @@ pub struct PeerTransport { impl Debug for PeerTransport { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { - f.debug_struct("PeerTransport") - .field("target", &self.signal_target) - .finish() + f.debug_struct("PeerTransport").field("target", &self.signal_target).finish() } } @@ -83,9 +84,7 @@ impl PeerTransport { if self.peer_connection.current_remote_description().is_some() && !inner.restarting_ice { drop(inner); - self.peer_connection - .add_ice_candidate(ice_candidate) - .await?; + self.peer_connection.add_ice_candidate(ice_candidate).await?; return Ok(()); } @@ -100,9 +99,7 @@ impl PeerTransport { ) -> EngineResult<()> { let mut inner = self.inner.lock().await; - self.peer_connection - .set_remote_description(remote_description) - .await?; + self.peer_connection.set_remote_description(remote_description).await?; for ic in inner.pending_candidates.drain(..) { self.peer_connection.add_ice_candidate(ic).await?; @@ -125,9 +122,7 @@ impl PeerTransport { ) -> EngineResult { self.set_remote_description(offer).await?; let answer = self.peer_connection().create_answer(options).await?; - self.peer_connection() - .set_local_description(answer.clone()) - .await?; + self.peer_connection().set_local_description(answer.clone()).await?; Ok(answer) } @@ -144,11 +139,9 @@ impl PeerTransport { if options.ice_restart && remote_sdp.is_some() { let remote_sdp = remote_sdp.unwrap(); - // Cancel the old renegotiation (Basically say the server rejected the previous offer) - // So we can resend a new offer just after this - self.peer_connection - .set_remote_description(remote_sdp) - .await?; + // Cancel the old renegotiation (Basically say the server rejected the previous + // offer) So we can resend a new offer just after this + self.peer_connection.set_remote_description(remote_sdp).await?; } else { inner.renegotiate = true; return Ok(()); @@ -159,9 +152,7 @@ impl PeerTransport { } let offer = self.peer_connection.create_offer(options).await?; - self.peer_connection - .set_local_description(offer.clone()) - .await?; + self.peer_connection.set_local_description(offer.clone()).await?; if let Some(handler) = self.on_offer_handler.lock().as_mut() { handler(offer); diff --git a/livekit/src/rtc_engine/rtc_events.rs b/livekit/src/rtc_engine/rtc_events.rs index 4ed470a8..88bd1707 100644 --- a/livekit/src/rtc_engine/rtc_events.rs +++ b/livekit/src/rtc_engine/rtc_events.rs @@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::peer_transport::PeerTransport; -use crate::rtc_engine::peer_transport::OnOfferCreated; use libwebrtc::{self as rtc, prelude::*}; use livekit_protocol as proto; use log::error; use tokio::sync::mpsc; +use super::peer_transport::PeerTransport; +use crate::rtc_engine::peer_transport::OnOfferCreated; + pub type RtcEmitter = mpsc::UnboundedSender; pub type RtcEvents = mpsc::UnboundedReceiver; @@ -70,10 +71,7 @@ fn on_ice_candidate( emitter: RtcEmitter, ) -> rtc::peer_connection::OnIceCandidate { Box::new(move |ice_candidate| { - let _ = emitter.send(RtcEvent::IceCandidate { - ice_candidate, - target, - }); + let _ = emitter.send(RtcEvent::IceCandidate { ice_candidate, target }); }) } @@ -90,10 +88,7 @@ fn on_data_channel( Box::new(move |data_channel| { data_channel.on_message(Some(on_message(emitter.clone()))); - let _ = emitter.send(RtcEvent::DataChannel { - data_channel, - target, - }); + let _ = emitter.send(RtcEvent::DataChannel { data_channel, target }); }) } @@ -127,33 +122,23 @@ pub fn forward_pc_events(transport: &mut PeerTransport, rtc_emitter: RtcEmitter) .peer_connection() .on_data_channel(Some(on_data_channel(signal_target, rtc_emitter.clone()))); - transport - .peer_connection() - .on_track(Some(on_track(signal_target, rtc_emitter.clone()))); + transport.peer_connection().on_track(Some(on_track(signal_target, rtc_emitter.clone()))); - transport - .peer_connection() - .on_connection_state_change(Some(on_connection_state_change( - signal_target, - rtc_emitter.clone(), - ))); + transport.peer_connection().on_connection_state_change(Some(on_connection_state_change( + signal_target, + rtc_emitter.clone(), + ))); transport .peer_connection() - .on_ice_candidate_error(Some(on_ice_candidate_error( - signal_target, - rtc_emitter.clone(), - ))); + .on_ice_candidate_error(Some(on_ice_candidate_error(signal_target, rtc_emitter.clone()))); transport.on_offer(Some(on_offer(signal_target, rtc_emitter))); } fn on_message(emitter: RtcEmitter) -> rtc::data_channel::OnMessage { Box::new(move |buffer| { - let _ = emitter.send(RtcEvent::Data { - data: buffer.data.to_vec(), - binary: buffer.binary, - }); + let _ = emitter.send(RtcEvent::Data { data: buffer.data.to_vec(), binary: buffer.binary }); }) } diff --git a/livekit/src/rtc_engine/rtc_session.rs b/livekit/src/rtc_engine/rtc_session.rs index 628f4325..b38ff430 100644 --- a/livekit/src/rtc_engine/rtc_session.rs +++ b/livekit/src/rtc_engine/rtc_session.rs @@ -12,35 +12,48 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::{rtc_events, EngineError, EngineOptions, EngineResult, SimulateScenario}; -use crate::id::ParticipantSid; -use crate::options::TrackPublishOptions; -use crate::prelude::TrackKind; -use crate::room::DisconnectReason; -use crate::rtc_engine::lk_runtime::LkRuntime; -use crate::rtc_engine::peer_transport::PeerTransport; -use crate::rtc_engine::rtc_events::{RtcEvent, RtcEvents}; -use crate::track::LocalTrack; -use crate::DataPacketKind; -use libwebrtc::prelude::*; -use libwebrtc::stats::RtcStats; +use std::{ + collections::HashMap, + convert::TryInto, + fmt::Debug, + ops::Not, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, + time::Duration, +}; + +use libwebrtc::{prelude::*, stats::RtcStats}; use livekit_api::signal_client::{SignalClient, SignalEvent, SignalEvents}; use livekit_protocol as proto; use parking_lot::Mutex; use prost::Message; -use proto::debouncer::{self, Debouncer}; -use proto::SignalTarget; +use proto::{ + debouncer::{self, Debouncer}, + SignalTarget, +}; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; -use std::convert::TryInto; -use std::fmt::Debug; -use std::ops::Not; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::Arc; -use std::time::Duration; -use tokio::sync::{mpsc, oneshot, watch}; -use tokio::task::JoinHandle; -use tokio::time::sleep; +use tokio::{ + sync::{mpsc, oneshot, watch}, + task::JoinHandle, + time::sleep, +}; + +use super::{rtc_events, EngineError, EngineOptions, EngineResult, SimulateScenario}; +use crate::{ + id::ParticipantSid, + options::TrackPublishOptions, + prelude::TrackKind, + room::DisconnectReason, + rtc_engine::{ + lk_runtime::LkRuntime, + peer_transport::PeerTransport, + rtc_events::{RtcEvent, RtcEvents}, + }, + track::LocalTrack, + DataPacketKind, +}; pub const ICE_CONNECT_TIMEOUT: Duration = Duration::from_secs(15); pub const TRACK_PUBLISH_TIMEOUT: Duration = Duration::from_secs(10); @@ -166,9 +179,7 @@ impl RtcSession { let lk_runtime = LkRuntime::instance(); let mut publisher_pc = PeerTransport::new( - lk_runtime - .pc_factory() - .create_peer_connection(rtc_config.clone())?, + lk_runtime.pc_factory().create_peer_connection(rtc_config.clone())?, proto::SignalTarget::Publisher, ); @@ -188,10 +199,7 @@ impl RtcSession { let mut reliable_dc = publisher_pc.peer_connection().create_data_channel( RELIABLE_DC_LABEL, - DataChannelInit { - ordered: true, - ..DataChannelInit::default() - }, + DataChannelInit { ordered: true, ..DataChannelInit::default() }, )?; // Forward events received inside the signaling thread to our rtc channel @@ -221,11 +229,7 @@ impl RtcSession { let signal_task = tokio::spawn(inner.clone().signal_task(signal_events, close_rx.clone())); let rtc_task = tokio::spawn(inner.clone().rtc_session_task(rtc_events, close_rx)); - let handle = Mutex::new(Some(SessionHandle { - close_tx, - signal_task, - rtc_task, - })); + let handle = Mutex::new(Some(SessionHandle { close_tx, signal_task, rtc_task })); Ok((Self { inner, handle }, join_response, session_events)) } @@ -295,24 +299,11 @@ impl RtcSession { } pub async fn get_stats(&self) -> EngineResult { - let publisher_stats = self - .inner - .publisher_pc - .peer_connection() - .get_stats() - .await?; - - let subscriber_stats = self - .inner - .subscriber_pc - .peer_connection() - .get_stats() - .await?; - - Ok(SessionStats { - publisher_stats, - subscriber_stats, - }) + let publisher_stats = self.inner.publisher_pc.peer_connection().get_stats().await?; + + let subscriber_stats = self.inner.subscriber_pc.peer_connection().get_stats().await?; + + Ok(SessionStats { publisher_stats, subscriber_stats }) } pub fn publisher(&self) -> &PeerTransport { @@ -433,18 +424,14 @@ impl SessionInner { log::debug!("received subscriber offer: {:?}", offer); let offer = SessionDescription::parse(&offer.sdp, offer.r#type.parse().unwrap()).unwrap(); - let answer = self - .subscriber_pc - .create_anwser(offer, AnswerOptions::default()) - .await?; + let answer = + self.subscriber_pc.create_anwser(offer, AnswerOptions::default()).await?; self.signal_client - .send(proto::signal_request::Message::Answer( - proto::SessionDescription { - r#type: "answer".to_string(), - sdp: answer.to_string(), - }, - )) + .send(proto::signal_request::Message::Answer(proto::SessionDescription { + r#type: "answer".to_string(), + sdp: answer.to_string(), + })) .await; } proto::signal_response::Message::Trickle(trickle) => { @@ -475,19 +462,17 @@ impl SessionInner { ); } proto::signal_response::Message::Update(update) => { - let _ = self.emitter.send(SessionEvent::ParticipantUpdate { - updates: update.participants, - }); + let _ = self + .emitter + .send(SessionEvent::ParticipantUpdate { updates: update.participants }); } proto::signal_response::Message::SpeakersChanged(speaker) => { - let _ = self.emitter.send(SessionEvent::SpeakersChanged { - speakers: speaker.speakers, - }); + let _ = + self.emitter.send(SessionEvent::SpeakersChanged { speakers: speaker.speakers }); } proto::signal_response::Message::ConnectionQuality(quality) => { - let _ = self.emitter.send(SessionEvent::ConnectionQuality { - updates: quality.updates, - }); + let _ = + self.emitter.send(SessionEvent::ConnectionQuality { updates: quality.updates }); } proto::signal_response::Message::TrackPublished(publish_res) => { let mut pending_tracks = self.pending_tracks.lock(); @@ -496,9 +481,8 @@ impl SessionInner { } } proto::signal_response::Message::RoomUpdate(room_update) => { - let _ = self.emitter.send(SessionEvent::RoomUpdate { - room: room_update.room.unwrap(), - }); + let _ = + self.emitter.send(SessionEvent::RoomUpdate { room: room_update.room.unwrap() }); } _ => {} } @@ -508,23 +492,18 @@ impl SessionInner { async fn on_rtc_event(&self, event: RtcEvent) -> EngineResult<()> { match event { - RtcEvent::IceCandidate { - ice_candidate, - target, - } => { + RtcEvent::IceCandidate { ice_candidate, target } => { log::debug!("local ice_candidate {:?} {:?}", ice_candidate, target); self.signal_client - .send(proto::signal_request::Message::Trickle( - proto::TrickleRequest { - candidate_init: serde_json::to_string(&IceCandidateJson { - sdp_mid: ice_candidate.sdp_mid(), - sdp_m_line_index: ice_candidate.sdp_mline_index(), - candidate: ice_candidate.candidate(), - }) - .unwrap(), - target: target as i32, - }, - )) + .send(proto::signal_request::Message::Trickle(proto::TrickleRequest { + candidate_init: serde_json::to_string(&IceCandidateJson { + sdp_mid: ice_candidate.sdp_mid(), + sdp_m_line_index: ice_candidate.sdp_mline_index(), + candidate: ice_candidate.candidate(), + }) + .unwrap(), + target: target as i32, + })) .await; } RtcEvent::ConnectionChange { state, target } => { @@ -541,10 +520,7 @@ impl SessionInner { ); } } - RtcEvent::DataChannel { - data_channel, - target, - } => { + RtcEvent::DataChannel { data_channel, target } => { log::debug!("received data channel: {:?} {:?}", data_channel, target); if target == SignalTarget::Subscriber { if data_channel.label() == LOSSY_DC_LABEL { @@ -558,20 +534,13 @@ impl SessionInner { // Send the publisher offer to the server log::debug!("sending publisher offer: {:?}", offer); self.signal_client - .send(proto::signal_request::Message::Offer( - proto::SessionDescription { - r#type: "offer".to_string(), - sdp: offer.to_string(), - }, - )) + .send(proto::signal_request::Message::Offer(proto::SessionDescription { + r#type: "offer".to_string(), + sdp: offer.to_string(), + })) .await; } - RtcEvent::Track { - mut streams, - track, - transceiver, - target: _, - } => { + RtcEvent::Track { mut streams, track, transceiver, target: _ } => { if !streams.is_empty() { let _ = self.emitter.send(SessionEvent::MediaTrack { stream: streams.remove(0), @@ -584,9 +553,7 @@ impl SessionInner { } RtcEvent::Data { data, binary } => { if !binary { - Err(EngineError::Internal( - "text messages aren't supported".into(), - ))?; + Err(EngineError::Internal("text messages aren't supported".into()))?; } let data = proto::DataPacket::decode(&*data).unwrap(); @@ -625,9 +592,7 @@ impl SessionInner { pendings_tracks.insert(cid.clone(), tx); } - self.signal_client - .send(proto::signal_request::Message::AddTrack(req)) - .await; + self.signal_client.send(proto::signal_request::Message::AddTrack(req)).await; // Wait the result from the server (TrackInfo) tokio::select! { @@ -665,18 +630,16 @@ impl SessionInner { send_encodings: encodings, }; - let transceiver = self - .publisher_pc - .peer_connection() - .add_transceiver(track.rtc_track(), init)?; + let transceiver = + self.publisher_pc.peer_connection().add_transceiver(track.rtc_track(), init)?; if track.kind() == TrackKind::Video { - let capabilities = LkRuntime::instance() - .pc_factory() - .get_rtp_sender_capabilities(match track.kind() { + let capabilities = LkRuntime::instance().pc_factory().get_rtp_sender_capabilities( + match track.kind() { TrackKind::Video => MediaType::Video, TrackKind::Audio => MediaType::Audio, - }); + }, + ); let mut matched = Vec::new(); let mut partial_matched = Vec::new(); @@ -743,12 +706,10 @@ impl SessionInner { async fn simulate_scenario(&self, scenario: SimulateScenario) -> EngineResult<()> { let simulate_leave = || { - self.on_signal_event(proto::signal_response::Message::Leave( - proto::LeaveRequest { - reason: DisconnectReason::ClientInitiated as i32, - can_reconnect: true, - }, - )) + self.on_signal_event(proto::signal_response::Message::Leave(proto::LeaveRequest { + reason: DisconnectReason::ClientInitiated as i32, + can_reconnect: true, + })) }; match scenario { @@ -757,66 +718,54 @@ impl SessionInner { } SimulateScenario::Speaker => { self.signal_client - .send(proto::signal_request::Message::Simulate( - proto::SimulateScenario { - scenario: Some(proto::simulate_scenario::Scenario::SpeakerUpdate(3)), - }, - )) + .send(proto::signal_request::Message::Simulate(proto::SimulateScenario { + scenario: Some(proto::simulate_scenario::Scenario::SpeakerUpdate(3)), + })) .await; } SimulateScenario::NodeFailure => { self.signal_client - .send(proto::signal_request::Message::Simulate( - proto::SimulateScenario { - scenario: Some(proto::simulate_scenario::Scenario::NodeFailure(true)), - }, - )) + .send(proto::signal_request::Message::Simulate(proto::SimulateScenario { + scenario: Some(proto::simulate_scenario::Scenario::NodeFailure(true)), + })) .await; } SimulateScenario::ServerLeave => { self.signal_client - .send(proto::signal_request::Message::Simulate( - proto::SimulateScenario { - scenario: Some(proto::simulate_scenario::Scenario::ServerLeave(true)), - }, - )) + .send(proto::signal_request::Message::Simulate(proto::SimulateScenario { + scenario: Some(proto::simulate_scenario::Scenario::ServerLeave(true)), + })) .await; } SimulateScenario::Migration => { self.signal_client - .send(proto::signal_request::Message::Simulate( - proto::SimulateScenario { - scenario: Some(proto::simulate_scenario::Scenario::Migration(true)), - }, - )) + .send(proto::signal_request::Message::Simulate(proto::SimulateScenario { + scenario: Some(proto::simulate_scenario::Scenario::Migration(true)), + })) .await; } SimulateScenario::ForceTcp => { self.signal_client - .send(proto::signal_request::Message::Simulate( - proto::SimulateScenario { - scenario: Some( - proto::simulate_scenario::Scenario::SwitchCandidateProtocol( - proto::CandidateProtocol::Tcp as i32, - ), + .send(proto::signal_request::Message::Simulate(proto::SimulateScenario { + scenario: Some( + proto::simulate_scenario::Scenario::SwitchCandidateProtocol( + proto::CandidateProtocol::Tcp as i32, ), - }, - )) + ), + })) .await; simulate_leave().await? } SimulateScenario::ForceTls => { self.signal_client - .send(proto::signal_request::Message::Simulate( - proto::SimulateScenario { - scenario: Some( - proto::simulate_scenario::Scenario::SwitchCandidateProtocol( - proto::CandidateProtocol::Tls as i32, - ), + .send(proto::signal_request::Message::Simulate(proto::SimulateScenario { + scenario: Some( + proto::simulate_scenario::Scenario::SwitchCandidateProtocol( + proto::CandidateProtocol::Tls as i32, ), - }, - )) + ), + })) .await; simulate_leave().await? @@ -839,19 +788,16 @@ impl SessionInner { }) } - /// This reconnection if more seemless compared to the full reconnection implemented in ['RTCEngine'] + /// This reconnection if more seemless compared to the full reconnection implemented in + /// ['RTCEngine'] async fn restart(&self) -> EngineResult { let reconnect_response = self.signal_client.restart().await?; log::info!("received reconnect response: {:?}", reconnect_response); let rtc_config = make_rtc_config_reconnect(reconnect_response.clone(), self.options.rtc_config.clone()); - self.publisher_pc - .peer_connection() - .set_configuration(rtc_config.clone())?; - self.subscriber_pc - .peer_connection() - .set_configuration(rtc_config)?; + self.publisher_pc.peer_connection().set_configuration(rtc_config.clone())?; + self.subscriber_pc.peer_connection().set_configuration(rtc_config)?; Ok(reconnect_response) } @@ -859,10 +805,7 @@ impl SessionInner { async fn restart_publisher(&self) -> EngineResult<()> { if self.has_published.load(Ordering::Acquire) { self.publisher_pc - .create_and_send_offer(OfferOptions { - ice_restart: true, - ..Default::default() - }) + .create_and_send_offer(OfferOptions { ice_restart: true, ..Default::default() }) .await?; } Ok(()) @@ -903,19 +846,14 @@ impl SessionInner { if debouncer.is_none() || debouncer.as_ref().unwrap().call().is_err() { let session = self.clone(); - *debouncer = Some(debouncer::debounce( - PUBLISHER_NEGOTIATION_FREQUENCY, - async move { - log::debug!("negotiating the publisher"); - if let Err(err) = session - .publisher_pc - .create_and_send_offer(OfferOptions::default()) - .await - { - log::error!("failed to negotiate the publisher: {:?}", err); - } - }, - )); + *debouncer = Some(debouncer::debounce(PUBLISHER_NEGOTIATION_FREQUENCY, async move { + log::debug!("negotiating the publisher"); + if let Err(err) = + session.publisher_pc.create_and_send_offer(OfferOptions::default()).await + { + log::error!("failed to negotiate the publisher: {:?}", err); + } + })); } } diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 00000000..18a73ace --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,10 @@ +comment_width = 100 +doc_comment_code_block_width = 100 +format_code_in_doc_comments = true +group_imports = "StdExternalCrate" +imports_granularity = "Crate" +max_width = 100 +use_small_heuristics = "Max" +wrap_comments = true +# Workaround for https://github.com/rust-lang/rust.vim/issues/464 +edition = "2021" diff --git a/webrtc-sys/build.rs b/webrtc-sys/build.rs index 9da4df32..826c528b 100644 --- a/webrtc-sys/build.rs +++ b/webrtc-sys/build.rs @@ -12,9 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::env; -use std::path; -use std::process::Command; +use std::{env, path, process::Command}; fn main() { if env::var("DOCS_RS").is_ok() { @@ -93,10 +91,7 @@ fn main() { webrtc_include.join("sdk/objc/base"), ]); - println!( - "cargo:rustc-link-search=native={}", - webrtc_lib.to_str().unwrap() - ); + println!("cargo:rustc-link-search=native={}", webrtc_lib.to_str().unwrap()); for (key, value) in webrtc_sys_build::webrtc_defines() { let value = value.as_deref(); @@ -157,10 +152,7 @@ fn main() { configure_darwin_sysroot(&mut builder); - builder - .file("src/objc_video_factory.mm") - .flag("-stdlib=libc++") - .flag("-std=c++20"); + builder.file("src/objc_video_factory.mm").flag("-stdlib=libc++").flag("-std=c++20"); } "ios" => { println!("cargo:rustc-link-lib=framework=CoreFoundation"); @@ -192,10 +184,7 @@ fn main() { configure_android_sysroot(&mut builder); - builder - .file("src/android.cpp") - .flag("-std=c++20") - .cpp_link_stdlib("c++_static"); + builder.file("src/android.cpp").flag("-std=c++20").cpp_link_stdlib("c++_static"); } _ => { panic!("Unsupported target, {}", target_os); @@ -239,18 +228,12 @@ fn configure_darwin_sysroot(builder: &mut cc::Build) { println!("cargo:rustc-link-lib={}", clang_rt); println!("cargo:rustc-link-arg=-ObjC"); - let sysroot = Command::new("xcrun") - .args(["--sdk", sdk, "--show-sdk-path"]) - .output() - .unwrap(); + let sysroot = Command::new("xcrun").args(["--sdk", sdk, "--show-sdk-path"]).output().unwrap(); let sysroot = String::from_utf8_lossy(&sysroot.stdout); let sysroot = sysroot.trim(); - let search_dirs = Command::new("clang") - .arg("--print-search-dirs") - .output() - .unwrap(); + let search_dirs = Command::new("clang").arg("--print-search-dirs").output().unwrap(); let search_dirs = String::from_utf8_lossy(&search_dirs.stdout); for line in search_dirs.lines() { diff --git a/webrtc-sys/build/src/lib.rs b/webrtc-sys/build/src/lib.rs index 6b4cb1ee..4f93ce54 100644 --- a/webrtc-sys/build/src/lib.rs +++ b/webrtc-sys/build/src/lib.rs @@ -83,8 +83,8 @@ pub fn custom_dir() -> Option { } /// Location of the downloaded webrtc binaries -/// The reason why we don't use OUT_DIR is because we sometimes need to share the same binaries across multiple crates -/// without dependencies constraints +/// The reason why we don't use OUT_DIR is because we sometimes need to share the same binaries +/// across multiple crates without dependencies constraints /// This also has the benefit of not re-downloading the binaries for each crate pub fn prebuilt_dir() -> path::PathBuf { let target_dir = scratch::path(SCRATH_PATH); @@ -119,9 +119,7 @@ pub fn webrtc_defines() -> Vec<(String, Option)> { let webrtc_gni = fs::File::open(webrtc_dir().join("webrtc.ninja")).unwrap(); let mut defines_line = String::default(); - io::BufReader::new(webrtc_gni) - .read_line(&mut defines_line) - .unwrap(); + io::BufReader::new(webrtc_gni).read_line(&mut defines_line).unwrap(); let mut vec = Vec::default(); for cap in defines_re.captures_iter(&defines_line) { @@ -157,10 +155,8 @@ pub fn configure_jni_symbols() -> Result<(), Box> { let jni_regex = Regex::new(r"(Java_org_webrtc.*)").unwrap(); let content = String::from_utf8_lossy(&readelf_output.stdout); - let jni_symbols: Vec<&str> = jni_regex - .captures_iter(&content) - .map(|cap| cap.get(1).unwrap().as_str()) - .collect(); + let jni_symbols: Vec<&str> = + jni_regex.captures_iter(&content).map(|cap| cap.get(1).unwrap().as_str()).collect(); if jni_symbols.is_empty() { return Err("No JNI symbols found".into()); // Shouldn't happen @@ -178,10 +174,7 @@ pub fn configure_jni_symbols() -> Result<(), Box> { let jni_symbols = jni_symbols.join("; "); write!(vs_file, "JNI_WEBRTC {{\n\tglobal: {}; \n}};", jni_symbols).unwrap(); - println!( - "cargo:rustc-link-arg=-Wl,--version-script={}", - vs_path.display() - ); + println!("cargo:rustc-link-arg=-Wl,--version-script={}", vs_path.display()); Ok(()) } @@ -203,11 +196,7 @@ pub fn download_webrtc() -> Result<(), Box> { let tmp_path = env::var("OUT_DIR").unwrap() + "/webrtc.zip"; let tmp_path = path::Path::new(&tmp_path); - let mut file = fs::File::options() - .write(true) - .read(true) - .create(true) - .open(tmp_path)?; + let mut file = fs::File::options().write(true).read(true).create(true).open(tmp_path)?; resp.copy_to(&mut file)?; let mut archive = zip::ZipArchive::new(file)?; diff --git a/webrtc-sys/src/audio_track.rs b/webrtc-sys/src/audio_track.rs index c3c35cd4..ee32e475 100644 --- a/webrtc-sys/src/audio_track.rs +++ b/webrtc-sys/src/audio_track.rs @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::impl_thread_safety; use std::sync::Arc; +use crate::impl_thread_safety; + #[cxx::bridge(namespace = "livekit")] pub mod ffi { @@ -88,7 +89,6 @@ impl AudioSinkWrapper { } fn on_data(&self, data: &[i16], sample_rate: i32, nb_channels: usize, nb_frames: usize) { - self.observer - .on_data(data, sample_rate, nb_channels, nb_frames); + self.observer.on_data(data, sample_rate, nb_channels, nb_frames); } } diff --git a/webrtc-sys/src/data_channel.rs b/webrtc-sys/src/data_channel.rs index b01f75c4..7073194d 100644 --- a/webrtc-sys/src/data_channel.rs +++ b/webrtc-sys/src/data_channel.rs @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::impl_thread_safety; use std::sync::Arc; +use crate::impl_thread_safety; + #[cxx::bridge(namespace = "livekit")] pub mod ffi { #[derive(Debug)] diff --git a/webrtc-sys/src/frame_cryptor.rs b/webrtc-sys/src/frame_cryptor.rs index 3210d5ca..e46e1052 100644 --- a/webrtc-sys/src/frame_cryptor.rs +++ b/webrtc-sys/src/frame_cryptor.rs @@ -161,7 +161,6 @@ impl RtcFrameCryptorObserverWrapper { participant_id: String, state: FrameCryptionState, ) { - self.observer - .on_frame_cryption_state_change(participant_id, state); + self.observer.on_frame_cryption_state_change(participant_id, state); } } diff --git a/webrtc-sys/src/jsep.rs b/webrtc-sys/src/jsep.rs index e3bc531b..cdbb4366 100644 --- a/webrtc-sys/src/jsep.rs +++ b/webrtc-sys/src/jsep.rs @@ -12,9 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::{ + error::Error, + fmt::{Display, Formatter}, +}; + use crate::impl_thread_safety; -use std::error::Error; -use std::fmt::{Display, Formatter}; #[cxx::bridge(namespace = "livekit")] pub mod ffi { @@ -74,11 +77,7 @@ impl Error for ffi::SdpParseError {} impl Display for ffi::SdpParseError { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { - write!( - f, - "SdpParseError occurred {}: {}", - self.line, self.description - ) + write!(f, "SdpParseError occurred {}: {}", self.line, self.description) } } diff --git a/webrtc-sys/src/lib.rs b/webrtc-sys/src/lib.rs index e007075b..7a3e19e1 100644 --- a/webrtc-sys/src/lib.rs +++ b/webrtc-sys/src/lib.rs @@ -18,6 +18,7 @@ pub mod audio_resampler; pub mod audio_track; pub mod candidate; pub mod data_channel; +pub mod frame_cryptor; pub mod helper; pub mod jsep; pub mod media_stream; @@ -34,7 +35,6 @@ pub mod video_frame_buffer; pub mod video_track; pub mod webrtc; pub mod yuv_helper; -pub mod frame_cryptor; pub const MEDIA_TYPE_VIDEO: &str = "video"; pub const MEDIA_TYPE_AUDIO: &str = "audio"; diff --git a/webrtc-sys/src/peer_connection.rs b/webrtc-sys/src/peer_connection.rs index 602a396d..b81c8955 100644 --- a/webrtc-sys/src/peer_connection.rs +++ b/webrtc-sys/src/peer_connection.rs @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::impl_thread_safety; use std::any::Any; +use crate::impl_thread_safety; + #[cxx::bridge(namespace = "livekit")] pub mod ffi { #[repr(i32)] diff --git a/webrtc-sys/src/peer_connection_factory.rs b/webrtc-sys/src/peer_connection_factory.rs index 74c23338..51efc2f4 100644 --- a/webrtc-sys/src/peer_connection_factory.rs +++ b/webrtc-sys/src/peer_connection_factory.rs @@ -12,16 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::candidate::ffi::Candidate; -use crate::data_channel::ffi::DataChannel; -use crate::impl_thread_safety; -use crate::jsep::ffi::IceCandidate; -use crate::media_stream::ffi::MediaStream; -use crate::rtp_receiver::ffi::RtpReceiver; -use crate::rtp_transceiver::ffi::RtpTransceiver; -use cxx::SharedPtr; use std::sync::Arc; +use cxx::SharedPtr; + +use crate::{ + candidate::ffi::Candidate, data_channel::ffi::DataChannel, impl_thread_safety, + jsep::ffi::IceCandidate, media_stream::ffi::MediaStream, rtp_receiver::ffi::RtpReceiver, + rtp_transceiver::ffi::RtpTransceiver, +}; + #[cxx::bridge(namespace = "livekit")] pub mod ffi { pub struct CandidatePair { @@ -251,8 +251,7 @@ impl PeerConnectionObserverWrapper { } fn on_standardized_ice_connection_change(&self, new_state: ffi::IceConnectionState) { - self.observer - .on_standardized_ice_connection_change(new_state); + self.observer.on_standardized_ice_connection_change(new_state); } fn on_connection_change(&self, new_state: ffi::PeerConnectionState) { @@ -275,13 +274,11 @@ impl PeerConnectionObserverWrapper { error_code: i32, error_text: String, ) { - self.observer - .on_ice_candidate_error(address, port, url, error_code, error_text); + self.observer.on_ice_candidate_error(address, port, url, error_code, error_text); } fn on_ice_candidates_removed(&self, candidates: Vec) { - self.observer - .on_ice_candidates_removed(candidates.into_iter().map(|v| v.ptr).collect()); + self.observer.on_ice_candidates_removed(candidates.into_iter().map(|v| v.ptr).collect()); } fn on_ice_connection_receiving_change(&self, receiving: bool) { @@ -293,8 +290,7 @@ impl PeerConnectionObserverWrapper { } fn on_add_track(&self, receiver: SharedPtr, streams: Vec) { - self.observer - .on_add_track(receiver, streams.into_iter().map(|v| v.ptr).collect()); + self.observer.on_add_track(receiver, streams.into_iter().map(|v| v.ptr).collect()); } fn on_track(&self, transceiver: SharedPtr) { diff --git a/webrtc-sys/src/rtc_error.rs b/webrtc-sys/src/rtc_error.rs index 2fbfb895..64c8642c 100644 --- a/webrtc-sys/src/rtc_error.rs +++ b/webrtc-sys/src/rtc_error.rs @@ -12,10 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::error::Error; -use std::fmt::{Display, Formatter}; +use std::{ + error::Error, + fmt::{Display, Formatter}, +}; -// cxx doesn't support custom Exception type, so we serialize RtcError inside the cxx::Exception "what" string +// cxx doesn't support custom Exception type, so we serialize RtcError inside the cxx::Exception +// "what" string #[cxx::bridge(namespace = "livekit")] pub mod ffi { @@ -89,11 +92,7 @@ impl Error for ffi::RtcError {} impl Display for ffi::RtcError { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { - write!( - f, - "RtcError occurred {:?}: {}", - self.error_type, self.message - ) + write!(f, "RtcError occurred {:?}: {}", self.error_type, self.message) } } @@ -118,12 +117,9 @@ mod tests { assert_eq!(error.error_type, RtcErrorType::InternalError); assert_eq!(error.error_detail, RtcErrorDetailType::DataChannelFailure); - assert_eq!(error.has_sctp_cause_code, true); + assert!(error.has_sctp_cause_code); assert_eq!(error.sctp_cause_code, 24); - assert_eq!( - error.message, - "this is not a test, I repeat, this is not a test" - ); + assert_eq!(error.message, "this is not a test, I repeat, this is not a test"); } #[test] @@ -133,7 +129,7 @@ mod tests { assert_eq!(error.error_type, RtcErrorType::InvalidModification); assert_eq!(error.error_detail, RtcErrorDetailType::None); - assert_eq!(error.has_sctp_cause_code, false); + assert!(!error.has_sctp_cause_code); assert_eq!(error.sctp_cause_code, 0); assert_eq!(error.message, "exception is thrown!"); } diff --git a/webrtc-sys/src/rtp_receiver.rs b/webrtc-sys/src/rtp_receiver.rs index 58e2725a..fb59e61c 100644 --- a/webrtc-sys/src/rtp_receiver.rs +++ b/webrtc-sys/src/rtp_receiver.rs @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::impl_thread_safety; use std::any::Any; +use crate::impl_thread_safety; + #[cxx::bridge(namespace = "livekit")] pub mod ffi { diff --git a/webrtc-sys/src/rtp_sender.rs b/webrtc-sys/src/rtp_sender.rs index 42a274a7..af5909a2 100644 --- a/webrtc-sys/src/rtp_sender.rs +++ b/webrtc-sys/src/rtp_sender.rs @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::impl_thread_safety; use std::any::Any; +use crate::impl_thread_safety; + #[cxx::bridge(namespace = "livekit")] pub mod ffi { diff --git a/webrtc-sys/src/video_track.rs b/webrtc-sys/src/video_track.rs index 24971fe8..09fd2230 100644 --- a/webrtc-sys/src/video_track.rs +++ b/webrtc-sys/src/video_track.rs @@ -12,11 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::impl_thread_safety; -use crate::video_frame::ffi::VideoFrame; -use cxx::UniquePtr; use std::sync::Arc; +use cxx::UniquePtr; + +use crate::{impl_thread_safety, video_frame::ffi::VideoFrame}; + #[cxx::bridge(namespace = "livekit")] pub mod ffi { #[repr(i32)]