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