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
92 fn create_peer_connection(
93 self: &PeerConnectionFactory,
94 config: RtcConfiguration,
95 observer: Box<PeerConnectionObserverWrapper>,
96 ) -> Result<SharedPtr<PeerConnection>>;
97
98 fn create_video_track(
99 self: &PeerConnectionFactory,
100 label: String,
101 source: SharedPtr<VideoTrackSource>,
102 ) -> SharedPtr<VideoTrack>;
103
104 fn create_audio_track(
105 self: &PeerConnectionFactory,
106 label: String,
107 source: SharedPtr<AudioTrackSource>,
108 ) -> SharedPtr<AudioTrack>;
109
110 fn create_device_audio_track(
112 self: &PeerConnectionFactory,
113 label: String,
114 ) -> SharedPtr<AudioTrack>;
115
116 fn rtp_sender_capabilities(
117 self: &PeerConnectionFactory,
118 kind: MediaType,
119 ) -> RtpCapabilities;
120
121 fn rtp_receiver_capabilities(
122 self: &PeerConnectionFactory,
123 kind: MediaType,
124 ) -> RtpCapabilities;
125 }
126
127 extern "Rust" {
128 type PeerConnectionObserverWrapper;
129
130 fn on_signaling_change(self: &PeerConnectionObserverWrapper, new_state: SignalingState);
131 fn on_add_stream(self: &PeerConnectionObserverWrapper, stream: SharedPtr<MediaStream>);
132 fn on_remove_stream(self: &PeerConnectionObserverWrapper, stream: SharedPtr<MediaStream>);
133 fn on_data_channel(
134 self: &PeerConnectionObserverWrapper,
135 data_channel: SharedPtr<DataChannel>,
136 );
137 fn on_renegotiation_needed(self: &PeerConnectionObserverWrapper);
138 fn on_negotiation_needed_event(self: &PeerConnectionObserverWrapper, event: u32);
139 fn on_ice_connection_change(
140 self: &PeerConnectionObserverWrapper,
141 new_state: IceConnectionState,
142 );
143 fn on_standardized_ice_connection_change(
144 self: &PeerConnectionObserverWrapper,
145 new_state: IceConnectionState,
146 );
147 fn on_connection_change(
148 self: &PeerConnectionObserverWrapper,
149 new_state: PeerConnectionState,
150 );
151 fn on_ice_gathering_change(
152 self: &PeerConnectionObserverWrapper,
153 new_state: IceGatheringState,
154 );
155 fn on_ice_candidate(
156 self: &PeerConnectionObserverWrapper,
157 candidate: SharedPtr<IceCandidate>,
158 );
159 fn on_ice_candidate_error(
160 self: &PeerConnectionObserverWrapper,
161 address: String,
162 port: i32,
163 url: String,
164 error_code: i32,
165 error_text: String,
166 );
167 fn on_ice_candidates_removed(
168 self: &PeerConnectionObserverWrapper,
169 removed: Vec<CandidatePtr>,
170 );
171 fn on_ice_connection_receiving_change(
172 self: &PeerConnectionObserverWrapper,
173 receiving: bool,
174 );
175 fn on_ice_selected_candidate_pair_changed(
176 self: &PeerConnectionObserverWrapper,
177 event: CandidatePairChangeEvent,
178 );
179 fn on_add_track(
180 self: &PeerConnectionObserverWrapper,
181 receiver: SharedPtr<RtpReceiver>,
182 streams: Vec<MediaStreamPtr>,
183 );
184 fn on_track(self: &PeerConnectionObserverWrapper, transceiver: SharedPtr<RtpTransceiver>);
185 fn on_remove_track(self: &PeerConnectionObserverWrapper, receiver: SharedPtr<RtpReceiver>);
186 fn on_interesting_usage(self: &PeerConnectionObserverWrapper, usage_pattern: i32);
187 }
188}
189
190impl_thread_safety!(ffi::PeerConnectionFactory, Send + Sync);
191
192pub trait PeerConnectionObserver: Send + Sync {
193 fn on_signaling_change(&self, new_state: ffi::SignalingState);
194 fn on_add_stream(&self, stream: SharedPtr<MediaStream>);
195 fn on_remove_stream(&self, stream: SharedPtr<MediaStream>);
196 fn on_data_channel(&self, data_channel: SharedPtr<DataChannel>);
197 fn on_renegotiation_needed(&self);
198 fn on_negotiation_needed_event(&self, event: u32);
199 fn on_ice_connection_change(&self, new_state: ffi::IceConnectionState);
200 fn on_standardized_ice_connection_change(&self, new_state: ffi::IceConnectionState);
201 fn on_connection_change(&self, new_state: ffi::PeerConnectionState);
202 fn on_ice_gathering_change(&self, new_state: ffi::IceGatheringState);
203 fn on_ice_candidate(&self, candidate: SharedPtr<IceCandidate>);
204 fn on_ice_candidate_error(
205 &self,
206 address: String,
207 port: i32,
208 url: String,
209 error_code: i32,
210 error_text: String,
211 );
212 fn on_ice_candidates_removed(&self, removed: Vec<SharedPtr<Candidate>>);
213 fn on_ice_connection_receiving_change(&self, receiving: bool);
214 fn on_ice_selected_candidate_pair_changed(&self, event: ffi::CandidatePairChangeEvent);
215 fn on_add_track(&self, receiver: SharedPtr<RtpReceiver>, streams: Vec<SharedPtr<MediaStream>>);
216 fn on_track(&self, transceiver: SharedPtr<RtpTransceiver>);
217 fn on_remove_track(&self, receiver: SharedPtr<RtpReceiver>);
218 fn on_interesting_usage(&self, usage_pattern: i32);
219}
220
221pub struct PeerConnectionObserverWrapper {
224 observer: Arc<dyn PeerConnectionObserver>,
225}
226
227impl PeerConnectionObserverWrapper {
228 pub fn new(observer: Arc<dyn PeerConnectionObserver>) -> Self {
229 Self { observer }
230 }
231
232 fn on_signaling_change(&self, new_state: ffi::SignalingState) {
233 self.observer.on_signaling_change(new_state);
234 }
235
236 fn on_add_stream(&self, stream: SharedPtr<MediaStream>) {
237 self.observer.on_add_stream(stream);
238 }
239
240 fn on_remove_stream(&self, stream: SharedPtr<MediaStream>) {
241 self.observer.on_remove_stream(stream);
242 }
243
244 fn on_data_channel(&self, data_channel: SharedPtr<DataChannel>) {
245 self.observer.on_data_channel(data_channel);
246 }
247
248 fn on_renegotiation_needed(&self) {
249 self.observer.on_renegotiation_needed();
250 }
251
252 fn on_negotiation_needed_event(&self, event: u32) {
253 self.observer.on_negotiation_needed_event(event);
254 }
255
256 fn on_ice_connection_change(&self, new_state: ffi::IceConnectionState) {
257 self.observer.on_ice_connection_change(new_state);
258 }
259
260 fn on_standardized_ice_connection_change(&self, new_state: ffi::IceConnectionState) {
261 self.observer.on_standardized_ice_connection_change(new_state);
262 }
263
264 fn on_connection_change(&self, new_state: ffi::PeerConnectionState) {
265 self.observer.on_connection_change(new_state);
266 }
267
268 fn on_ice_gathering_change(&self, new_state: ffi::IceGatheringState) {
269 self.observer.on_ice_gathering_change(new_state);
270 }
271
272 fn on_ice_candidate(&self, candidate: SharedPtr<IceCandidate>) {
273 self.observer.on_ice_candidate(candidate);
274 }
275
276 fn on_ice_candidate_error(
277 &self,
278 address: String,
279 port: i32,
280 url: String,
281 error_code: i32,
282 error_text: String,
283 ) {
284 self.observer.on_ice_candidate_error(address, port, url, error_code, error_text);
285 }
286
287 fn on_ice_candidates_removed(&self, candidates: Vec<ffi::CandidatePtr>) {
288 self.observer.on_ice_candidates_removed(candidates.into_iter().map(|v| v.ptr).collect());
289 }
290
291 fn on_ice_connection_receiving_change(&self, receiving: bool) {
292 self.observer.on_ice_connection_receiving_change(receiving);
293 }
294
295 fn on_ice_selected_candidate_pair_changed(&self, event: ffi::CandidatePairChangeEvent) {
296 self.observer.on_ice_selected_candidate_pair_changed(event);
297 }
298
299 fn on_add_track(&self, receiver: SharedPtr<RtpReceiver>, streams: Vec<ffi::MediaStreamPtr>) {
300 self.observer.on_add_track(receiver, streams.into_iter().map(|v| v.ptr).collect());
301 }
302
303 fn on_track(&self, transceiver: SharedPtr<RtpTransceiver>) {
304 self.observer.on_track(transceiver);
305 }
306
307 fn on_remove_track(&self, receiver: SharedPtr<RtpReceiver>) {
308 self.observer.on_remove_track(receiver);
309 }
310
311 fn on_interesting_usage(&self, usage_pattern: i32) {
312 self.observer.on_interesting_usage(usage_pattern);
313 }
314}