receiver_estimated_maximum_bitrate.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. package rtcp
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "fmt"
  6. "math"
  7. )
  8. // ReceiverEstimatedMaximumBitrate contains the receiver's estimated maximum bitrate.
  9. // see: https://tools.ietf.org/html/draft-alvestrand-rmcat-remb-03
  10. type ReceiverEstimatedMaximumBitrate struct {
  11. // SSRC of sender
  12. SenderSSRC uint32
  13. // Estimated maximum bitrate
  14. Bitrate float32
  15. // SSRC entries which this packet applies to
  16. SSRCs []uint32
  17. }
  18. // Marshal serializes the packet and returns a byte slice.
  19. func (p ReceiverEstimatedMaximumBitrate) Marshal() (buf []byte, err error) {
  20. // Allocate a buffer of the exact output size.
  21. buf = make([]byte, p.MarshalSize())
  22. // Write to our buffer.
  23. n, err := p.MarshalTo(buf)
  24. if err != nil {
  25. return nil, err
  26. }
  27. // This will always be true but just to be safe.
  28. if n != len(buf) {
  29. return nil, errWrongMarshalSize
  30. }
  31. return buf, nil
  32. }
  33. // MarshalSize returns the size of the packet when marshaled.
  34. // This can be used in conjunction with `MarshalTo` to avoid allocations.
  35. func (p ReceiverEstimatedMaximumBitrate) MarshalSize() (n int) {
  36. return 20 + 4*len(p.SSRCs)
  37. }
  38. // MarshalTo serializes the packet to the given byte slice.
  39. func (p ReceiverEstimatedMaximumBitrate) MarshalTo(buf []byte) (n int, err error) {
  40. const bitratemax = 0x3FFFFp+63
  41. /*
  42. 0 1 2 3
  43. 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
  44. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  45. |V=2|P| FMT=15 | PT=206 | length |
  46. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  47. | SSRC of packet sender |
  48. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  49. | SSRC of media source |
  50. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  51. | Unique identifier 'R' 'E' 'M' 'B' |
  52. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  53. | Num SSRC | BR Exp | BR Mantissa |
  54. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  55. | SSRC feedback |
  56. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  57. | ... |
  58. */
  59. size := p.MarshalSize()
  60. if len(buf) < size {
  61. return 0, errPacketTooShort
  62. }
  63. buf[0] = 143 // v=2, p=0, fmt=15
  64. buf[1] = 206
  65. // Length of this packet in 32-bit words minus one.
  66. length := uint16((p.MarshalSize() / 4) - 1)
  67. binary.BigEndian.PutUint16(buf[2:4], length)
  68. binary.BigEndian.PutUint32(buf[4:8], p.SenderSSRC)
  69. binary.BigEndian.PutUint32(buf[8:12], 0) // always zero
  70. // ALL HAIL REMB
  71. buf[12] = 'R'
  72. buf[13] = 'E'
  73. buf[14] = 'M'
  74. buf[15] = 'B'
  75. // Write the length of the ssrcs to follow at the end
  76. buf[16] = byte(len(p.SSRCs))
  77. exp := 0
  78. bitrate := p.Bitrate
  79. if bitrate >= bitratemax {
  80. bitrate = bitratemax
  81. }
  82. if bitrate < 0 {
  83. return 0, errInvalidBitrate
  84. }
  85. for bitrate >= (1 << 18) {
  86. bitrate /= 2.0
  87. exp++
  88. }
  89. if exp >= (1 << 6) {
  90. return 0, errInvalidBitrate
  91. }
  92. mantissa := uint(math.Floor(float64(bitrate)))
  93. // We can't quite use the binary package because
  94. // a) it's a uint24 and b) the exponent is only 6-bits
  95. // Just trust me; this is big-endian encoding.
  96. buf[17] = byte(exp<<2) | byte(mantissa>>16)
  97. buf[18] = byte(mantissa >> 8)
  98. buf[19] = byte(mantissa)
  99. // Write the SSRCs at the very end.
  100. n = 20
  101. for _, ssrc := range p.SSRCs {
  102. binary.BigEndian.PutUint32(buf[n:n+4], ssrc)
  103. n += 4
  104. }
  105. return n, nil
  106. }
  107. // Unmarshal reads a REMB packet from the given byte slice.
  108. func (p *ReceiverEstimatedMaximumBitrate) Unmarshal(buf []byte) (err error) {
  109. const mantissamax = 0x7FFFFF
  110. /*
  111. 0 1 2 3
  112. 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
  113. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  114. |V=2|P| FMT=15 | PT=206 | length |
  115. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  116. | SSRC of packet sender |
  117. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  118. | SSRC of media source |
  119. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  120. | Unique identifier 'R' 'E' 'M' 'B' |
  121. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  122. | Num SSRC | BR Exp | BR Mantissa |
  123. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  124. | SSRC feedback |
  125. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  126. | ... |
  127. */
  128. // 20 bytes is the size of the packet with no SSRCs
  129. if len(buf) < 20 {
  130. return errPacketTooShort
  131. }
  132. // version must be 2
  133. version := buf[0] >> 6
  134. if version != 2 {
  135. return fmt.Errorf("%w expected(2) actual(%d)", errBadVersion, version)
  136. }
  137. // padding must be unset
  138. padding := (buf[0] >> 5) & 1
  139. if padding != 0 {
  140. return fmt.Errorf("%w expected(0) actual(%d)", errWrongPadding, padding)
  141. }
  142. // fmt must be 15
  143. fmtVal := buf[0] & 31
  144. if fmtVal != 15 {
  145. return fmt.Errorf("%w expected(15) actual(%d)", errWrongFeedbackType, fmtVal)
  146. }
  147. // Must be payload specific feedback
  148. if buf[1] != 206 {
  149. return fmt.Errorf("%w expected(206) actual(%d)", errWrongPayloadType, buf[1])
  150. }
  151. // length is the number of 32-bit words, minus 1
  152. length := binary.BigEndian.Uint16(buf[2:4])
  153. size := int((length + 1) * 4)
  154. // There's not way this could be legit
  155. if size < 20 {
  156. return errHeaderTooSmall
  157. }
  158. // Make sure the buffer is large enough.
  159. if len(buf) < size {
  160. return errPacketTooShort
  161. }
  162. // The sender SSRC is 32-bits
  163. p.SenderSSRC = binary.BigEndian.Uint32(buf[4:8])
  164. // The destination SSRC must be 0
  165. media := binary.BigEndian.Uint32(buf[8:12])
  166. if media != 0 {
  167. return errSSRCMustBeZero
  168. }
  169. // REMB rules all around me
  170. if !bytes.Equal(buf[12:16], []byte{'R', 'E', 'M', 'B'}) {
  171. return errMissingREMBidentifier
  172. }
  173. // The next byte is the number of SSRC entries at the end.
  174. num := int(buf[16])
  175. // Now we know the expected size, make sure they match.
  176. if size != 20+4*num {
  177. return errSSRCNumAndLengthMismatch
  178. }
  179. // Get the 6-bit exponent value.
  180. exp := buf[17] >> 2
  181. exp += 127 // bias for IEEE754
  182. exp += 23 // IEEE754 biases the decimal to the left, abs-send-time biases it to the right
  183. // The remaining 2-bits plus the next 16-bits are the mantissa.
  184. mantissa := uint32(buf[17]&3)<<16 | uint32(buf[18])<<8 | uint32(buf[19])
  185. if mantissa != 0 {
  186. // ieee754 requires an implicit leading bit
  187. for (mantissa & (mantissamax + 1)) == 0 {
  188. exp--
  189. mantissa *= 2
  190. }
  191. }
  192. // bitrate = mantissa * 2^exp
  193. p.Bitrate = math.Float32frombits((uint32(exp) << 23) | (mantissa & mantissamax))
  194. // Clear any existing SSRCs
  195. p.SSRCs = nil
  196. // Loop over and parse the SSRC entires at the end.
  197. // We already verified that size == num * 4
  198. for n := 20; n < size; n += 4 {
  199. ssrc := binary.BigEndian.Uint32(buf[n : n+4])
  200. p.SSRCs = append(p.SSRCs, ssrc)
  201. }
  202. return nil
  203. }
  204. // Header returns the Header associated with this packet.
  205. func (p *ReceiverEstimatedMaximumBitrate) Header() Header {
  206. return Header{
  207. Count: FormatREMB,
  208. Type: TypePayloadSpecificFeedback,
  209. Length: uint16((p.MarshalSize() / 4) - 1),
  210. }
  211. }
  212. // String prints the REMB packet in a human-readable format.
  213. func (p *ReceiverEstimatedMaximumBitrate) String() string {
  214. // Keep a table of powers to units for fast conversion.
  215. bitUnits := []string{"b", "Kb", "Mb", "Gb", "Tb", "Pb", "Eb"}
  216. // Do some unit conversions because b/s is far too difficult to read.
  217. bitrate := p.Bitrate
  218. powers := 0
  219. // Keep dividing the bitrate until it's under 1000
  220. for bitrate >= 1000.0 && powers < len(bitUnits) {
  221. bitrate /= 1000.0
  222. powers++
  223. }
  224. unit := bitUnits[powers]
  225. return fmt.Sprintf("ReceiverEstimatedMaximumBitrate %x %.2f %s/s", p.SenderSSRC, bitrate, unit)
  226. }
  227. // DestinationSSRC returns an array of SSRC values that this packet refers to.
  228. func (p *ReceiverEstimatedMaximumBitrate) DestinationSSRC() []uint32 {
  229. return p.SSRCs
  230. }