Skip to content
File

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

rust311 lines
1use crate::rtp::Ssrc;
2 
3use super::RtcpType;
4use super::{FeedbackMessageType, PayloadType, RtcpHeader, RtcpPacket};
5 
6const BITRATE_MAX: f32 = 2.417_842_4e24; //0x3FFFFp+63;
7const MANTISSA_MAX: u32 = 0x7FFFFF;
8const REMB_OFFSET: usize = 16;
9 
10const UNIQUE_IDENTIFIER: [u8; 4] = *b"REMB";
11 
12/*
13 0 1 2 3
14 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
15 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16 |V=2|P| FMT=15 | PT=206 | length |
17 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
18 | SSRC of packet sender |
19 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20 | SSRC of media source |
21 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
22 | Unique identifier 'R' 'E' 'M' 'B' |
23 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24 | Num SSRC | BR Exp | BR Mantissa |
25 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
26 | SSRC feedback |
27 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
28 | ... |
29*/
30 
31#[derive(Debug, Clone)]
32pub struct Remb {
33 /// SSRC of sender
34 pub sender_ssrc: Ssrc,
35 
36 /// SSRC of source, in Remb is default 0
37 pub ssrc: Ssrc,
38 
39 /// Estimated maximum bitrate
40 pub bitrate: f32,
41 
42 /// SSRC entries which this packet applies to
43 pub ssrcs: Vec<u32>,
44}
45 
46impl Eq for Remb {}
47impl PartialEq for Remb {
48 fn eq(&self, other: &Self) -> bool {
49 self.sender_ssrc == other.sender_ssrc
50 && (self.bitrate as u64) == (other.bitrate as u64)
51 && self.ssrcs == other.ssrcs
52 }
53}
54 
55impl RtcpPacket for Remb {
56 fn header(&self) -> RtcpHeader {
57 RtcpHeader {
58 rtcp_type: RtcpType::PayloadSpecificFeedback,
59 feedback_message_type: FeedbackMessageType::PayloadFeedback(
60 PayloadType::ApplicationLayer,
61 ),
62 words_less_one: (self.length_words() - 1) as u16,
63 }
64 }
65 
66 fn length_words(&self) -> usize {
67 // header
68 // remb
69 // ssrcs
70 1 + REMB_OFFSET / 4 + self.ssrcs.len()
71 }
72 
73 fn write_to(&self, buf: &mut [u8]) -> usize {
74 let mut exp = 0;
75 let mut bitrate = self.bitrate.clamp(0.0, BITRATE_MAX);
76 
77 while bitrate >= (1 << 18) as f32 {
78 bitrate /= 2.0;
79 exp += 1;
80 }
81 
82 let mantissa = bitrate.floor() as u32;
83 
84 self.header().write_to(&mut buf[..4]);
85 buf[4..8].copy_from_slice(&self.sender_ssrc.to_be_bytes());
86 buf[8..12].copy_from_slice(&[0; 4]);
87 buf[12..16].copy_from_slice(&UNIQUE_IDENTIFIER);
88 buf[16] = self.ssrcs.len() as u8;
89 // We can't quite use the binary package because
90 // a) it's a uint24 and b) the exponent is only 6-bits
91 // Just trust me; this is big-endian encoding.
92 buf[17] = (exp << 2) as u8 | (mantissa >> 16) as u8;
93 buf[18] = (mantissa >> 8) as u8;
94 buf[19] = mantissa as u8;
95 
96 // Write the SSRCs at the very end.
97 for (index, ssrc) in self.ssrcs.iter().enumerate() {
98 let begin = 4 + REMB_OFFSET + index * 4;
99 let end = begin + 4;
100 buf[begin..end].copy_from_slice(&ssrc.to_be_bytes());
101 }
102 
103 4 + REMB_OFFSET + self.ssrcs.len() * 4
104 }
105}
106 
107impl<'a> TryFrom<&'a [u8]> for Remb {
108 type Error = &'static str;
109 
110 fn try_from(buf: &'a [u8]) -> Result<Self, Self::Error> {
111 if buf.len() < 16 {
112 return Err("Remb less than 16 bytes");
113 }
114 
115 let sender_ssrc = u32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]).into();
116 let media_ssrc = u32::from_be_bytes([buf[4], buf[5], buf[6], buf[7]]);
117 if media_ssrc != 0 {
118 return Err("Ssrc must be zero");
119 }
120 
121 if buf[8] != UNIQUE_IDENTIFIER[0]
122 || buf[9] != UNIQUE_IDENTIFIER[1]
123 || buf[10] != UNIQUE_IDENTIFIER[2]
124 || buf[11] != UNIQUE_IDENTIFIER[3]
125 {
126 return Err("Missing remb identifier");
127 }
128 
129 // The next byte is the number of SSRC entries at the end.
130 let ssrcs_len = buf[12] as usize;
131 
132 // Get the 6-bit exponent value.
133 let b17 = buf[13];
134 let mut exp = (b17 as u64) >> 2;
135 exp += 127; // bias for IEEE754
136 exp += 23; // IEEE754 biases the decimal to the left, abs-send-time biases it to the right
137 
138 // The remaining 2-bits plus the next 16-bits are the mantissa.
139 let b18 = buf[14];
140 let b19 = buf[15];
141 let mut mantissa = ((b17 & 3) as u32) << 16 | (b18 as u32) << 8 | b19 as u32;
142 
143 if mantissa != 0 {
144 // ieee754 requires an implicit leading bit
145 while (mantissa & (MANTISSA_MAX + 1)) == 0 {
146 exp -= 1;
147 mantissa *= 2;
148 }
149 }
150 
151 // bitrate = mantissa * 2^exp
152 let bitrate = f32::from_bits(((exp as u32) << 23) | (mantissa & MANTISSA_MAX));
153 
154 // `ssrcs_len` is attacker-controlled byte (buf[12], 0..=255)
155 // reject packets too short to hold that many trailing SSRC bytes.
156 if buf.len() < REMB_OFFSET + ssrcs_len * 4 {
157 return Err("Remb ssrcs length exceeds buffer");
158 }
159 
160 let mut ssrcs = vec![];
161 for i in 0..ssrcs_len {
162 let b_index = 16 + i * 4;
163 ssrcs.push(u32::from_be_bytes([
164 buf[b_index],
165 buf[b_index + 1],
166 buf[b_index + 2],
167 buf[b_index + 3],
168 ]));
169 }
170 
171 Ok(Remb {
172 sender_ssrc,
173 ssrc: 0.into(),
174 ssrcs,
175 bitrate,
176 })
177 }
178}
179 
180#[cfg(test)]
181mod tests {
182 use super::*;
183 
184 #[test]
185 fn test_receiver_estimated_maximum_bitrate_marshal() {
186 let input = Remb {
187 sender_ssrc: 1.into(),
188 ssrc: 0.into(),
189 bitrate: 8927168.0,
190 ssrcs: vec![1215622422],
191 };
192 
193 let expected = [
194 143, 206, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 82, 69, 77, 66, 1, 26, 32, 223, 72, 116, 237,
195 22,
196 ];
197 
198 let mut output = [0; 1500];
199 let len = input.write_to(&mut output);
200 assert_eq!(expected, output[0..len]);
201 }
202 
203 #[test]
204 fn test_receiver_estimated_maximum_bitrate_unmarshal() {
205 // Real data sent by Chrome while watching a 6Mb/s stream
206 let input = [
207 143, 206, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 82, 69, 77, 66, 1, 26, 32, 223, 72, 116, 237,
208 22,
209 ];
210 
211 // mantissa = []byte{26 & 3, 32, 223} = []byte{2, 32, 223} = 139487
212 // exp = 26 >> 2 = 6
213 // bitrate = 139487 * 2^6 = 139487 * 64 = 8927168 = 8.9 Mb/s
214 let expected = Remb {
215 sender_ssrc: 1.into(),
216 ssrc: 0.into(),
217 bitrate: 8927168.0,
218 ssrcs: vec![1215622422],
219 };
220 
221 let packet = Remb::try_from(&input[4..]).unwrap();
222 assert_eq!(expected, packet);
223 }
224 
225 #[test]
226 fn test_receiver_estimated_maximum_bitrate_truncate() {
227 let input = [
228 143, 206, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 82, 69, 77, 66, 1, 26, 32, 223, 72, 116, 237,
229 22,
230 ];
231 
232 // Make sure that we're interpreting the bitrate correctly.
233 // For the above example, we have:
234 
235 // mantissa = 139487
236 // exp = 6
237 // bitrate = 8927168
238 
239 let mut packet = Remb::try_from(&input[4..]).unwrap();
240 assert_eq!(8927168.0, packet.bitrate);
241 
242 // Just verify marshal produces the same input.
243 let mut output = [0; 1500];
244 let output_len = packet.write_to(&mut output);
245 assert_eq!(input, output[0..output_len]);
246 
247 // If we subtract the bitrate by 1, we'll round down a lower mantissa
248 packet.bitrate -= 1.0;
249 
250 // bitrate = 8927167
251 // mantissa = 139486
252 // exp = 6
253 
254 let output_len = packet.write_to(&mut output);
255 assert_ne!(input, output[0..output_len]);
256 let expected = [
257 143, 206, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 82, 69, 77, 66, 1, 26, 32, 222, 72, 116, 237,
258 22,
259 ];
260 assert_eq!(expected, output[0..output_len]);
261 
262 // Which if we actually unmarshal again, we'll find that it's actually decreased by 63 (which is exp)
263 // mantissa = 139486
264 // exp = 6
265 // bitrate = 8927104
266 
267 let packet = Remb::try_from(&output[4..]).unwrap();
268 assert_eq!(8927104.0, packet.bitrate);
269 }
270 
271 #[test]
272 fn test_receiver_estimated_maximum_bitrate_overflow() {
273 // Marshal a packet with the maximum possible bitrate.
274 let packet = Remb {
275 sender_ssrc: 0.into(),
276 ssrc: 0.into(),
277 bitrate: f32::MAX,
278 ssrcs: vec![],
279 };
280 
281 // mantissa = 262143 = 0x3FFFF
282 // exp = 63
283 
284 let expected = [
285 143, 206, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 77, 66, 0, 255, 255, 255,
286 ];
287 
288 let mut output = [0; 1500];
289 let output_len = packet.write_to(&mut output);
290 assert_eq!(expected, output[0..output_len]);
291 
292 // mantissa = 262143
293 // exp = 63
294 // bitrate = 0xFFFFC00000000000
295 
296 let packet = Remb::try_from(&output[4..output_len]).unwrap();
297 assert_eq!(f32::from_bits(0x67FFFFC0), packet.bitrate);
298 
299 // Make sure we marshal to the same result again.
300 let output_len = packet.write_to(&mut output);
301 assert_eq!(expected, output[0..output_len]);
302 
303 // Finally, try unmarshalling one number higher than we used to be able to handle.
304 let input = [
305 143, 206, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 82, 69, 77, 66, 0, 188, 0, 0,
306 ];
307 let packet = Remb::try_from(&input[4..]).unwrap();
308 assert_eq!(f32::from_bits(0x62800000), packet.bitrate);
309 }
310}