1use std::time::Duration;
2
3use bytes::{Buf, BufMut, Bytes, BytesMut};
4
5use crate::{InvalidInput, RtcpPacket, RtcpPacketType};
6
7#[repr(C, packed)]
9struct RawReportBlock {
10 ssrc: u32,
11 loss: u32,
12 extended_sequence_number: u32,
13 jitter: u32,
14 last_sr_timestamp: u32,
15 delay_since_last_sr: u32,
16}
17
18#[derive(Copy, Clone)]
20pub struct ReportBlock {
21 ssrc: u32,
22 loss: u32,
23 extended_sequence_number: u32,
24 jitter: u32,
25 last_sr_timestamp: u32,
26 delay_since_last_sr: u32,
27}
28
29impl ReportBlock {
30 #[inline]
32 pub const fn new() -> Self {
33 Self {
34 ssrc: 0,
35 loss: 0,
36 extended_sequence_number: 0,
37 jitter: 0,
38 last_sr_timestamp: 0,
39 delay_since_last_sr: 0,
40 }
41 }
42
43 pub fn decode(data: &mut Bytes) -> Result<Self, InvalidInput> {
45 if data.len() < std::mem::size_of::<RawReportBlock>() {
46 return Err(InvalidInput);
47 }
48
49 let ptr = data.as_ptr() as *const RawReportBlock;
50
51 let raw = unsafe { ptr.read_unaligned() };
52
53 let res = Self {
54 ssrc: u32::from_be(raw.ssrc),
55 loss: u32::from_be(raw.loss),
56 extended_sequence_number: u32::from_be(raw.extended_sequence_number),
57 jitter: u32::from_be(raw.jitter),
58 last_sr_timestamp: u32::from_be(raw.last_sr_timestamp),
59 delay_since_last_sr: u32::from_be(raw.delay_since_last_sr),
60 };
61
62 data.advance(std::mem::size_of::<RawReportBlock>());
63
64 Ok(res)
65 }
66
67 pub fn encode(&self, buf: &mut BytesMut) {
69 let raw = RawReportBlock {
70 ssrc: self.ssrc.to_be(),
71 loss: self.loss.to_be(),
72 extended_sequence_number: self.extended_sequence_number.to_be(),
73 jitter: self.jitter.to_be(),
74 last_sr_timestamp: self.last_sr_timestamp.to_be(),
75 delay_since_last_sr: self.delay_since_last_sr.to_be(),
76 };
77
78 let ptr = &raw as *const _ as *const u8;
79
80 let data =
81 unsafe { std::slice::from_raw_parts(ptr, std::mem::size_of::<RawReportBlock>()) };
82
83 buf.extend_from_slice(data);
84 }
85
86 #[inline]
88 pub fn ssrc(&self) -> u32 {
89 self.ssrc
90 }
91
92 #[inline]
94 pub fn with_ssrc(mut self, ssrc: u32) -> Self {
95 self.ssrc = ssrc;
96 self
97 }
98
99 #[inline]
101 pub fn fractional_loss(&self) -> u8 {
102 (self.loss >> 24) as u8
103 }
104
105 #[inline]
107 pub fn with_fractional_loss(mut self, loss: u8) -> Self {
108 self.loss &= 0x00ffffff;
109 self.loss |= (loss as u32) << 24;
110 self
111 }
112
113 #[inline]
115 pub fn cumulative_loss(&self) -> i32 {
116 ((self.loss << 8) as i32) >> 8
117 }
118
119 #[inline]
121 pub fn with_cumulative_loss(mut self, loss: i32) -> Self {
122 let min = -(1i32 << 23);
123 let max = (1i32 << 23) - 1;
124
125 let loss = loss.max(min).min(max) as u32;
126
127 self.loss &= 0xff000000;
128 self.loss |= loss & 0x00ffffff;
129 self
130 }
131
132 #[inline]
134 pub fn extended_sequence_number(&self) -> u32 {
135 self.extended_sequence_number
136 }
137
138 #[inline]
140 pub fn with_extended_sequence_number(mut self, n: u32) -> Self {
141 self.extended_sequence_number = n;
142 self
143 }
144
145 #[inline]
147 pub fn jitter(&self) -> u32 {
148 self.jitter
149 }
150
151 #[inline]
153 pub fn with_jitter(mut self, jitter: u32) -> Self {
154 self.jitter = jitter;
155 self
156 }
157
158 #[inline]
163 pub fn last_sr_timestamp(&self) -> u64 {
164 (self.last_sr_timestamp as u64) << 16
165 }
166
167 #[inline]
172 pub fn with_last_sr_timestamp(mut self, ts: u64) -> Self {
173 self.last_sr_timestamp = (ts >> 16) as u32;
174 self
175 }
176
177 #[inline]
179 pub fn delay_since_last_sr(&self) -> Duration {
180 let secs = (self.delay_since_last_sr >> 16) as u64;
181 let nanos = ((self.delay_since_last_sr & 0xffff) as u64 * 1_000_000_000) >> 16;
182
183 Duration::new(secs, nanos as u32)
184 }
185
186 #[inline]
188 pub fn with_delay_since_last_sr(mut self, delay: Duration) -> Self {
189 let secs = (delay.as_secs() << 16) as u32;
190 let fraction = (((delay.subsec_nanos() as u64) << 16) / 1_000_000_000) as u32;
191
192 self.delay_since_last_sr = secs + fraction;
193 self
194 }
195
196 #[inline]
198 pub fn raw_size(&self) -> usize {
199 std::mem::size_of::<RawReportBlock>()
200 }
201}
202
203impl Default for ReportBlock {
204 #[inline]
205 fn default() -> Self {
206 Self::new()
207 }
208}
209
210#[repr(C, packed)]
212struct RawSenderReportHeader {
213 ssrc: u32,
214 ntp_timestamp: u64,
215 rtp_timestamp: u32,
216 packet_count: u32,
217 octet_count: u32,
218}
219
220#[derive(Clone)]
222pub struct SenderReport {
223 ssrc: u32,
224 ntp_timestamp: u64,
225 rtp_timestamp: u32,
226 packet_count: u32,
227 octet_count: u32,
228 blocks: Vec<ReportBlock>,
229}
230
231impl SenderReport {
232 #[inline]
234 pub const fn new() -> Self {
235 Self {
236 ssrc: 0,
237 ntp_timestamp: 0,
238 rtp_timestamp: 0,
239 packet_count: 0,
240 octet_count: 0,
241 blocks: Vec::new(),
242 }
243 }
244
245 pub fn decode(packet: &RtcpPacket) -> Result<Self, InvalidInput> {
247 let header = packet.header();
248
249 let mut data = packet.stripped_payload();
250
251 if data.len() < std::mem::size_of::<RawSenderReportHeader>() {
252 return Err(InvalidInput);
253 }
254
255 let ptr = data.as_ptr() as *const RawSenderReportHeader;
256
257 let raw = unsafe { ptr.read_unaligned() };
258
259 let mut res = Self {
260 ssrc: u32::from_be(raw.ssrc),
261 ntp_timestamp: u64::from_be(raw.ntp_timestamp),
262 rtp_timestamp: u32::from_be(raw.rtp_timestamp),
263 packet_count: u32::from_be(raw.packet_count),
264 octet_count: u32::from_be(raw.octet_count),
265 blocks: Vec::with_capacity(header.item_count() as usize),
266 };
267
268 data.advance(std::mem::size_of::<RawSenderReportHeader>());
269
270 for _ in 0..header.item_count() {
271 res.blocks.push(ReportBlock::decode(&mut data)?);
272 }
273
274 Ok(res)
275 }
276
277 pub fn encode(&self) -> RtcpPacket {
279 let mut payload = BytesMut::with_capacity(self.raw_size());
280
281 let raw = RawSenderReportHeader {
282 ssrc: self.ssrc.to_be(),
283 ntp_timestamp: self.ntp_timestamp.to_be(),
284 rtp_timestamp: self.rtp_timestamp.to_be(),
285 packet_count: self.packet_count.to_be(),
286 octet_count: self.octet_count.to_be(),
287 };
288
289 let ptr = &raw as *const _ as *const u8;
290
291 let data = unsafe {
292 std::slice::from_raw_parts(ptr, std::mem::size_of::<RawSenderReportHeader>())
293 };
294
295 payload.extend_from_slice(data);
296
297 for block in &self.blocks {
298 block.encode(&mut payload);
299 }
300
301 RtcpPacket::new(RtcpPacketType::SR)
302 .with_item_count(self.blocks.len() as u8)
303 .with_payload(payload.freeze(), 0)
304 }
305
306 #[inline]
308 pub fn ssrc(&self) -> u32 {
309 self.ssrc
310 }
311
312 #[inline]
314 pub fn with_ssrc(mut self, ssrc: u32) -> Self {
315 self.ssrc = ssrc;
316 self
317 }
318
319 #[inline]
321 pub fn ntp_timestamp(&self) -> u64 {
322 self.ntp_timestamp
323 }
324
325 #[inline]
327 pub fn with_ntp_timestamp(mut self, timestamp: u64) -> Self {
328 self.ntp_timestamp = timestamp;
329 self
330 }
331
332 #[inline]
334 pub fn rtp_timestamp(&self) -> u32 {
335 self.rtp_timestamp
336 }
337
338 #[inline]
340 pub fn with_rtp_timestamp(mut self, timestamp: u32) -> Self {
341 self.rtp_timestamp = timestamp;
342 self
343 }
344
345 #[inline]
347 pub fn packet_count(&self) -> u32 {
348 self.packet_count
349 }
350
351 #[inline]
353 pub fn with_packet_count(mut self, count: u32) -> Self {
354 self.packet_count = count;
355 self
356 }
357
358 #[inline]
360 pub fn octet_count(&self) -> u32 {
361 self.octet_count
362 }
363
364 #[inline]
366 pub fn with_octet_count(mut self, count: u32) -> Self {
367 self.octet_count = count;
368 self
369 }
370
371 #[inline]
373 pub fn report_blocks(&self) -> &[ReportBlock] {
374 &self.blocks
375 }
376
377 #[inline]
383 pub fn with_report_blocks<T>(mut self, blocks: T) -> Self
384 where
385 T: Into<Vec<ReportBlock>>,
386 {
387 let blocks = blocks.into();
388
389 assert!(blocks.len() < 32);
390
391 self.blocks = blocks;
392 self
393 }
394
395 #[inline]
397 pub fn raw_size(&self) -> usize {
398 std::mem::size_of::<RawSenderReportHeader>()
399 + std::mem::size_of::<RawReportBlock>() * self.blocks.len()
400 }
401}
402
403impl Default for SenderReport {
404 #[inline]
405 fn default() -> Self {
406 Self::new()
407 }
408}
409
410#[derive(Clone)]
412pub struct ReceiverReport {
413 ssrc: u32,
414 blocks: Vec<ReportBlock>,
415}
416
417impl ReceiverReport {
418 #[inline]
420 pub const fn new() -> Self {
421 Self {
422 ssrc: 0,
423 blocks: Vec::new(),
424 }
425 }
426
427 pub fn decode(packet: &RtcpPacket) -> Result<Self, InvalidInput> {
429 let header = packet.header();
430
431 let mut data = packet.stripped_payload();
432
433 if data.len() < 4 {
434 return Err(InvalidInput);
435 }
436
437 let mut res = Self {
438 ssrc: data.get_u32(),
439 blocks: Vec::with_capacity(header.item_count() as usize),
440 };
441
442 for _ in 0..header.item_count() {
443 res.blocks.push(ReportBlock::decode(&mut data)?);
444 }
445
446 Ok(res)
447 }
448
449 pub fn encode(&self) -> RtcpPacket {
451 let mut payload = BytesMut::with_capacity(self.raw_size());
452
453 payload.put_u32(self.ssrc);
454
455 for block in &self.blocks {
456 block.encode(&mut payload);
457 }
458
459 RtcpPacket::new(RtcpPacketType::RR)
460 .with_item_count(self.blocks.len() as u8)
461 .with_payload(payload.freeze(), 0)
462 }
463
464 #[inline]
466 pub fn ssrc(&self) -> u32 {
467 self.ssrc
468 }
469
470 #[inline]
472 pub fn with_ssrc(mut self, ssrc: u32) -> Self {
473 self.ssrc = ssrc;
474 self
475 }
476
477 #[inline]
479 pub fn report_blocks(&self) -> &[ReportBlock] {
480 &self.blocks
481 }
482
483 #[inline]
489 pub fn with_report_blocks<T>(mut self, blocks: T) -> Self
490 where
491 T: Into<Vec<ReportBlock>>,
492 {
493 let blocks = blocks.into();
494
495 assert!(blocks.len() < 32);
496
497 self.blocks = blocks;
498 self
499 }
500
501 #[inline]
503 pub fn raw_size(&self) -> usize {
504 4 + std::mem::size_of::<RawReportBlock>() * self.blocks.len()
505 }
506}
507
508impl Default for ReceiverReport {
509 #[inline]
510 fn default() -> Self {
511 Self::new()
512 }
513}