1use std::collections::HashMap;
16
17use serde::Deserialize;
18
19use crate::data_channel::DataChannelState;
20
21#[derive(Debug, Clone, Deserialize)]
28#[serde(tag = "type")]
29#[serde(rename_all = "kebab-case")]
30pub enum RtcStats {
31 Codec(CodecStats),
32 InboundRtp(InboundRtpStats),
33 OutboundRtp(OutboundRtpStats),
34 RemoteInboundRtp(RemoteInboundRtpStats),
35 RemoteOutboundRtp(RemoteOutboundRtpStats),
36 MediaSource(MediaSourceStats),
37 MediaPlayout(MediaPlayoutStats),
38 PeerConnection(PeerConnectionStats),
39 DataChannel(DataChannelStats),
40 Transport(TransportStats),
41 CandidatePair(CandidatePairStats),
42 LocalCandidate(LocalCandidateStats),
43 RemoteCandidate(RemoteCandidateStats),
44 Certificate(CertificateStats),
45 Stream(StreamStats),
46 Track, }
48
49#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Deserialize)]
50#[serde(rename_all = "lowercase")]
51pub enum QualityLimitationReason {
52 #[default]
53 None,
54 Cpu,
55 Bandwidth,
56 Other,
57}
58
59#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Deserialize)]
60#[serde(rename_all = "lowercase")]
61pub enum IceRole {
62 #[default]
63 Unknown,
64 Controlling,
65 Controlled,
66}
67
68#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)]
69#[serde(rename_all = "lowercase")]
70pub enum DtlsTransportState {
71 New,
72 Connecting,
73 Connected,
74 Closed,
75 Failed,
76}
77
78#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)]
79#[serde(rename_all = "lowercase")]
80pub enum IceTransportState {
81 New,
82 Checking,
83 Connected,
84 Completed,
85 Disconnected,
86 Failed,
87 Closed,
88}
89
90#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Deserialize)]
91#[serde(rename_all = "lowercase")]
92pub enum DtlsRole {
93 Client,
94 Server,
95 #[default]
96 Unknown,
97}
98
99#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)]
100#[serde(rename_all = "kebab-case")]
101pub enum IceCandidatePairState {
102 Frozen,
103 Waiting,
104 InProgress, Failed,
106 Succeeded,
107}
108
109#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)]
110#[serde(rename_all = "lowercase")]
111pub enum IceCandidateType {
112 Host,
113 Srflx,
114 Prflx,
115 Relay,
116}
117
118#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)]
119#[serde(rename_all = "lowercase")]
120pub enum IceServerTransportProtocol {
121 Udp,
122 Tcp,
123 Tls,
124}
125
126#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)]
127#[serde(rename_all = "lowercase")]
128pub enum IceTcpCandidateType {
129 Active,
130 Passive,
131 So,
132}
133
134#[derive(Debug, Default, Clone, Deserialize)]
135pub struct CodecStats {
136 #[serde(flatten)]
137 pub rtc: dictionaries::RtcStats,
138
139 #[serde(flatten)]
140 pub codec: dictionaries::CodecStats,
141}
142
143#[derive(Debug, Default, Clone, Deserialize)]
144pub struct InboundRtpStats {
145 #[serde(flatten)]
146 pub rtc: dictionaries::RtcStats,
147
148 #[serde(flatten)]
149 pub stream: dictionaries::RtpStreamStats,
150
151 #[serde(flatten)]
152 pub received: dictionaries::ReceivedRtpStreamStats,
153
154 #[serde(flatten)]
155 pub inbound: dictionaries::InboundRtpStreamStats,
156}
157
158#[derive(Debug, Default, Clone, Deserialize)]
159pub struct OutboundRtpStats {
160 #[serde(flatten)]
161 pub rtc: dictionaries::RtcStats,
162
163 #[serde(flatten)]
164 pub stream: dictionaries::RtpStreamStats,
165
166 #[serde(flatten)]
167 pub sent: dictionaries::SentRtpStreamStats,
168
169 #[serde(flatten)]
170 pub outbound: dictionaries::OutboundRtpStreamStats,
171}
172
173#[derive(Debug, Default, Clone, Deserialize)]
174pub struct RemoteInboundRtpStats {
175 #[serde(flatten)]
176 pub rtc: dictionaries::RtcStats,
177
178 #[serde(flatten)]
179 pub stream: dictionaries::RtpStreamStats,
180
181 #[serde(flatten)]
182 pub received: dictionaries::ReceivedRtpStreamStats,
183
184 #[serde(flatten)]
185 pub remote_inbound: dictionaries::RemoteInboundRtpStreamStats,
186}
187
188#[derive(Debug, Default, Clone, Deserialize)]
189pub struct RemoteOutboundRtpStats {
190 #[serde(flatten)]
191 pub rtc: dictionaries::RtcStats,
192
193 #[serde(flatten)]
194 pub stream: dictionaries::RtpStreamStats,
195
196 #[serde(flatten)]
197 pub sent: dictionaries::SentRtpStreamStats,
198
199 #[serde(flatten)]
200 pub remote_outbound: dictionaries::RemoteOutboundRtpStreamStats,
201}
202
203#[derive(Debug, Default, Clone, Deserialize)]
204pub struct MediaSourceStats {
205 #[serde(flatten)]
206 pub rtc: dictionaries::RtcStats,
207
208 #[serde(flatten)]
209 pub source: dictionaries::MediaSourceStats,
210
211 #[serde(flatten)]
212 pub audio: dictionaries::AudioSourceStats,
213
214 #[serde(flatten)]
215 pub video: dictionaries::VideoSourceStats,
216}
217
218#[derive(Debug, Default, Clone, Deserialize)]
219pub struct MediaPlayoutStats {
220 #[serde(flatten)]
221 pub rtc: dictionaries::RtcStats,
222
223 #[serde(flatten)]
224 pub audio_playout: dictionaries::AudioPlayoutStats,
225}
226
227#[derive(Debug, Default, Clone, Deserialize)]
228pub struct PeerConnectionStats {
229 #[serde(flatten)]
230 pub rtc: dictionaries::RtcStats,
231
232 #[serde(flatten)]
233 pub pc: dictionaries::PeerConnectionStats,
234}
235
236#[derive(Debug, Default, Clone, Deserialize)]
237pub struct DataChannelStats {
238 #[serde(flatten)]
239 pub rtc: dictionaries::RtcStats,
240
241 #[serde(flatten)]
242 pub dc: dictionaries::DataChannelStats,
243}
244
245#[derive(Debug, Default, Clone, Deserialize)]
246pub struct TransportStats {
247 #[serde(flatten)]
248 pub rtc: dictionaries::RtcStats,
249
250 #[serde(flatten)]
251 pub transport: dictionaries::TransportStats,
252}
253
254#[derive(Debug, Default, Clone, Deserialize)]
255pub struct CandidatePairStats {
256 #[serde(flatten)]
257 pub rtc: dictionaries::RtcStats,
258
259 #[serde(flatten)]
260 pub candidate_pair: dictionaries::CandidatePairStats,
261}
262
263#[derive(Debug, Default, Clone, Deserialize)]
264pub struct LocalCandidateStats {
265 #[serde(flatten)]
266 pub rtc: dictionaries::RtcStats,
267
268 #[serde(flatten)]
269 pub local_candidate: dictionaries::IceCandidateStats,
270}
271
272#[derive(Debug, Default, Clone, Deserialize)]
273pub struct RemoteCandidateStats {
274 #[serde(flatten)]
275 pub rtc: dictionaries::RtcStats,
276
277 #[serde(flatten)]
278 pub remote_candidate: dictionaries::IceCandidateStats,
279}
280
281#[derive(Debug, Default, Clone, Deserialize)]
282pub struct CertificateStats {
283 #[serde(flatten)]
284 pub rtc: dictionaries::RtcStats,
285
286 #[serde(flatten)]
287 pub certificate: dictionaries::CertificateStats,
288}
289
290#[derive(Debug, Default, Clone, Deserialize)]
291pub struct StreamStats {
292 #[serde(flatten)]
293 pub rtc: dictionaries::RtcStats,
294
295 #[serde(flatten)]
296 pub stream: dictionaries::StreamStats,
297}
298
299#[derive(Debug, Default, Clone, Deserialize)]
300pub struct TrackStats {}
301
302pub mod dictionaries {
303 use super::*;
304
305 #[derive(Debug, Default, Clone, Deserialize)]
306 #[serde(rename_all = "camelCase")]
307 #[serde(default)]
308 pub struct RtcStats {
309 pub id: String,
310 pub timestamp: i64,
311 }
312
313 #[derive(Debug, Default, Clone, Deserialize)]
314 #[serde(rename_all = "camelCase")]
315 #[serde(default)]
316 pub struct CodecStats {
317 pub payload_type: u32,
318 pub transport_id: String,
319 pub mime_type: String,
320 pub clock_rate: u32,
321 pub channels: u32,
322 pub sdp_fmtp_line: String,
323 }
324
325 #[derive(Debug, Default, Clone, Deserialize)]
326 #[serde(rename_all = "camelCase")]
327 #[serde(default)]
328 pub struct RtpStreamStats {
329 pub ssrc: u32,
330 pub kind: String,
331 pub transport_id: String,
332 pub codec_id: String,
333 }
334
335 #[derive(Debug, Default, Clone, Deserialize)]
336 #[serde(rename_all = "camelCase")]
337 #[serde(default)]
338 pub struct ReceivedRtpStreamStats {
339 pub packets_received: u64,
340 pub packets_lost: i64,
341 pub jitter: f64,
342 }
343
344 #[derive(Debug, Default, Clone, Deserialize)]
345 #[serde(rename_all = "camelCase")]
346 #[serde(default)]
347 pub struct InboundRtpStreamStats {
348 pub track_identifier: String,
349 pub mid: String,
350 pub remote_id: String,
351 pub frames_decoded: u32,
352 pub key_frames_decoded: u32,
353 pub frames_rendered: u32,
354 pub frames_dropped: u32,
355 pub frame_width: u32,
356 pub frame_height: u32,
357 pub frames_per_second: f64,
358 pub qp_sum: u64,
359 pub total_decode_time: f64,
360 pub total_inter_frame_delay: f64,
361 pub total_squared_inter_frame_delay: f64,
362 pub pause_count: u32,
363 pub total_pause_duration: f64,
364 pub freeze_count: u32,
365 pub total_freeze_duration: f64,
366 pub last_packet_received_timestamp: f64,
367 pub header_bytes_received: u64,
368 pub packets_discarded: u64,
369 pub fec_bytes_received: u64,
370 pub fec_packets_received: u64,
371 pub fec_packets_discarded: u64,
372 pub bytes_received: u64,
373 pub nack_count: u32,
374 pub fir_count: u32,
375 pub pli_count: u32,
376 pub total_processing_delay: f64,
377 pub estimated_playout_timestamp: f64,
378 pub jitter_buffer_delay: f64,
379 pub jitter_buffer_target_delay: f64,
380 pub jitter_buffer_emitted_count: u64,
381 pub jitter_buffer_minimum_delay: f64,
382 pub total_samples_received: u64,
383 pub concealed_samples: u64,
384 pub silent_concealed_samples: u64,
385 pub concealment_events: u64,
386 pub inserted_samples_for_deceleration: u64,
387 pub removed_samples_for_acceleration: u64,
388 pub audio_level: f64,
389 pub total_audio_energy: f64,
390 pub total_samples_duration: f64,
391 pub frames_received: u64,
392 pub decoder_implementation: String,
393 pub playout_id: String,
394 pub power_efficient_decoder: bool,
395 pub frames_assembled_from_multiple_packets: u64,
396 pub total_assembly_time: f64,
397 pub retransmitted_packets_received: u64,
398 pub retransmitted_bytes_received: u64,
399 pub rtx_ssrc: u32,
400 pub fec_ssrc: u32,
401 }
402
403 #[derive(Debug, Default, Clone, Deserialize)]
404 #[serde(rename_all = "camelCase")]
405 #[serde(default)]
406 pub struct SentRtpStreamStats {
407 pub packets_sent: u64,
408 pub bytes_sent: u64,
409 }
410
411 #[derive(Debug, Default, Clone, Deserialize)]
412 #[serde(rename_all = "camelCase")]
413 #[serde(default)]
414 pub struct OutboundRtpStreamStats {
415 pub mid: String,
416 pub media_source_id: String,
417 pub remote_id: String,
418 pub rid: String,
419 pub header_bytes_sent: u64,
420 pub retransmitted_packets_sent: u64,
421 pub retransmitted_bytes_sent: u64,
422 pub rtx_ssrc: u32,
423 pub target_bitrate: f64,
424 pub total_encoded_bytes_target: u64,
425 pub frame_width: u32,
426 pub frame_height: u32,
427 pub frames_per_second: f64,
428 pub frames_sent: u32,
429 pub huge_frames_sent: u32,
430 pub frames_encoded: u32,
431 pub key_frames_encoded: u32,
432 pub qp_sum: u64,
433 pub total_encode_time: f64,
434 pub total_packet_send_delay: f64,
435 pub quality_limitation_reason: QualityLimitationReason,
436 pub quality_limitation_durations: HashMap<String, f64>,
437 pub quality_limitation_resolution_changes: u32,
438 pub nack_count: u32,
439 pub fir_count: u32,
440 pub pli_count: u32,
441 pub encoder_implementation: String,
442 pub power_efficient_encoder: bool,
443 pub active: bool,
444 pub scalibility_mode: String,
445 }
446
447 #[derive(Debug, Default, Clone, Deserialize)]
448 #[serde(rename_all = "camelCase")]
449 #[serde(default)]
450 pub struct RemoteInboundRtpStreamStats {
451 pub local_id: String,
452 pub round_trip_time: f64,
453 pub total_round_trip_time: f64,
454 pub fraction_lost: f64,
455 pub round_trip_time_measurements: u64,
456 }
457
458 #[derive(Debug, Default, Clone, Deserialize)]
459 #[serde(rename_all = "camelCase")]
460 #[serde(default)]
461 pub struct RemoteOutboundRtpStreamStats {
462 pub local_id: String,
463 pub remote_timestamp: f64,
464 pub reports_sent: u64,
465 pub round_trip_time: f64,
466 pub total_round_trip_time: f64,
467 pub round_trip_time_measurements: u64,
468 }
469
470 #[derive(Debug, Default, Clone, Deserialize)]
471 #[serde(rename_all = "camelCase")]
472 #[serde(default)]
473 pub struct MediaSourceStats {
474 pub track_identifier: String,
475 pub kind: String,
476 }
477
478 #[derive(Debug, Default, Clone, Deserialize)]
479 #[serde(rename_all = "camelCase")]
480 #[serde(default)]
481 pub struct AudioSourceStats {
482 pub audio_level: f64,
483 pub total_audio_energy: f64,
484 pub total_samples_duration: f64,
485 pub echo_return_loss: f64,
486 pub echo_return_loss_enhancement: f64,
487 pub dropped_samples_duration: f64,
488 pub dropped_samples_events: u32,
489 pub total_capture_delay: f64,
490 pub total_samples_captured: u64,
491 }
492
493 #[derive(Debug, Default, Clone, Deserialize)]
494 #[serde(rename_all = "camelCase")]
495 #[serde(default)]
496 pub struct VideoSourceStats {
497 pub width: u32,
498 pub height: u32,
499 pub frames: u32,
500 pub frames_per_second: f64,
501 }
502
503 #[derive(Debug, Default, Clone, Deserialize)]
504 #[serde(rename_all = "camelCase")]
505 #[serde(default)]
506 pub struct AudioPlayoutStats {
507 pub kind: String,
508 pub synthesized_samples_duration: f64,
509 pub synthesized_samples_events: u32,
510 pub total_samples_duration: f64,
511 pub total_playout_delay: f64,
512 pub total_samples_count: u64,
513 }
514
515 #[derive(Debug, Default, Clone, Deserialize)]
516 #[serde(rename_all = "camelCase")]
517 #[serde(default)]
518 pub struct PeerConnectionStats {
519 pub data_channels_opened: u32,
520 pub data_channels_closed: u32,
521 }
522
523 #[derive(Debug, Default, Clone, Deserialize)]
524 #[serde(rename_all = "camelCase")]
525 #[serde(default)]
526 pub struct DataChannelStats {
527 pub label: String,
528 pub protocol: String,
529 pub data_channel_identifier: i32,
530 pub state: Option<DataChannelState>,
531 pub messages_sent: u32,
532 pub bytes_sent: u64,
533 pub messages_received: u32,
534 pub bytes_received: u64,
535 }
536
537 #[derive(Debug, Default, Clone, Deserialize)]
538 #[serde(rename_all = "camelCase")]
539 #[serde(default)]
540 pub struct TransportStats {
541 pub packets_sent: u64,
542 pub packets_received: u64,
543 pub bytes_sent: u64,
544 pub bytes_received: u64,
545 pub ice_role: IceRole,
546 pub ice_local_username_fragment: String,
547 pub dtls_state: Option<DtlsTransportState>,
548 pub ice_state: Option<IceTransportState>,
549 pub selected_candidate_pair_id: String,
550 pub local_certificate_id: String,
551 pub remote_certificate_id: String,
552 pub tls_version: String,
553 pub dtls_cipher: String,
554 pub dtls_role: DtlsRole,
555 pub srtp_cipher: String,
556 pub selected_candidate_pair_changes: u32,
557 }
558
559 #[derive(Debug, Default, Clone, Deserialize)]
560 #[serde(rename_all = "camelCase")]
561 #[serde(default)]
562 pub struct CandidatePairStats {
563 pub transport_id: String,
564 pub local_candidate_id: String,
565 pub remote_candidate_id: String,
566 pub state: Option<IceCandidatePairState>,
567 pub nominated: bool,
568 pub packets_sent: u64,
569 pub packets_received: u64,
570 pub bytes_sent: u64,
571 pub bytes_received: u64,
572 pub last_packet_sent_timestamp: f64,
573 pub last_packet_received_timestamp: f64,
574 pub total_round_trip_time: f64,
575 pub current_round_trip_time: f64,
576 pub available_outgoing_bitrate: f64,
577 pub available_incoming_bitrate: f64,
578 pub requests_received: u64,
579 pub requests_sent: u64,
580 pub responses_received: u64,
581 pub responses_sent: u64,
582 pub consent_requests_sent: u64,
583 pub packets_discarded_on_send: u32,
584 pub bytes_discarded_on_send: u64,
585 }
586
587 #[derive(Debug, Default, Clone, Deserialize)]
588 #[serde(rename_all = "camelCase")]
589 #[serde(default)]
590 pub struct IceCandidateStats {
591 pub transport_id: String,
592 pub address: String,
593 pub port: i32,
594 pub protocol: String,
595 pub candidate_type: Option<IceCandidateType>,
596 pub priority: i32,
597 pub url: String,
598 pub relay_protocol: Option<IceServerTransportProtocol>,
599 pub foundation: String,
600 pub related_address: String,
601 pub related_port: i32,
602 pub username_fragment: String,
603 pub tcp_type: Option<IceTcpCandidateType>,
604 }
605
606 #[derive(Debug, Default, Clone, Deserialize)]
607 #[serde(rename_all = "camelCase")]
608 #[serde(default)]
609 pub struct CertificateStats {
610 pub fingerprint: String,
611 pub fingerprint_algorithm: String,
612 pub base64_certificate: String,
613 pub issuer_certificate_id: String,
614 }
615
616 #[derive(Debug, Default, Clone, Deserialize)]
617 #[serde(rename_all = "camelCase")]
618 #[serde(default)]
619 pub struct StreamStats {
620 pub id: String,
621 pub stream_identifier: String,
622 }
624}