msf_rtp/rtcp/
report.rs

1use std::time::Duration;
2
3use bytes::{Buf, BufMut, Bytes, BytesMut};
4
5use crate::{InvalidInput, RtcpPacket, RtcpPacketType};
6
7/// Helper struct.
8#[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/// Sender/receiver report block.
19#[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    /// Create a new report block.
31    #[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    /// Decode a report block from given data.
44    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    /// Encode the report block.
68    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    /// Get SSRC.
87    #[inline]
88    pub fn ssrc(&self) -> u32 {
89        self.ssrc
90    }
91
92    /// Set SSRC.
93    #[inline]
94    pub fn with_ssrc(mut self, ssrc: u32) -> Self {
95        self.ssrc = ssrc;
96        self
97    }
98
99    /// Get fractional loss as 0.8 fixed point number.
100    #[inline]
101    pub fn fractional_loss(&self) -> u8 {
102        (self.loss >> 24) as u8
103    }
104
105    /// Set fractional loss as 0.8 fixed point number.
106    #[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    /// Get cumulative packet loss (the precision is only up to 24 bits).
114    #[inline]
115    pub fn cumulative_loss(&self) -> i32 {
116        ((self.loss << 8) as i32) >> 8
117    }
118
119    /// Set cumulative packet loss (the precision is only up to 24 bits).
120    #[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    /// Get extended highest sequence number.
133    #[inline]
134    pub fn extended_sequence_number(&self) -> u32 {
135        self.extended_sequence_number
136    }
137
138    /// Set the extended sequence number.
139    #[inline]
140    pub fn with_extended_sequence_number(mut self, n: u32) -> Self {
141        self.extended_sequence_number = n;
142        self
143    }
144
145    /// Get jitter.
146    #[inline]
147    pub fn jitter(&self) -> u32 {
148        self.jitter
149    }
150
151    /// Set the jitter.
152    #[inline]
153    pub fn with_jitter(mut self, jitter: u32) -> Self {
154        self.jitter = jitter;
155        self
156    }
157
158    /// Get NTP timestamp of the last sender report (after truncating to the
159    /// middle 32 bits).
160    ///
161    /// The returned timestamp is a 32.32 fixed point number.
162    #[inline]
163    pub fn last_sr_timestamp(&self) -> u64 {
164        (self.last_sr_timestamp as u64) << 16
165    }
166
167    /// Set NTP timestamp of the last sender report.
168    ///
169    /// The timestamp is expected to be a 32.32 fixed point number and it will
170    /// be truncated to the middle 32 bits.
171    #[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    /// Get delay since the last sender report.
178    #[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    /// Set delay since the last sender report.
187    #[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    /// Get size of the encoded report block.
197    #[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/// Helper struct.
211#[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/// Sender report.
221#[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    /// Create a new sender report.
233    #[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    /// Decode sender report.
246    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    /// Encode the sender report.
278    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    /// Get SSRC identifier of the sender.
307    #[inline]
308    pub fn ssrc(&self) -> u32 {
309        self.ssrc
310    }
311
312    /// Set the SSRC identifier of the sender.
313    #[inline]
314    pub fn with_ssrc(mut self, ssrc: u32) -> Self {
315        self.ssrc = ssrc;
316        self
317    }
318
319    /// Get NTP timestamp as a 32.32 fixed point number.
320    #[inline]
321    pub fn ntp_timestamp(&self) -> u64 {
322        self.ntp_timestamp
323    }
324
325    /// Set the NTP timestamp as a 32.32. fixed point number.
326    #[inline]
327    pub fn with_ntp_timestamp(mut self, timestamp: u64) -> Self {
328        self.ntp_timestamp = timestamp;
329        self
330    }
331
332    /// Get RTP timestamp.
333    #[inline]
334    pub fn rtp_timestamp(&self) -> u32 {
335        self.rtp_timestamp
336    }
337
338    /// Set the RTP timestamp.
339    #[inline]
340    pub fn with_rtp_timestamp(mut self, timestamp: u32) -> Self {
341        self.rtp_timestamp = timestamp;
342        self
343    }
344
345    /// Get packet count.
346    #[inline]
347    pub fn packet_count(&self) -> u32 {
348        self.packet_count
349    }
350
351    /// Set the packet count.
352    #[inline]
353    pub fn with_packet_count(mut self, count: u32) -> Self {
354        self.packet_count = count;
355        self
356    }
357
358    /// Get octet count.
359    #[inline]
360    pub fn octet_count(&self) -> u32 {
361        self.octet_count
362    }
363
364    /// Set the octet count.
365    #[inline]
366    pub fn with_octet_count(mut self, count: u32) -> Self {
367        self.octet_count = count;
368        self
369    }
370
371    /// Get report blocks.
372    #[inline]
373    pub fn report_blocks(&self) -> &[ReportBlock] {
374        &self.blocks
375    }
376
377    /// Set the report blocks.
378    ///
379    /// # Panics
380    /// The method will panic if the number of report blocks is greater than
381    /// 31.
382    #[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    /// Get size of the encoded sender report.
396    #[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/// Receiver report.
411#[derive(Clone)]
412pub struct ReceiverReport {
413    ssrc: u32,
414    blocks: Vec<ReportBlock>,
415}
416
417impl ReceiverReport {
418    /// Create a new receiver report.
419    #[inline]
420    pub const fn new() -> Self {
421        Self {
422            ssrc: 0,
423            blocks: Vec::new(),
424        }
425    }
426
427    /// Decode receiver report.
428    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    /// Encode the sender report.
450    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    /// Get SSRC identifier of the sender.
465    #[inline]
466    pub fn ssrc(&self) -> u32 {
467        self.ssrc
468    }
469
470    /// Set the SSRC identifier of the sender.
471    #[inline]
472    pub fn with_ssrc(mut self, ssrc: u32) -> Self {
473        self.ssrc = ssrc;
474        self
475    }
476
477    /// Get report blocks.
478    #[inline]
479    pub fn report_blocks(&self) -> &[ReportBlock] {
480        &self.blocks
481    }
482
483    /// Set the report blocks.
484    ///
485    /// # Panics
486    /// The method will panic if the number of report blocks is greater than
487    /// 31.
488    #[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    /// Get size of the encoded sender report.
502    #[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}