Skip to content
This repository was archived by the owner on Aug 23, 2022. It is now read-only.

Commit 8521ddf

Browse files
author
Rain Liu
committed
update REMB code
1 parent 38115e9 commit 8521ddf

File tree

3 files changed

+154
-204
lines changed

3 files changed

+154
-204
lines changed

src/header.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub enum PacketType {
1616
ApplicationDefined = 204, // RFC 3550, 6.7 (unimplemented)
1717
TransportSpecificFeedback = 205, // RFC 4585, 6051
1818
PayloadSpecificFeedback = 206, // RFC 4585, 6.3
19+
ExtendedReport = 207, // RFC 3611
1920
}
2021

2122
impl Default for PacketType {
@@ -51,6 +52,7 @@ impl std::fmt::Display for PacketType {
5152
PacketType::ApplicationDefined => "APP",
5253
PacketType::TransportSpecificFeedback => "TSFB",
5354
PacketType::PayloadSpecificFeedback => "PSFB",
55+
PacketType::ExtendedReport => "XR",
5456
};
5557
write!(f, "{}", s)
5658
}

src/payload_feedbacks/receiver_estimated_maximum_bitrate/mod.rs

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub struct ReceiverEstimatedMaximumBitrate {
1818
pub sender_ssrc: u32,
1919

2020
/// Estimated maximum bitrate
21-
pub bitrate: u64,
21+
pub bitrate: f32,
2222

2323
/// SSRC entries which this packet applies to
2424
pub ssrcs: Vec<u32>,
@@ -34,7 +34,7 @@ const UNIQUE_IDENTIFIER: [u8; 4] = [b'R', b'E', b'M', b'B'];
3434
impl fmt::Display for ReceiverEstimatedMaximumBitrate {
3535
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3636
// 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;
3838
let mut powers = 0;
3939

4040
// Keep dividing the bitrate until it's under 1000
@@ -100,6 +100,8 @@ impl MarshalSize for ReceiverEstimatedMaximumBitrate {
100100
impl Marshal for ReceiverEstimatedMaximumBitrate {
101101
/// Marshal serializes the packet and returns a byte slice.
102102
fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
103+
const BITRATE_MAX: f32 = 2.417_842_4e24; //0x3FFFFp+63;
104+
103105
/*
104106
0 1 2 3
105107
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 {
135137
// Write the length of the ssrcs to follow at the end
136138
buf.put_u8(self.ssrcs.len() as u8);
137139

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());
160148
}
161149

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+
162161
// We can't quite use the binary package because
163162
// a) it's a uint24 and b) the exponent is only 6-bits
164163
// 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);
166165
buf.put_u8((mantissa >> 8) as u8);
167166
buf.put_u8(mantissa as u8);
168167

@@ -191,6 +190,8 @@ impl Unmarshal for ReceiverEstimatedMaximumBitrate {
191190
if raw_packet_len < 20 {
192191
return Err(Error::PacketTooShort.into());
193192
}
193+
194+
const MANTISSA_MAX: u32 = 0x7FFFFF;
194195
/*
195196
0 1 2 3
196197
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 {
241242

242243
// Get the 6-bit exponent value.
243244
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
245248

246249
// The remaining 2-bits plus the next 16-bits are the mantissa.
247250
let b18 = raw_packet.get_u8();
248251
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));
259264

260265
let mut ssrcs = vec![];
261266
for _i in 0..ssrcs_len {

0 commit comments

Comments
 (0)