Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(171)

Side by Side Diff: webrtc/modules/rtp_rtcp/source/rtcp_packet/remb.cc

Issue 1552773002: [rtp_rtcp] rtcp::Remb cleaned and got Parse function (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/remb.h" 11 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/remb.h"
12 12
13 #include "webrtc/base/checks.h"
13 #include "webrtc/base/logging.h" 14 #include "webrtc/base/logging.h"
14 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" 15 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
15 16
16 using webrtc::RTCPUtility::PT_PSFB; 17 using webrtc::RTCPUtility::RtcpCommonHeader;
17 using webrtc::RTCPUtility::RTCPPacketPSFBAPP;
18 using webrtc::RTCPUtility::RTCPPacketPSFBREMBItem;
19 18
20 namespace webrtc { 19 namespace webrtc {
21 namespace rtcp { 20 namespace rtcp {
22 namespace { 21 // Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb).
23 const uint32_t kUnusedMediaSourceSsrc0 = 0; 22 //
23 // 0 1 2 3
24 // 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
25 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
26 // |V=2|P| FMT=15 | PT=206 | length |
27 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
28 // 0 | SSRC of packet sender |
29 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
30 // 4 | Unused = 0 |
31 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32 // 8 | Unique identifier 'R' 'E' 'M' 'B' |
33 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 // 12 | Num SSRC | BR Exp | BR Mantissa |
35 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 // 16 | SSRC feedback |
37 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38 // : ... :
39 bool Remb::Parse(const RtcpCommonHeader& header, const uint8_t* payload) {
40 RTC_DCHECK(header.packet_type == kPacketType);
41 RTC_DCHECK(header.count_or_format == kFeedbackMessageType);
24 42
25 void AssignUWord8(uint8_t* buffer, size_t* offset, uint8_t value) { 43 if (header.payload_size_bytes < 16) {
26 buffer[(*offset)++] = value; 44 LOG(LS_WARNING) << "Payload length " << header.payload_size_bytes
45 << " is too small for Remb packet.";
46 return false;
47 }
48 if (kSignature != ByteReader<uint32_t>::ReadBigEndian(&payload[8])) {
49 LOG(LS_WARNING) << "REMB identifier not found, not a REMB packet.";
50 return false;
51 }
52 uint8_t number_of_ssrcs = payload[12];
53 if (header.payload_size_bytes !=
54 kCommonFeedbackLength + (2 + number_of_ssrcs) * 4) {
55 LOG(LS_WARNING) << "Payload size " << header.payload_size_bytes
56 << " does not match " << number_of_ssrcs << " ssrcs.";
57 return false;
58 }
59
60 ParseCommonFeedback(payload);
61 uint8_t exponenta = payload[13] >> 2;
62 uint32_t mantissa = (static_cast<uint32_t>(payload[13] & 0x03) << 16) |
63 ByteReader<uint16_t>::ReadBigEndian(&payload[14]);
64 bitrate_ = (mantissa << exponenta);
65
66 const uint8_t* next_ssrc = payload + 16;
67 ssrcs_.clear();
68 ssrcs_.reserve(number_of_ssrcs);
69 for (uint8_t i = 0; i < number_of_ssrcs; ++i) {
70 ssrcs_.push_back(ByteReader<uint32_t>::ReadBigEndian(next_ssrc));
71 next_ssrc += sizeof(uint32_t);
72 }
73
74 return true;
27 } 75 }
28 76
29 void AssignUWord32(uint8_t* buffer, size_t* offset, uint32_t value) { 77 bool Remb::AppliesTo(uint32_t ssrc) {
30 ByteWriter<uint32_t>::WriteBigEndian(buffer + *offset, value); 78 if (ssrcs_.size() >= kMaxNumberOfSsrcs) {
31 *offset += 4; 79 LOG(LS_WARNING) << "Max number of REMB feedback SSRCs reached.";
80 return false;
81 }
82 ssrcs_.push_back(ssrc);
83 return true;
32 } 84 }
33 85
34 void ComputeMantissaAnd6bitBase2Exponent(uint32_t input_base10, 86 bool Remb::AppliesToMany(const std::vector<uint32_t>& ssrcs) {
35 uint8_t bits_mantissa, 87 if (ssrcs_.size() + ssrcs.size() > kMaxNumberOfSsrcs) {
36 uint32_t* mantissa, 88 LOG(LS_WARNING) << "Not enough space for all given SSRCs.";
37 uint8_t* exp) { 89 return false;
38 // input_base10 = mantissa * 2^exp
39 assert(bits_mantissa <= 32);
40 uint32_t mantissa_max = (1 << bits_mantissa) - 1;
41 uint8_t exponent = 0;
42 for (uint32_t i = 0; i < 64; ++i) {
43 if (input_base10 <= (mantissa_max << i)) {
44 exponent = i;
45 break;
46 }
47 } 90 }
48 *exp = exponent; 91 // Append.
49 *mantissa = (input_base10 >> exponent); 92 ssrcs_.insert(ssrcs_.end(), ssrcs.begin(), ssrcs.end());
93 return true;
50 } 94 }
51 95
52 // Receiver Estimated Max Bitrate (REMB) (draft-alvestrand-rmcat-remb).
53 //
54 // 0 1 2 3
55 // 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
56 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57 // |V=2|P| FMT=15 | PT=206 | length |
58 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59 // | SSRC of packet sender |
60 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61 // | SSRC of media source |
62 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63 // | Unique identifier 'R' 'E' 'M' 'B' |
64 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65 // | Num SSRC | BR Exp | BR Mantissa |
66 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67 // | SSRC feedback |
68 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69 // | ... |
70 void CreateRemb(const RTCPPacketPSFBAPP& remb,
71 const RTCPPacketPSFBREMBItem& remb_item,
72 uint8_t* buffer,
73 size_t* pos) {
74 uint32_t mantissa = 0;
75 uint8_t exp = 0;
76 ComputeMantissaAnd6bitBase2Exponent(remb_item.BitRate, 18, &mantissa, &exp);
77
78 AssignUWord32(buffer, pos, remb.SenderSSRC);
79 AssignUWord32(buffer, pos, kUnusedMediaSourceSsrc0);
80 AssignUWord8(buffer, pos, 'R');
81 AssignUWord8(buffer, pos, 'E');
82 AssignUWord8(buffer, pos, 'M');
83 AssignUWord8(buffer, pos, 'B');
84 AssignUWord8(buffer, pos, remb_item.NumberOfSSRCs);
85 AssignUWord8(buffer, pos, (exp << 2) + ((mantissa >> 16) & 0x03));
86 AssignUWord8(buffer, pos, mantissa >> 8);
87 AssignUWord8(buffer, pos, mantissa);
88 for (uint8_t i = 0; i < remb_item.NumberOfSSRCs; ++i) {
89 AssignUWord32(buffer, pos, remb_item.SSRCs[i]);
90 }
91 }
92 } // namespace
93
94 bool Remb::Create(uint8_t* packet, 96 bool Remb::Create(uint8_t* packet,
95 size_t* index, 97 size_t* index,
96 size_t max_length, 98 size_t max_length,
97 RtcpPacket::PacketReadyCallback* callback) const { 99 RtcpPacket::PacketReadyCallback* callback) const {
98 while (*index + BlockLength() > max_length) { 100 while (*index + BlockLength() > max_length) {
99 if (!OnBufferFull(packet, index, callback)) 101 if (!OnBufferFull(packet, index, callback))
100 return false; 102 return false;
101 } 103 }
102 const uint8_t kFmt = 15; 104 size_t index_end = *index + BlockLength();
103 CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index); 105 CreateHeader(kFeedbackMessageType, kPacketType, HeaderLength(), packet,
104 CreateRemb(remb_, remb_item_, packet, index); 106 index);
107 RTC_DCHECK_EQ(Psfb::media_ssrc(), 0u);
åsapersson 2016/01/20 15:33:13 RTC_DCHECK_EQ(0u, ...
danilchap 2016/01/20 16:13:19 Done.
108 CreateCommonFeedback(packet + *index);
109 *index += kCommonFeedbackLength;
110
111 ByteWriter<uint32_t>::WriteBigEndian(packet + *index, kSignature);
112 *index += sizeof(uint32_t);
113 const uint32_t kMaxMantissa = 0x3ffff; // 18 bits.
114 uint32_t mantissa = bitrate_;
115 uint8_t exponenta = 0;
116 while (mantissa > kMaxMantissa) {
117 mantissa >>= 1;
118 ++exponenta;
119 }
120 packet[(*index)++] = ssrcs_.size();
121 packet[(*index)++] = (exponenta << 2) | (mantissa >> 16);
122 ByteWriter<uint16_t>::WriteBigEndian(packet + *index, mantissa & 0xffff);
123 *index += sizeof(uint16_t);
124
125 for (uint32_t ssrc : ssrcs_) {
126 ByteWriter<uint32_t>::WriteBigEndian(packet + *index, ssrc);
127 *index += sizeof(uint32_t);
128 }
129 RTC_DCHECK_EQ(index_end, *index);
105 return true; 130 return true;
106 } 131 }
107 132
108 void Remb::AppliesTo(uint32_t ssrc) {
109 if (remb_item_.NumberOfSSRCs >= kMaxNumberOfSsrcs) {
110 LOG(LS_WARNING) << "Max number of REMB feedback SSRCs reached.";
111 return;
112 }
113 remb_item_.SSRCs[remb_item_.NumberOfSSRCs++] = ssrc;
114 }
115
116 } // namespace rtcp 133 } // namespace rtcp
117 } // namespace webrtc 134 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698