Skip to main content

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;
34const SSRC_ENTRY_OFFSET: usize = 20;
35
36/// Keep a table of powers to units for fast conversion.
37const BIT_UNITS: [&str; 7] = ["b", "Kb", "Mb", "Gb", "Tb", "Pb", "Eb"];
38const UNIQUE_IDENTIFIER: [u8; 4] = [b'R', b'E', b'M', b'B'];
39
40/// String prints the REMB packet in a human-readable format.
41impl fmt::Display for ReceiverEstimatedMaximumBitrate {
42    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43        // Do some unit conversions because b/s is far too difficult to read.
44        let mut bitrate = self.bitrate;
45        let mut powers = 0;
46
47        // Keep dividing the bitrate until it's under 1000
48        while bitrate >= 1000.0 && powers < BIT_UNITS.len() {
49            bitrate /= 1000.0;
50            powers += 1;
51        }
52
53        let unit = BIT_UNITS[powers];
54
55        write!(
56            f,
57            "ReceiverEstimatedMaximumBitrate {:x} {:.2} {}/s",
58            self.sender_ssrc, bitrate, unit,
59        )
60    }
61}
62
63impl Packet for ReceiverEstimatedMaximumBitrate {
64    /// Header returns the Header associated with this packet.
65    fn header(&self) -> Header {
66        Header {
67            padding: get_padding_size(self.raw_size()) != 0,
68            count: FORMAT_REMB,
69            packet_type: PacketType::PayloadSpecificFeedback,
70            length: ((self.marshal_size() / 4) - 1) as u16,
71        }
72    }
73
74    /// destination_ssrc returns an array of SSRC values that this packet refers to.
75    fn destination_ssrc(&self) -> Vec<u32> {
76        self.ssrcs.clone()
77    }
78
79    fn raw_size(&self) -> usize {
80        HEADER_LENGTH + REMB_OFFSET + self.ssrcs.len() * 4
81    }
82
83    fn as_any(&self) -> &dyn Any {
84        self
85    }
86
87    fn equal(&self, other: &dyn Packet) -> bool {
88        other
89            .as_any()
90            .downcast_ref::<ReceiverEstimatedMaximumBitrate>()
91            == Some(self)
92    }
93
94    fn cloned(&self) -> Box<dyn Packet> {
95        Box::new(self.clone())
96    }
97}
98
99impl MarshalSize for ReceiverEstimatedMaximumBitrate {
100    fn marshal_size(&self) -> usize {
101        let l = self.raw_size();
102        // align to 32-bit boundary
103        l + get_padding_size(l)
104    }
105}
106
107impl Marshal for ReceiverEstimatedMaximumBitrate {
108    /// Marshal serializes the packet and returns a byte slice.
109    fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
110        const BITRATE_MAX: f32 = 2.417_842_4e24; //0x3FFFFp+63;
111
112        /*
113            0                   1                   2                   3
114            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
115           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
116           |V=2|P| FMT=15  |   PT=206      |             length            |
117           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
118           |                  SSRC of packet sender                        |
119           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
120           |                  SSRC of media source                         |
121           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
122           |  Unique identifier 'R' 'E' 'M' 'B'                            |
123           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
124           |  Num SSRC     | BR Exp    |  BR Mantissa                      |
125           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
126           |   SSRC feedback                                               |
127           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
128           |  ...                                                          |
129        */
130
131        if buf.remaining_mut() < self.marshal_size() {
132            return Err(Error::BufferTooShort);
133        }
134
135        let h = self.header();
136        let n = h.marshal_to(buf)?;
137        buf = &mut buf[n..];
138
139        buf.put_u32(self.sender_ssrc);
140        buf.put_u32(0); // always zero
141
142        buf.put_slice(&UNIQUE_IDENTIFIER);
143
144        // Write the length of the ssrcs to follow at the end
145        buf.put_u8(self.ssrcs.len() as u8);
146
147        let mut exp = 0;
148        let mut bitrate = self.bitrate;
149        if bitrate >= BITRATE_MAX {
150            bitrate = BITRATE_MAX
151        }
152
153        if bitrate < 0.0 {
154            return Err(Error::InvalidBitrate);
155        }
156
157        while bitrate >= (1 << 18) as f32 {
158            bitrate /= 2.0;
159            exp += 1;
160        }
161
162        if exp >= (1 << 6) {
163            return Err(Error::InvalidBitrate);
164        }
165
166        let mantissa = bitrate.floor() as u32;
167
168        // We can't quite use the binary package because
169        // a) it's a uint24 and b) the exponent is only 6-bits
170        // Just trust me; this is big-endian encoding.
171        buf.put_u8((exp << 2) as u8 | (mantissa >> 16) as u8);
172        buf.put_u8((mantissa >> 8) as u8);
173        buf.put_u8(mantissa as u8);
174
175        // Write the SSRCs at the very end.
176        for ssrc in &self.ssrcs {
177            buf.put_u32(*ssrc);
178        }
179
180        if h.padding {
181            put_padding(buf, self.raw_size());
182        }
183
184        Ok(self.marshal_size())
185    }
186}
187
188impl Unmarshal for ReceiverEstimatedMaximumBitrate {
189    /// Unmarshal reads a REMB packet from the given byte slice.
190    fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
191    where
192        Self: Sized,
193        B: Buf,
194    {
195        let raw_packet_len = raw_packet.remaining();
196        if raw_packet_len < SSRC_ENTRY_OFFSET {
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        if raw_packet_len < SSRC_ENTRY_OFFSET + ssrcs_len * 4 {
249            return Err(Error::PacketTooShort);
250        }
251
252        // Get the 6-bit exponent value.
253        let b17 = raw_packet.get_u8();
254        let mut exp = (b17 as u64) >> 2;
255        exp += 127; // bias for IEEE754
256        exp += 23; // IEEE754 biases the decimal to the left, abs-send-time biases it to the right
257
258        // The remaining 2-bits plus the next 16-bits are the mantissa.
259        let b18 = raw_packet.get_u8();
260        let b19 = raw_packet.get_u8();
261        let mut mantissa = ((b17 & 3) as u32) << 16 | (b18 as u32) << 8 | b19 as u32;
262
263        if mantissa != 0 {
264            // ieee754 requires an implicit leading bit
265            while (mantissa & (MANTISSA_MAX + 1)) == 0 {
266                exp -= 1;
267                mantissa *= 2;
268            }
269        }
270
271        // bitrate = mantissa * 2^exp
272        let bitrate = f32::from_bits(((exp as u32) << 23) | (mantissa & MANTISSA_MAX));
273
274        let mut ssrcs = vec![];
275        for _i in 0..ssrcs_len {
276            ssrcs.push(raw_packet.get_u32());
277        }
278
279        if
280        /*header.padding &&*/
281        raw_packet.has_remaining() {
282            raw_packet.advance(raw_packet.remaining());
283        }
284
285        Ok(ReceiverEstimatedMaximumBitrate {
286            sender_ssrc,
287            //media_ssrc,
288            bitrate,
289            ssrcs,
290        })
291    }
292}