Skip to content
File

Blob: firmware/vendor/str0m/src/rtp/rtcp/rr.rs

rust134 lines
1use super::Ssrc;
2use super::list::private::WordSized;
3use super::{FeedbackMessageType, ReportList, RtcpHeader, RtcpPacket, RtcpType};
4 
5/// A receiver report.
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct ReceiverReport {
8 /// Sender of this feedback. Mostly irrelevant, but part of RTCP packets.
9 pub sender_ssrc: Ssrc,
10 /// The individual reports for received SSRC.
11 pub reports: ReportList<ReceptionReport>,
12}
13 
14/// An individual report of reception.
15#[allow(missing_docs)]
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub struct ReceptionReport {
18 pub ssrc: Ssrc,
19 pub fraction_lost: u8,
20 pub packets_lost: u32, // 24 bit
21 pub max_seq: u32,
22 pub jitter: u32,
23 pub last_sr_time: u32,
24 pub last_sr_delay: u32,
25}
26 
27impl RtcpPacket for ReceiverReport {
28 fn header(&self) -> RtcpHeader {
29 RtcpHeader {
30 rtcp_type: RtcpType::ReceiverReport,
31 feedback_message_type: FeedbackMessageType::ReceptionReport(self.reports.len() as u8),
32 words_less_one: (self.length_words() - 1) as u16,
33 }
34 }
35 
36 fn length_words(&self) -> usize {
37 // * header: 1
38 // * sender SSRC
39 // * reports: x 6
40 1 + 1 + 6 * self.reports.len()
41 }
42 
43 fn write_to(&self, buf: &mut [u8]) -> usize {
44 self.header().write_to(buf);
45 
46 buf[4..8].copy_from_slice(&self.sender_ssrc.to_be_bytes());
47 
48 for (i, r) in self.reports.iter().enumerate() {
49 r.write_to(&mut buf[8 + i * 24..]);
50 }
51 
52 self.length_words() * 4
53 }
54}
55 
56impl WordSized for ReceptionReport {
57 fn word_size(&self) -> usize {
58 6
59 }
60}
61 
62impl ReceptionReport {
63 pub(crate) fn write_to(&self, buf: &mut [u8]) {
64 buf[0..4].copy_from_slice(&self.ssrc.to_be_bytes());
65 buf[4..8].copy_from_slice(&self.packets_lost.to_be_bytes());
66 buf[4] = self.fraction_lost;
67 buf[8..12].copy_from_slice(&self.max_seq.to_be_bytes());
68 buf[12..16].copy_from_slice(&self.jitter.to_be_bytes());
69 buf[16..20].copy_from_slice(&self.last_sr_time.to_be_bytes());
70 buf[20..24].copy_from_slice(&self.last_sr_delay.to_be_bytes());
71 }
72}
73 
74impl<'a> TryFrom<&'a [u8]> for ReceiverReport {
75 type Error = &'static str;
76 
77 fn try_from(buf: &'a [u8]) -> Result<Self, Self::Error> {
78 if buf.len() < 4 {
79 return Err("Less than 4 bytes for ReceiverReport");
80 }
81 
82 let sender_ssrc = u32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]).into();
83 
84 let mut reports = ReportList::new();
85 let mut buf = &buf[4..];
86 
87 let count = buf.len() / 24;
88 
89 let max = count.min(31);
90 
91 for _ in 0..max {
92 let report = buf.try_into()?;
93 reports.push(report);
94 buf = &buf[24..];
95 }
96 
97 Ok(ReceiverReport {
98 sender_ssrc,
99 reports,
100 })
101 }
102}
103 
104impl<'a> TryFrom<&'a [u8]> for ReceptionReport {
105 type Error = &'static str;
106 
107 fn try_from(buf: &'a [u8]) -> Result<Self, Self::Error> {
108 if buf.len() < 24 {
109 return Err("Less than 24 bytes for ReceptionReport");
110 }
111 
112 // Receiver report shape is here
113 // https://www.rfc-editor.org/rfc/rfc3550#section-6.4.2
114 
115 let ssrc = u32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]).into();
116 let fraction_lost = buf[4];
117 let packets_lost = u32::from_be_bytes([0, buf[5], buf[6], buf[7]]);
118 let max_seq = u32::from_be_bytes([buf[8], buf[9], buf[10], buf[11]]);
119 let jitter = u32::from_be_bytes([buf[12], buf[13], buf[14], buf[15]]);
120 let last_sr_time = u32::from_be_bytes([buf[16], buf[17], buf[18], buf[19]]);
121 let last_sr_delay = u32::from_be_bytes([buf[20], buf[21], buf[22], buf[23]]);
122 
123 Ok(ReceptionReport {
124 ssrc,
125 fraction_lost,
126 packets_lost,
127 max_seq,
128 jitter,
129 last_sr_time,
130 last_sr_delay,
131 })
132 }
133}