1use std::time::Duration;
2
3use bytes::{Buf, BufMut, Bytes, BytesMut};
4
5use crate::{InvalidInput, RtcpPacket, RtcpPacketType};
6
7#[repr(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 let raw = unsafe { &*ptr };
51
52 let res = Self {
53 ssrc: u32::from_be(raw.ssrc),
54 loss: u32::from_be(raw.loss),
55 extended_sequence_number: u32::from_be(raw.extended_sequence_number),
56 jitter: u32::from_be(raw.jitter),
57 last_sr_timestamp: u32::from_be(raw.last_sr_timestamp),
58 delay_since_last_sr: u32::from_be(raw.delay_since_last_sr),
59 };
60
61 data.advance(std::mem::size_of::<RawReportBlock>());
62
63 Ok(res)
64 }
65
66 pub fn encode(&self, buf: &mut BytesMut) {
68 let raw = RawReportBlock {
69 ssrc: self.ssrc.to_be(),
70 loss: self.loss.to_be(),
71 extended_sequence_number: self.extended_sequence_number.to_be(),
72 jitter: self.jitter.to_be(),
73 last_sr_timestamp: self.last_sr_timestamp.to_be(),
74 delay_since_last_sr: self.delay_since_last_sr.to_be(),
75 };
76
77 let ptr = &raw as *const _ as *const u8;
78
79 let data =
80 unsafe { std::slice::from_raw_parts(ptr, std::mem::size_of::<RawReportBlock>()) };
81
82 buf.extend_from_slice(data);
83 }
84
85 #[inline]
87 pub fn ssrc(&self) -> u32 {
88 self.ssrc
89 }
90
91 #[inline]
93 pub fn with_ssrc(mut self, ssrc: u32) -> Self {
94 self.ssrc = ssrc;
95 self
96 }
97
98 #[inline]
100 pub fn fractional_loss(&self) -> u8 {
101 (self.loss >> 24) as u8
102 }
103
104 #[inline]
106 pub fn with_fractional_loss(mut self, loss: u8) -> Self {
107 self.loss &= 0x00ffffff;
108 self.loss |= (loss as u32) << 24;
109 self
110 }
111
112 #[inline]
114 pub fn cumulative_loss(&self) -> i32 {
115 ((self.loss << 8) as i32) >> 8
116 }
117
118 #[inline]
120 pub fn with_cumulative_loss(mut self, loss: i32) -> Self {
121 let min = -(1i32 << 23);
122 let max = (1i32 << 23) - 1;
123
124 let loss = loss.max(min).min(max) as u32;
125
126 self.loss &= 0xff000000;
127 self.loss |= loss & 0x00ffffff;
128 self
129 }
130
131 #[inline]
133 pub fn extended_sequence_number(&self) -> u32 {
134 self.extended_sequence_number
135 }
136
137 #[inline]
139 pub fn with_extended_sequence_number(mut self, n: u32) -> Self {
140 self.extended_sequence_number = n;
141 self
142 }
143
144 #[inline]
146 pub fn jitter(&self) -> u32 {
147 self.jitter
148 }
149
150 #[inline]
152 pub fn with_jitter(mut self, jitter: u32) -> Self {
153 self.jitter = jitter;
154 self
155 }
156
157 #[inline]
162 pub fn last_sr_timestamp(&self) -> u64 {
163 (self.last_sr_timestamp as u64) << 16
164 }
165
166 #[inline]
171 pub fn with_last_sr_timestamp(mut self, ts: u64) -> Self {
172 self.last_sr_timestamp = (ts >> 16) as u32;
173 self
174 }
175
176 #[inline]
178 pub fn delay_since_last_sr(&self) -> Duration {
179 let secs = (self.delay_since_last_sr >> 16) as u64;
180 let nanos = ((self.delay_since_last_sr & 0xffff) as u64 * 1_000_000_000) >> 16;
181
182 Duration::new(secs, nanos as u32)
183 }
184
185 #[inline]
187 pub fn with_delay_since_last_sr(mut self, delay: Duration) -> Self {
188 let secs = (delay.as_secs() << 16) as u32;
189 let fraction = (((delay.subsec_nanos() as u64) << 16) / 1_000_000_000) as u32;
190
191 self.delay_since_last_sr = secs + fraction;
192 self
193 }
194
195 #[inline]
197 pub fn raw_size(&self) -> usize {
198 std::mem::size_of::<RawReportBlock>()
199 }
200}
201
202impl Default for ReportBlock {
203 #[inline]
204 fn default() -> Self {
205 Self::new()
206 }
207}
208
209#[repr(packed)]
211struct RawSenderReportHeader {
212 ssrc: u32,
213 ntp_timestamp: u64,
214 rtp_timestamp: u32,
215 packet_count: u32,
216 octet_count: u32,
217}
218
219#[derive(Clone)]
221pub struct SenderReport {
222 ssrc: u32,
223 ntp_timestamp: u64,
224 rtp_timestamp: u32,
225 packet_count: u32,
226 octet_count: u32,
227 blocks: Vec<ReportBlock>,
228}
229
230impl SenderReport {
231 #[inline]
233 pub const fn new() -> Self {
234 Self {
235 ssrc: 0,
236 ntp_timestamp: 0,
237 rtp_timestamp: 0,
238 packet_count: 0,
239 octet_count: 0,
240 blocks: Vec::new(),
241 }
242 }
243
244 pub fn decode(packet: &RtcpPacket) -> Result<Self, InvalidInput> {
246 let header = packet.header();
247
248 let mut data = packet.stripped_payload();
249
250 if data.len() < std::mem::size_of::<RawSenderReportHeader>() {
251 return Err(InvalidInput);
252 }
253
254 let ptr = data.as_ptr() as *const RawSenderReportHeader;
255 let raw = unsafe { &*ptr };
256
257 let mut res = Self {
258 ssrc: u32::from_be(raw.ssrc),
259 ntp_timestamp: u64::from_be(raw.ntp_timestamp),
260 rtp_timestamp: u32::from_be(raw.rtp_timestamp),
261 packet_count: u32::from_be(raw.packet_count),
262 octet_count: u32::from_be(raw.octet_count),
263 blocks: Vec::with_capacity(header.item_count() as usize),
264 };
265
266 data.advance(std::mem::size_of::<RawSenderReportHeader>());
267
268 for _ in 0..header.item_count() {
269 res.blocks.push(ReportBlock::decode(&mut data)?);
270 }
271
272 Ok(res)
273 }
274
275 pub fn encode(&self) -> RtcpPacket {
277 let mut payload = BytesMut::with_capacity(self.raw_size());
278
279 let raw = RawSenderReportHeader {
280 ssrc: self.ssrc.to_be(),
281 ntp_timestamp: self.ntp_timestamp.to_be(),
282 rtp_timestamp: self.rtp_timestamp.to_be(),
283 packet_count: self.packet_count.to_be(),
284 octet_count: self.octet_count.to_be(),
285 };
286
287 let ptr = &raw as *const _ as *const u8;
288
289 let data = unsafe {
290 std::slice::from_raw_parts(ptr, std::mem::size_of::<RawSenderReportHeader>())
291 };
292
293 payload.extend_from_slice(data);
294
295 for block in &self.blocks {
296 block.encode(&mut payload);
297 }
298
299 RtcpPacket::new(RtcpPacketType::SR)
300 .with_item_count(self.blocks.len() as u8)
301 .with_payload(payload.freeze(), 0)
302 }
303
304 #[inline]
306 pub fn ssrc(&self) -> u32 {
307 self.ssrc
308 }
309
310 #[inline]
312 pub fn with_ssrc(mut self, ssrc: u32) -> Self {
313 self.ssrc = ssrc;
314 self
315 }
316
317 #[inline]
319 pub fn ntp_timestamp(&self) -> u64 {
320 self.ntp_timestamp
321 }
322
323 #[inline]
325 pub fn with_ntp_timestamp(mut self, timestamp: u64) -> Self {
326 self.ntp_timestamp = timestamp;
327 self
328 }
329
330 #[inline]
332 pub fn rtp_timestamp(&self) -> u32 {
333 self.rtp_timestamp
334 }
335
336 #[inline]
338 pub fn with_rtp_timestamp(mut self, timestamp: u32) -> Self {
339 self.rtp_timestamp = timestamp;
340 self
341 }
342
343 #[inline]
345 pub fn packet_count(&self) -> u32 {
346 self.packet_count
347 }
348
349 #[inline]
351 pub fn with_packet_count(mut self, count: u32) -> Self {
352 self.packet_count = count;
353 self
354 }
355
356 #[inline]
358 pub fn octet_count(&self) -> u32 {
359 self.octet_count
360 }
361
362 #[inline]
364 pub fn with_octet_count(mut self, count: u32) -> Self {
365 self.octet_count = count;
366 self
367 }
368
369 #[inline]
371 pub fn report_blocks(&self) -> &[ReportBlock] {
372 &self.blocks
373 }
374
375 #[inline]
381 pub fn with_report_blocks<T>(mut self, blocks: T) -> Self
382 where
383 T: Into<Vec<ReportBlock>>,
384 {
385 let blocks = blocks.into();
386
387 assert!(blocks.len() < 32);
388
389 self.blocks = blocks;
390 self
391 }
392
393 #[inline]
395 pub fn raw_size(&self) -> usize {
396 std::mem::size_of::<RawSenderReportHeader>()
397 + std::mem::size_of::<RawReportBlock>() * self.blocks.len()
398 }
399}
400
401impl Default for SenderReport {
402 #[inline]
403 fn default() -> Self {
404 Self::new()
405 }
406}
407
408#[derive(Clone)]
410pub struct ReceiverReport {
411 ssrc: u32,
412 blocks: Vec<ReportBlock>,
413}
414
415impl ReceiverReport {
416 #[inline]
418 pub const fn new() -> Self {
419 Self {
420 ssrc: 0,
421 blocks: Vec::new(),
422 }
423 }
424
425 pub fn decode(packet: &RtcpPacket) -> Result<Self, InvalidInput> {
427 let header = packet.header();
428
429 let mut data = packet.stripped_payload();
430
431 if data.len() < 4 {
432 return Err(InvalidInput);
433 }
434
435 let mut res = Self {
436 ssrc: data.get_u32(),
437 blocks: Vec::with_capacity(header.item_count() as usize),
438 };
439
440 for _ in 0..header.item_count() {
441 res.blocks.push(ReportBlock::decode(&mut data)?);
442 }
443
444 Ok(res)
445 }
446
447 pub fn encode(&self) -> RtcpPacket {
449 let mut payload = BytesMut::with_capacity(self.raw_size());
450
451 payload.put_u32(self.ssrc);
452
453 for block in &self.blocks {
454 block.encode(&mut payload);
455 }
456
457 RtcpPacket::new(RtcpPacketType::RR)
458 .with_item_count(self.blocks.len() as u8)
459 .with_payload(payload.freeze(), 0)
460 }
461
462 #[inline]
464 pub fn ssrc(&self) -> u32 {
465 self.ssrc
466 }
467
468 #[inline]
470 pub fn with_ssrc(mut self, ssrc: u32) -> Self {
471 self.ssrc = ssrc;
472 self
473 }
474
475 #[inline]
477 pub fn report_blocks(&self) -> &[ReportBlock] {
478 &self.blocks
479 }
480
481 #[inline]
487 pub fn with_report_blocks<T>(mut self, blocks: T) -> Self
488 where
489 T: Into<Vec<ReportBlock>>,
490 {
491 let blocks = blocks.into();
492
493 assert!(blocks.len() < 32);
494
495 self.blocks = blocks;
496 self
497 }
498
499 #[inline]
501 pub fn raw_size(&self) -> usize {
502 4 + std::mem::size_of::<RawReportBlock>() * self.blocks.len()
503 }
504}
505
506impl Default for ReceiverReport {
507 #[inline]
508 fn default() -> Self {
509 Self::new()
510 }
511}