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