1pub use cxx::SharedPtr;
16
17use std::sync::Arc;
18
19use crate::{
20 candidate::ffi::Candidate, data_channel::ffi::DataChannel, impl_thread_safety,
21 jsep::ffi::IceCandidate, media_stream::ffi::MediaStream, rtp_receiver::ffi::RtpReceiver,
22 rtp_transceiver::ffi::RtpTransceiver,
23};
24
25#[cxx::bridge(namespace = "livekit_ffi")]
26pub mod ffi {
27 pub struct CandidatePair {
28 local: SharedPtr<Candidate>,
29 remote: SharedPtr<Candidate>,
30 }
31
32 pub struct CandidatePairChangeEvent {
33 selected_candidate_pair: CandidatePair,
34 last_data_received_ms: i64,
35 reason: String,
36 estimated_disconnected_time_ms: i64,
37 }
38
39 extern "C++" {
40 include!("livekit/rtp_parameters.h");
41 include!("livekit/rtc_error.h");
42 include!("livekit/helper.h");
43 include!("livekit/candidate.h");
44 include!("livekit/media_stream.h");
45 include!("livekit/rtp_transceiver.h");
46 include!("livekit/rtp_sender.h");
47 include!("livekit/rtp_receiver.h");
48 include!("livekit/data_channel.h");
49 include!("livekit/jsep.h");
50 include!("livekit/webrtc.h");
51 include!("livekit/peer_connection.h");
52 include!("livekit/audio_track.h");
53
54 type RtcConfiguration = crate::peer_connection::ffi::RtcConfiguration;
55 type PeerConnectionState = crate::peer_connection::ffi::PeerConnectionState;
56 type SignalingState = crate::peer_connection::ffi::SignalingState;
57 type IceConnectionState = crate::peer_connection::ffi::IceConnectionState;
58 type IceGatheringState = crate::peer_connection::ffi::IceGatheringState;
59 type AudioTrackSource = crate::audio_track::ffi::AudioTrackSource;
60 type VideoTrackSource = crate::video_track::ffi::VideoTrackSource;
61 type RtpCapabilities = crate::rtp_parameters::ffi::RtpCapabilities;
62 type AudioTrack = crate::audio_track::ffi::AudioTrack;
63 type VideoTrack = crate::video_track::ffi::VideoTrack;
64 type MediaStreamPtr = crate::helper::ffi::MediaStreamPtr;
65 type CandidatePtr = crate::helper::ffi::CandidatePtr;
66 type RtpSenderPtr = crate::helper::ffi::RtpSenderPtr;
67 type RtpReceiverPtr = crate::helper::ffi::RtpReceiverPtr;
68 type RtpTransceiverPtr = crate::helper::ffi::RtpTransceiverPtr;
69 type RtcError = crate::rtc_error::ffi::RtcError;
70 type Candidate = crate::candidate::ffi::Candidate;
71 type IceCandidate = crate::jsep::ffi::IceCandidate;
72 type DataChannel = crate::data_channel::ffi::DataChannel;
73 type DataChannelInit = crate::data_channel::ffi::DataChannelInit;
74 type RtpSender = crate::rtp_sender::ffi::RtpSender;
75 type RtpReceiver = crate::rtp_receiver::ffi::RtpReceiver;
76 type RtpTransceiver = crate::rtp_transceiver::ffi::RtpTransceiver;
77 type RtpTransceiverInit = crate::rtp_transceiver::ffi::RtpTransceiverInit;
78 type MediaStream = crate::media_stream::ffi::MediaStream;
79 type MediaStreamTrack = crate::media_stream::ffi::MediaStreamTrack;
80 type SessionDescription = crate::jsep::ffi::SessionDescription;
81 type MediaType = crate::webrtc::ffi::MediaType;
82 }
83
84 unsafe extern "C++" {
85 include!("livekit/peer_connection_factory.h");
86
87 type PeerConnection = crate::peer_connection::ffi::PeerConnection;
88 type PeerConnectionFactory;
89
90 fn create_peer_connection_factory() -> SharedPtr<PeerConnectionFactory>;
91 fn create_peer_connection_factory_with_zero_playout_delay(
92 ) -> SharedPtr<PeerConnectionFactory>;
93
94 fn zero_playout_delay_enabled(self: &PeerConnectionFactory) -> bool;
95
96 fn create_peer_connection(
97 self: &PeerConnectionFactory,
98 config: RtcConfiguration,
99 observer: Box<PeerConnectionObserverWrapper>,
100 ) -> Result<SharedPtr<PeerConnection>>;
101
102 fn create_video_track(
103 self: &PeerConnectionFactory,
104 label: String,
105 source: SharedPtr<VideoTrackSource>,
106 ) -> SharedPtr<VideoTrack>;
107
108 fn create_audio_track(
109 self: &PeerConnectionFactory,
110 label: String,
111 source: SharedPtr<AudioTrackSource>,
112 ) -> SharedPtr<AudioTrack>;
113
114 fn create_device_audio_track(
116 self: &PeerConnectionFactory,
117 label: String,
118 ) -> SharedPtr<AudioTrack>;
119
120 fn rtp_sender_capabilities(
121 self: &PeerConnectionFactory,
122 kind: MediaType,
123 ) -> RtpCapabilities;
124
125 fn rtp_receiver_capabilities(
126 self: &PeerConnectionFactory,
127 kind: MediaType,
128 ) -> RtpCapabilities;
129 }
130
131 extern "Rust" {
132 type PeerConnectionObserverWrapper;
133
134 fn on_signaling_change(self: &PeerConnectionObserverWrapper, new_state: SignalingState);
135 fn on_add_stream(self: &PeerConnectionObserverWrapper, stream: SharedPtr<MediaStream>);
136 fn on_remove_stream(self: &PeerConnectionObserverWrapper, stream: SharedPtr<MediaStream>);
137 fn on_data_channel(
138 self: &PeerConnectionObserverWrapper,
139 data_channel: SharedPtr<DataChannel>,
140 );
141 fn on_renegotiation_needed(self: &PeerConnectionObserverWrapper);
142 fn on_negotiation_needed_event(self: &PeerConnectionObserverWrapper, event: u32);
143 fn on_ice_connection_change(
144 self: &PeerConnectionObserverWrapper,
145 new_state: IceConnectionState,
146 );
147 fn on_standardized_ice_connection_change(
148 self: &PeerConnectionObserverWrapper,
149 new_state: IceConnectionState,
150 );
151 fn on_connection_change(
152 self: &PeerConnectionObserverWrapper,
153 new_state: PeerConnectionState,
154 );
155 fn on_ice_gathering_change(
156 self: &PeerConnectionObserverWrapper,
157 new_state: IceGatheringState,
158 );
159 fn on_ice_candidate(
160 self: &PeerConnectionObserverWrapper,
161 candidate: SharedPtr<IceCandidate>,
162 );
163 fn on_ice_candidate_error(
164 self: &PeerConnectionObserverWrapper,
165 address: String,
166 port: i32,
167 url: String,
168 error_code: i32,
169 error_text: String,
170 );
171 fn on_ice_candidates_removed(
172 self: &PeerConnectionObserverWrapper,
173 removed: Vec<CandidatePtr>,
174 );
175 fn on_ice_connection_receiving_change(
176 self: &PeerConnectionObserverWrapper,
177 receiving: bool,
178 );
179 fn on_ice_selected_candidate_pair_changed(
180 self: &PeerConnectionObserverWrapper,
181 event: CandidatePairChangeEvent,
182 );
183 fn on_add_track(
184 self: &PeerConnectionObserverWrapper,
185 receiver: SharedPtr<RtpReceiver>,
186 streams: Vec<MediaStreamPtr>,
187 );
188 fn on_track(self: &PeerConnectionObserverWrapper, transceiver: SharedPtr<RtpTransceiver>);
189 fn on_remove_track(self: &PeerConnectionObserverWrapper, receiver: SharedPtr<RtpReceiver>);
190 fn on_interesting_usage(self: &PeerConnectionObserverWrapper, usage_pattern: i32);
191 }
192}
193
194impl_thread_safety!(ffi::PeerConnectionFactory, Send + Sync);
195
196pub trait PeerConnectionObserver: Send + Sync {
197 fn on_signaling_change(&self, new_state: ffi::SignalingState);
198 fn on_add_stream(&self, stream: SharedPtr<MediaStream>);
199 fn on_remove_stream(&self, stream: SharedPtr<MediaStream>);
200 fn on_data_channel(&self, data_channel: SharedPtr<DataChannel>);
201 fn on_renegotiation_needed(&self);
202 fn on_negotiation_needed_event(&self, event: u32);
203 fn on_ice_connection_change(&self, new_state: ffi::IceConnectionState);
204 fn on_standardized_ice_connection_change(&self, new_state: ffi::IceConnectionState);
205 fn on_connection_change(&self, new_state: ffi::PeerConnectionState);
206 fn on_ice_gathering_change(&self, new_state: ffi::IceGatheringState);
207 fn on_ice_candidate(&self, candidate: SharedPtr<IceCandidate>);
208 fn on_ice_candidate_error(
209 &self,
210 address: String,
211 port: i32,
212 url: String,
213 error_code: i32,
214 error_text: String,
215 );
216 fn on_ice_candidates_removed(&self, removed: Vec<SharedPtr<Candidate>>);
217 fn on_ice_connection_receiving_change(&self, receiving: bool);
218 fn on_ice_selected_candidate_pair_changed(&self, event: ffi::CandidatePairChangeEvent);
219 fn on_add_track(&self, receiver: SharedPtr<RtpReceiver>, streams: Vec<SharedPtr<MediaStream>>);
220 fn on_track(&self, transceiver: SharedPtr<RtpTransceiver>);
221 fn on_remove_track(&self, receiver: SharedPtr<RtpReceiver>);
222 fn on_interesting_usage(&self, usage_pattern: i32);
223}
224
225pub struct PeerConnectionObserverWrapper {
228 observer: Arc<dyn PeerConnectionObserver>,
229}
230
231impl PeerConnectionObserverWrapper {
232 pub fn new(observer: Arc<dyn PeerConnectionObserver>) -> Self {
233 Self { observer }
234 }
235
236 fn on_signaling_change(&self, new_state: ffi::SignalingState) {
237 self.observer.on_signaling_change(new_state);
238 }
239
240 fn on_add_stream(&self, stream: SharedPtr<MediaStream>) {
241 self.observer.on_add_stream(stream);
242 }
243
244 fn on_remove_stream(&self, stream: SharedPtr<MediaStream>) {
245 self.observer.on_remove_stream(stream);
246 }
247
248 fn on_data_channel(&self, data_channel: SharedPtr<DataChannel>) {
249 self.observer.on_data_channel(data_channel);
250 }
251
252 fn on_renegotiation_needed(&self) {
253 self.observer.on_renegotiation_needed();
254 }
255
256 fn on_negotiation_needed_event(&self, event: u32) {
257 self.observer.on_negotiation_needed_event(event);
258 }
259
260 fn on_ice_connection_change(&self, new_state: ffi::IceConnectionState) {
261 self.observer.on_ice_connection_change(new_state);
262 }
263
264 fn on_standardized_ice_connection_change(&self, new_state: ffi::IceConnectionState) {
265 self.observer.on_standardized_ice_connection_change(new_state);
266 }
267
268 fn on_connection_change(&self, new_state: ffi::PeerConnectionState) {
269 self.observer.on_connection_change(new_state);
270 }
271
272 fn on_ice_gathering_change(&self, new_state: ffi::IceGatheringState) {
273 self.observer.on_ice_gathering_change(new_state);
274 }
275
276 fn on_ice_candidate(&self, candidate: SharedPtr<IceCandidate>) {
277 self.observer.on_ice_candidate(candidate);
278 }
279
280 fn on_ice_candidate_error(
281 &self,
282 address: String,
283 port: i32,
284 url: String,
285 error_code: i32,
286 error_text: String,
287 ) {
288 self.observer.on_ice_candidate_error(address, port, url, error_code, error_text);
289 }
290
291 fn on_ice_candidates_removed(&self, candidates: Vec<ffi::CandidatePtr>) {
292 self.observer.on_ice_candidates_removed(candidates.into_iter().map(|v| v.ptr).collect());
293 }
294
295 fn on_ice_connection_receiving_change(&self, receiving: bool) {
296 self.observer.on_ice_connection_receiving_change(receiving);
297 }
298
299 fn on_ice_selected_candidate_pair_changed(&self, event: ffi::CandidatePairChangeEvent) {
300 self.observer.on_ice_selected_candidate_pair_changed(event);
301 }
302
303 fn on_add_track(&self, receiver: SharedPtr<RtpReceiver>, streams: Vec<ffi::MediaStreamPtr>) {
304 self.observer.on_add_track(receiver, streams.into_iter().map(|v| v.ptr).collect());
305 }
306
307 fn on_track(&self, transceiver: SharedPtr<RtpTransceiver>) {
308 self.observer.on_track(transceiver);
309 }
310
311 fn on_remove_track(&self, receiver: SharedPtr<RtpReceiver>) {
312 self.observer.on_remove_track(receiver);
313 }
314
315 fn on_interesting_usage(&self, usage_pattern: i32) {
316 self.observer.on_interesting_usage(usage_pattern);
317 }
318}