@@ -18,7 +18,7 @@ pub struct ReceiverEstimatedMaximumBitrate {
18
18
pub sender_ssrc : u32 ,
19
19
20
20
/// Estimated maximum bitrate
21
- pub bitrate : u64 ,
21
+ pub bitrate : f32 ,
22
22
23
23
/// SSRC entries which this packet applies to
24
24
pub ssrcs : Vec < u32 > ,
@@ -34,7 +34,7 @@ const UNIQUE_IDENTIFIER: [u8; 4] = [b'R', b'E', b'M', b'B'];
34
34
impl fmt:: Display for ReceiverEstimatedMaximumBitrate {
35
35
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
36
36
// Do some unit conversions because b/s is far too difficult to read.
37
- let mut bitrate = self . bitrate as f64 ;
37
+ let mut bitrate = self . bitrate ;
38
38
let mut powers = 0 ;
39
39
40
40
// Keep dividing the bitrate until it's under 1000
@@ -100,6 +100,8 @@ impl MarshalSize for ReceiverEstimatedMaximumBitrate {
100
100
impl Marshal for ReceiverEstimatedMaximumBitrate {
101
101
/// Marshal serializes the packet and returns a byte slice.
102
102
fn marshal_to ( & self , mut buf : & mut [ u8 ] ) -> Result < usize > {
103
+ const BITRATE_MAX : f32 = 2.417_842_4e24 ; //0x3FFFFp+63;
104
+
103
105
/*
104
106
0 1 2 3
105
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
@@ -135,34 +137,31 @@ impl Marshal for ReceiverEstimatedMaximumBitrate {
135
137
// Write the length of the ssrcs to follow at the end
136
138
buf. put_u8 ( self . ssrcs . len ( ) as u8 ) ;
137
139
138
- // We can only encode 18 bits of information in the mantissa.
139
- // The exponent lets us shift to the left up to 64 places (6-bits).
140
- // We actually need a uint82 to encode the largest possible number,
141
- // but uint64 should be good enough for 2.3 exabytes per second.
142
-
143
- // So we need to truncate the bitrate and use the exponent for the shift.
144
- // bitrate = mantissa * (1 << exp)
145
-
146
- // Calculate the total shift based on the leading number of zeroes.
147
- // This will be negative if there is no shift required.
148
- let shift = 64 - self . bitrate . leading_zeros ( ) ;
149
- let mantissa;
150
- let exp;
151
-
152
- if shift <= 18 {
153
- // Fit everything in the mantissa because we can.
154
- mantissa = self . bitrate ;
155
- exp = 0 ;
156
- } else {
157
- // We can only use 18 bits of precision, so truncate.
158
- mantissa = self . bitrate >> ( shift - 18 ) ;
159
- exp = shift - 18 ;
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 ( ) ) ;
160
148
}
161
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
+
162
161
// We can't quite use the binary package because
163
162
// a) it's a uint24 and b) the exponent is only 6-bits
164
163
// Just trust me; this is big-endian encoding.
165
- buf. put_u8 ( ( ( exp << 2 ) | ( mantissa >> 16 ) as u32 ) as u8 ) ;
164
+ buf. put_u8 ( ( exp << 2 ) as u8 | ( mantissa >> 16 ) as u8 ) ;
166
165
buf. put_u8 ( ( mantissa >> 8 ) as u8 ) ;
167
166
buf. put_u8 ( mantissa as u8 ) ;
168
167
@@ -191,6 +190,8 @@ impl Unmarshal for ReceiverEstimatedMaximumBitrate {
191
190
if raw_packet_len < 20 {
192
191
return Err ( Error :: PacketTooShort . into ( ) ) ;
193
192
}
193
+
194
+ const MANTISSA_MAX : u32 = 0x7FFFFF ;
194
195
/*
195
196
0 1 2 3
196
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
@@ -241,21 +242,25 @@ impl Unmarshal for ReceiverEstimatedMaximumBitrate {
241
242
242
243
// Get the 6-bit exponent value.
243
244
let b17 = raw_packet. get_u8 ( ) ;
244
- let exp = ( b17 as u64 ) >> 2 ;
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
245
248
246
249
// The remaining 2-bits plus the next 16-bits are the mantissa.
247
250
let b18 = raw_packet. get_u8 ( ) ;
248
251
let b19 = raw_packet. get_u8 ( ) ;
249
- let mantissa = ( ( b17 & 3 ) as u64 ) << 16 | ( b18 as u64 ) << 8 | b19 as u64 ;
250
-
251
- let bitrate = if exp > 46 {
252
- // NOTE: We intentionally truncate values so they fit in a uint64.
253
- // Otherwise we would need a uint82.
254
- // This is 2.3 exabytes per second, which should be good enough.
255
- std:: u64:: MAX
256
- } else {
257
- mantissa << exp
258
- } ;
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 ) ) ;
259
264
260
265
let mut ssrcs = vec ! [ ] ;
261
266
for _i in 0 ..ssrcs_len {
0 commit comments