rtc_rtcp/payload_feedbacks/receiver_estimated_maximum_bitrate/mod.rs
1#[cfg(test)]
2mod receiver_estimated_maximum_bitrate_test;
3
4use crate::{header::*, packet::*, util::*};
5use shared::{
6 error::{Error, Result},
7 marshal::{Marshal, MarshalSize, Unmarshal},
8};
9
10use bytes::{Buf, BufMut};
11use std::any::Any;
12use std::fmt;
13
14/// ReceiverEstimatedMaximumBitrate contains the receiver's estimated maximum bitrate.
15///
16/// ## Specifications
17///
18/// * [draft-alvestrand-rmcat-remb-03]
19///
20/// [draft-alvestrand-rmcat-remb-03]: https://tools.ietf.org/html/draft-alvestrand-rmcat-remb-03
21#[derive(Debug, PartialEq, Default, Clone)]
22pub struct ReceiverEstimatedMaximumBitrate {
23 /// SSRC of sender
24 pub sender_ssrc: u32,
25
26 /// Estimated maximum bitrate
27 pub bitrate: f32,
28
29 /// SSRC entries which this packet applies to
30 pub ssrcs: Vec<u32>,
31}
32
33const REMB_OFFSET: usize = 16;
34
35/// Keep a table of powers to units for fast conversion.
36const BIT_UNITS: [&str; 7] = ["b", "Kb", "Mb", "Gb", "Tb", "Pb", "Eb"];
37const UNIQUE_IDENTIFIER: [u8; 4] = [b'R', b'E', b'M', b'B'];
38
39/// String prints the REMB packet in a human-readable format.
40impl fmt::Display for ReceiverEstimatedMaximumBitrate {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 // Do some unit conversions because b/s is far too difficult to read.
43 let mut bitrate = self.bitrate;
44 let mut powers = 0;
45
46 // Keep dividing the bitrate until it's under 1000
47 while bitrate >= 1000.0 && powers < BIT_UNITS.len() {
48 bitrate /= 1000.0;
49 powers += 1;
50 }
51
52 let unit = BIT_UNITS[powers];
53
54 write!(
55 f,
56 "ReceiverEstimatedMaximumBitrate {:x} {:.2} {}/s",
57 self.sender_ssrc, bitrate, unit,
58 )
59 }
60}
61
62impl Packet for ReceiverEstimatedMaximumBitrate {
63 /// Header returns the Header associated with this packet.
64 fn header(&self) -> Header {
65 Header {
66 padding: get_padding_size(self.raw_size()) != 0,
67 count: FORMAT_REMB,
68 packet_type: PacketType::PayloadSpecificFeedback,
69 length: ((self.marshal_size() / 4) - 1) as u16,
70 }
71 }
72
73 /// destination_ssrc returns an array of SSRC values that this packet refers to.
74 fn destination_ssrc(&self) -> Vec<u32> {
75 self.ssrcs.clone()
76 }
77
78 fn raw_size(&self) -> usize {
79 HEADER_LENGTH + REMB_OFFSET + self.ssrcs.len() * 4
80 }
81
82 fn as_any(&self) -> &dyn Any {
83 self
84 }
85
86 fn equal(&self, other: &dyn Packet) -> bool {
87 other
88 .as_any()
89 .downcast_ref::<ReceiverEstimatedMaximumBitrate>()
90 == Some(self)
91 }
92
93 fn cloned(&self) -> Box<dyn Packet> {
94 Box::new(self.clone())
95 }
96}
97
98impl MarshalSize for ReceiverEstimatedMaximumBitrate {
99 fn marshal_size(&self) -> usize {
100 let l = self.raw_size();
101 // align to 32-bit boundary
102 l + get_padding_size(l)
103 }
104}
105
106impl Marshal for ReceiverEstimatedMaximumBitrate {
107 /// Marshal serializes the packet and returns a byte slice.
108 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
109 const BITRATE_MAX: f32 = 2.417_842_4e24; //0x3FFFFp+63;
110
111 /*
112 0 1 2 3
113 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
114 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
115 |V=2|P| FMT=15 | PT=206 | length |
116 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
117 | SSRC of packet sender |
118 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
119 | SSRC of media source |
120 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
121 | Unique identifier 'R' 'E' 'M' 'B' |
122 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
123 | Num SSRC | BR Exp | BR Mantissa |
124 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
125 | SSRC feedback |
126 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
127 | ... |
128 */
129
130 if buf.remaining_mut() < self.marshal_size() {
131 return Err(Error::BufferTooShort);
132 }
133
134 let h = self.header();
135 let n = h.marshal_to(buf)?;
136 buf = &mut buf[n..];
137
138 buf.put_u32(self.sender_ssrc);
139 buf.put_u32(0); // always zero
140
141 buf.put_slice(&UNIQUE_IDENTIFIER);
142
143 // Write the length of the ssrcs to follow at the end
144 buf.put_u8(self.ssrcs.len() as u8);
145
146 let mut exp = 0;
147 let mut bitrate = self.bitrate;
148 if bitrate >= BITRATE_MAX {
149 bitrate = BITRATE_MAX
150 }
151
152 if bitrate < 0.0 {
153 return Err(Error::InvalidBitrate);
154 }
155
156 while bitrate >= (1 << 18) as f32 {
157 bitrate /= 2.0;
158 exp += 1;
159 }
160
161 if exp >= (1 << 6) {
162 return Err(Error::InvalidBitrate);
163 }
164
165 let mantissa = bitrate.floor() as u32;
166
167 // We can't quite use the binary package because
168 // a) it's a uint24 and b) the exponent is only 6-bits
169 // Just trust me; this is big-endian encoding.
170 buf.put_u8((exp << 2) as u8 | (mantissa >> 16) as u8);
171 buf.put_u8((mantissa >> 8) as u8);
172 buf.put_u8(mantissa as u8);
173
174 // Write the SSRCs at the very end.
175 for ssrc in &self.ssrcs {
176 buf.put_u32(*ssrc);
177 }
178
179 if h.padding {
180 put_padding(buf, self.raw_size());
181 }
182
183 Ok(self.marshal_size())
184 }
185}
186
187impl Unmarshal for ReceiverEstimatedMaximumBitrate {
188 /// Unmarshal reads a REMB packet from the given byte slice.
189 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
190 where
191 Self: Sized,
192 B: Buf,
193 {
194 let raw_packet_len = raw_packet.remaining();
195 // 20 bytes is the size of the packet with no SSRCs
196 if raw_packet_len < 20 {
197 return Err(Error::PacketTooShort);
198 }
199
200 const MANTISSA_MAX: u32 = 0x7FFFFF;
201 /*
202 0 1 2 3
203 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
204 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
205 |V=2|P| FMT=15 | PT=206 | length |
206 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
207 | SSRC of packet sender |
208 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
209 | SSRC of media source |
210 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
211 | Unique identifier 'R' 'E' 'M' 'B' |
212 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
213 | Num SSRC | BR Exp | BR Mantissa |
214 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
215 | SSRC feedback |
216 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
217 | ... |
218 */
219 let header = Header::unmarshal(raw_packet)?;
220
221 if header.packet_type != PacketType::PayloadSpecificFeedback || header.count != FORMAT_REMB
222 {
223 return Err(Error::WrongType);
224 }
225
226 let sender_ssrc = raw_packet.get_u32();
227 let media_ssrc = raw_packet.get_u32();
228 if media_ssrc != 0 {
229 return Err(Error::SsrcMustBeZero);
230 }
231
232 // REMB rules all around me
233 let mut unique_identifier = [0; 4];
234 unique_identifier[0] = raw_packet.get_u8();
235 unique_identifier[1] = raw_packet.get_u8();
236 unique_identifier[2] = raw_packet.get_u8();
237 unique_identifier[3] = raw_packet.get_u8();
238 if unique_identifier[0] != UNIQUE_IDENTIFIER[0]
239 || unique_identifier[1] != UNIQUE_IDENTIFIER[1]
240 || unique_identifier[2] != UNIQUE_IDENTIFIER[2]
241 || unique_identifier[3] != UNIQUE_IDENTIFIER[3]
242 {
243 return Err(Error::MissingRembIdentifier);
244 }
245
246 // The next byte is the number of SSRC entries at the end.
247 let ssrcs_len = raw_packet.get_u8() as usize;
248
249 // Get the 6-bit exponent value.
250 let b17 = raw_packet.get_u8();
251 let mut exp = (b17 as u64) >> 2;
252 exp += 127; // bias for IEEE754
253 exp += 23; // IEEE754 biases the decimal to the left, abs-send-time biases it to the right
254
255 // The remaining 2-bits plus the next 16-bits are the mantissa.
256 let b18 = raw_packet.get_u8();
257 let b19 = raw_packet.get_u8();
258 let mut mantissa = ((b17 & 3) as u32) << 16 | (b18 as u32) << 8 | b19 as u32;
259
260 if mantissa != 0 {
261 // ieee754 requires an implicit leading bit
262 while (mantissa & (MANTISSA_MAX + 1)) == 0 {
263 exp -= 1;
264 mantissa *= 2;
265 }
266 }
267
268 // bitrate = mantissa * 2^exp
269 let bitrate = f32::from_bits(((exp as u32) << 23) | (mantissa & MANTISSA_MAX));
270
271 let mut ssrcs = vec![];
272 for _i in 0..ssrcs_len {
273 ssrcs.push(raw_packet.get_u32());
274 }
275
276 if
277 /*header.padding &&*/
278 raw_packet.has_remaining() {
279 raw_packet.advance(raw_packet.remaining());
280 }
281
282 Ok(ReceiverEstimatedMaximumBitrate {
283 sender_ssrc,
284 //media_ssrc,
285 bitrate,
286 ssrcs,
287 })
288 }
289}