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