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