1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h"
12
13 #include "modules/rtp_rtcp/source/byte_io.h"
14 #include "rtc_base/checks.h"
15 #include "rtc_base/logging.h"
16
17 namespace webrtc {
18 namespace rtcp {
TmmbItem(uint32_t ssrc,uint64_t bitrate_bps,uint16_t overhead)19 TmmbItem::TmmbItem(uint32_t ssrc, uint64_t bitrate_bps, uint16_t overhead)
20 : ssrc_(ssrc), bitrate_bps_(bitrate_bps), packet_overhead_(overhead) {
21 RTC_DCHECK_LE(overhead, 0x1ffu);
22 }
23
24 // 0 1 2 3
25 // 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
26 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
27 // 0 | SSRC |
28 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
29 // 4 | MxTBR Exp | MxTBR Mantissa |Measured Overhead|
30 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Parse(const uint8_t * buffer)31 bool TmmbItem::Parse(const uint8_t* buffer) {
32 ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[0]);
33 // Read 4 bytes into 1 block.
34 uint32_t compact = ByteReader<uint32_t>::ReadBigEndian(&buffer[4]);
35 // Split 1 block into 3 components.
36 uint8_t exponent = compact >> 26; // 6 bits.
37 uint64_t mantissa = (compact >> 9) & 0x1ffff; // 17 bits.
38 uint16_t overhead = compact & 0x1ff; // 9 bits.
39 // Combine 3 components into 2 values.
40 bitrate_bps_ = (mantissa << exponent);
41
42 bool shift_overflow = (bitrate_bps_ >> exponent) != mantissa;
43 if (shift_overflow) {
44 RTC_LOG(LS_ERROR) << "Invalid tmmb bitrate value : " << mantissa << "*2^"
45 << static_cast<int>(exponent);
46 return false;
47 }
48 packet_overhead_ = overhead;
49 return true;
50 }
51
Create(uint8_t * buffer) const52 void TmmbItem::Create(uint8_t* buffer) const {
53 constexpr uint64_t kMaxMantissa = 0x1ffff; // 17 bits.
54 uint64_t mantissa = bitrate_bps_;
55 uint32_t exponent = 0;
56 while (mantissa > kMaxMantissa) {
57 mantissa >>= 1;
58 ++exponent;
59 }
60
61 ByteWriter<uint32_t>::WriteBigEndian(&buffer[0], ssrc_);
62 uint32_t compact = (exponent << 26) | (mantissa << 9) | packet_overhead_;
63 ByteWriter<uint32_t>::WriteBigEndian(&buffer[4], compact);
64 }
65
set_packet_overhead(uint16_t overhead)66 void TmmbItem::set_packet_overhead(uint16_t overhead) {
67 RTC_DCHECK_LE(overhead, 0x1ffu);
68 packet_overhead_ = overhead;
69 }
70 } // namespace rtcp
71 } // namespace webrtc
72