1use std::time::Duration;
2
3use bytes::{Buf, BufMut, Bytes, BytesMut};
4use zerocopy::{
5 byteorder::network_endian::{U32, U64},
6 FromBytes, Immutable, IntoBytes, KnownLayout, SizeError, Unaligned,
7};
8
9use crate::{InvalidInput, RtcpPacket, RtcpPacketType};
10
11#[derive(Copy, Clone, KnownLayout, Immutable, Unaligned, IntoBytes, FromBytes)]
13#[repr(C)]
14struct RawReportBlock {
15 ssrc: U32,
16 loss: U32,
17 extended_sequence_number: U32,
18 jitter: U32,
19 last_sr_timestamp: U32,
20 delay_since_last_sr: U32,
21}
22
23#[derive(Copy, Clone)]
25pub struct ReportBlock {
26 ssrc: u32,
27 loss: u32,
28 extended_sequence_number: u32,
29 jitter: u32,
30 last_sr_timestamp: u32,
31 delay_since_last_sr: u32,
32}
33
34impl ReportBlock {
35 pub const RAW_SIZE: usize = std::mem::size_of::<RawReportBlock>();
37
38 #[inline]
40 pub const fn new(ssrc: u32) -> Self {
41 Self {
42 ssrc,
43 loss: 0,
44 extended_sequence_number: 0,
45 jitter: 0,
46 last_sr_timestamp: 0,
47 delay_since_last_sr: 0,
48 }
49 }
50
51 pub fn decode(data: &mut Bytes) -> Result<Self, InvalidInput> {
53 let (raw, _) = RawReportBlock::ref_from_prefix(data)
54 .map_err(SizeError::from)
55 .map_err(|_| InvalidInput::new())?;
56
57 let res = Self {
58 ssrc: raw.ssrc.get(),
59 loss: raw.loss.get(),
60 extended_sequence_number: raw.extended_sequence_number.get(),
61 jitter: raw.jitter.get(),
62 last_sr_timestamp: raw.last_sr_timestamp.get(),
63 delay_since_last_sr: raw.delay_since_last_sr.get(),
64 };
65
66 data.advance(std::mem::size_of::<RawReportBlock>());
67
68 Ok(res)
69 }
70
71 pub fn encode(&self, buf: &mut BytesMut) {
73 let raw = RawReportBlock {
74 ssrc: U32::new(self.ssrc),
75 loss: U32::new(self.loss),
76 extended_sequence_number: U32::new(self.extended_sequence_number),
77 jitter: U32::new(self.jitter),
78 last_sr_timestamp: U32::new(self.last_sr_timestamp),
79 delay_since_last_sr: U32::new(self.delay_since_last_sr),
80 };
81
82 buf.extend_from_slice(raw.as_bytes());
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.clamp(min, max) as u32;
125
126 self.loss &= 0xff000000;
127 self.loss |= loss & 0x00ffffff;
128 self
129 }
130
131 pub fn with_loss(self, expected: u64, received: u64) -> Self {
134 let delta = expected as i64 - received as i64;
135
136 let fraction = if delta < 0 {
137 0
138 } else {
139 ((delta as u64) << 8) / expected
140 };
141
142 self.with_fractional_loss(fraction as u8)
143 .with_cumulative_loss(delta as i32)
144 }
145
146 #[inline]
148 pub fn extended_sequence_number(&self) -> u32 {
149 self.extended_sequence_number
150 }
151
152 #[inline]
154 pub fn with_extended_sequence_number(mut self, n: u32) -> Self {
155 self.extended_sequence_number = n;
156 self
157 }
158
159 #[inline]
161 pub fn jitter(&self) -> u32 {
162 self.jitter
163 }
164
165 #[inline]
167 pub fn with_jitter(mut self, jitter: u32) -> Self {
168 self.jitter = jitter;
169 self
170 }
171
172 #[inline]
177 pub fn last_sr_timestamp(&self) -> u64 {
178 (self.last_sr_timestamp as u64) << 16
179 }
180
181 #[inline]
186 pub fn with_last_sr_timestamp(mut self, ts: u64) -> Self {
187 self.last_sr_timestamp = (ts >> 16) as u32;
188 self
189 }
190
191 #[inline]
193 pub fn delay_since_last_sr(&self) -> Duration {
194 let secs = (self.delay_since_last_sr >> 16) as u64;
195 let nanos = ((self.delay_since_last_sr & 0xffff) as u64 * 1_000_000_000) >> 16;
196
197 Duration::new(secs, nanos as u32)
198 }
199
200 #[inline]
202 pub fn with_delay_since_last_sr(mut self, delay: Duration) -> Self {
203 let secs = (delay.as_secs() << 16) as u32;
204 let fraction = (((delay.subsec_nanos() as u64) << 16) / 1_000_000_000) as u32;
205
206 self.delay_since_last_sr = secs + fraction;
207 self
208 }
209
210 #[inline]
212 pub fn raw_size(&self) -> usize {
213 Self::RAW_SIZE
214 }
215}
216
217#[derive(Copy, Clone, KnownLayout, Immutable, Unaligned, IntoBytes, FromBytes)]
219#[repr(C)]
220struct RawSenderReportHeader {
221 sender_ssrc: U32,
222 ntp_timestamp: U64,
223 rtp_timestamp: U32,
224 packet_count: U32,
225 octet_count: U32,
226}
227
228#[derive(Clone)]
230pub struct SenderReport {
231 sender_ssrc: u32,
232 ntp_timestamp: u64,
233 rtp_timestamp: u32,
234 packet_count: u32,
235 octet_count: u32,
236 report_blocks: Vec<ReportBlock>,
237}
238
239impl SenderReport {
240 #[inline]
242 pub const fn new(sender_ssrc: u32) -> Self {
243 Self {
244 sender_ssrc,
245 ntp_timestamp: 0,
246 rtp_timestamp: 0,
247 packet_count: 0,
248 octet_count: 0,
249 report_blocks: Vec::new(),
250 }
251 }
252
253 pub fn decode(packet: &RtcpPacket) -> Result<Self, InvalidInput> {
255 let header = packet.header();
256
257 let mut data = packet.stripped_payload();
258
259 let (raw, _) = RawSenderReportHeader::ref_from_prefix(&data)
260 .map_err(SizeError::from)
261 .map_err(|_| InvalidInput::new())?;
262
263 let mut res = Self {
264 sender_ssrc: raw.sender_ssrc.get(),
265 ntp_timestamp: raw.ntp_timestamp.get(),
266 rtp_timestamp: raw.rtp_timestamp.get(),
267 packet_count: raw.packet_count.get(),
268 octet_count: raw.octet_count.get(),
269 report_blocks: Vec::with_capacity(header.item_count() as usize),
270 };
271
272 data.advance(std::mem::size_of::<RawSenderReportHeader>());
273
274 for _ in 0..header.item_count() {
275 res.report_blocks.push(ReportBlock::decode(&mut data)?);
276 }
277
278 Ok(res)
279 }
280
281 pub fn encode(&self) -> RtcpPacket {
283 let mut payload = BytesMut::with_capacity(self.raw_size());
284
285 let raw = RawSenderReportHeader {
286 sender_ssrc: U32::new(self.sender_ssrc),
287 ntp_timestamp: U64::new(self.ntp_timestamp),
288 rtp_timestamp: U32::new(self.rtp_timestamp),
289 packet_count: U32::new(self.packet_count),
290 octet_count: U32::new(self.octet_count),
291 };
292
293 payload.extend_from_slice(raw.as_bytes());
294
295 for block in &self.report_blocks {
296 block.encode(&mut payload);
297 }
298
299 RtcpPacket::new(RtcpPacketType::SR)
300 .with_item_count(self.report_blocks.len() as u8)
301 .with_payload(payload.freeze(), 0)
302 }
303
304 #[inline]
306 pub fn sender_ssrc(&self) -> u32 {
307 self.sender_ssrc
308 }
309
310 #[inline]
312 pub fn with_sender_ssrc(mut self, ssrc: u32) -> Self {
313 self.sender_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.report_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.report_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.report_blocks.len()
398 }
399}
400
401#[derive(Clone)]
403pub struct ReceiverReport {
404 sender_ssrc: u32,
405 report_blocks: Vec<ReportBlock>,
406}
407
408impl ReceiverReport {
409 #[inline]
411 pub const fn new(sender_ssrc: u32) -> Self {
412 Self {
413 sender_ssrc,
414 report_blocks: Vec::new(),
415 }
416 }
417
418 pub fn decode(packet: &RtcpPacket) -> Result<Self, InvalidInput> {
420 let header = packet.header();
421
422 let mut data = packet.stripped_payload();
423
424 if data.len() < 4 {
425 return Err(InvalidInput::new());
426 }
427
428 let mut res = Self {
429 sender_ssrc: data.get_u32(),
430 report_blocks: Vec::with_capacity(header.item_count() as usize),
431 };
432
433 for _ in 0..header.item_count() {
434 res.report_blocks.push(ReportBlock::decode(&mut data)?);
435 }
436
437 Ok(res)
438 }
439
440 pub fn encode(&self) -> RtcpPacket {
442 let mut payload = BytesMut::with_capacity(self.raw_size());
443
444 payload.put_u32(self.sender_ssrc);
445
446 for block in &self.report_blocks {
447 block.encode(&mut payload);
448 }
449
450 RtcpPacket::new(RtcpPacketType::RR)
451 .with_item_count(self.report_blocks.len() as u8)
452 .with_payload(payload.freeze(), 0)
453 }
454
455 #[inline]
457 pub fn sender_ssrc(&self) -> u32 {
458 self.sender_ssrc
459 }
460
461 #[inline]
463 pub fn with_sender_ssrc(mut self, ssrc: u32) -> Self {
464 self.sender_ssrc = ssrc;
465 self
466 }
467
468 #[inline]
470 pub fn report_blocks(&self) -> &[ReportBlock] {
471 &self.report_blocks
472 }
473
474 #[inline]
480 pub fn with_report_blocks<T>(mut self, blocks: T) -> Self
481 where
482 T: Into<Vec<ReportBlock>>,
483 {
484 let blocks = blocks.into();
485
486 assert!(blocks.len() < 32);
487
488 self.report_blocks = blocks;
489 self
490 }
491
492 #[inline]
494 pub fn raw_size(&self) -> usize {
495 4 + std::mem::size_of::<RawReportBlock>() * self.report_blocks.len()
496 }
497}