OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 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.h" | 11 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h" |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 | 14 |
15 #include "webrtc/base/checks.h" | 15 #include "webrtc/base/checks.h" |
16 #include "webrtc/base/logging.h" | 16 #include "webrtc/base/logging.h" |
17 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 17 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
18 | 18 |
19 using webrtc::RTCPUtility::PT_APP; | 19 using webrtc::RTCPUtility::PT_APP; |
20 using webrtc::RTCPUtility::PT_IJ; | 20 using webrtc::RTCPUtility::PT_IJ; |
21 using webrtc::RTCPUtility::PT_RTPFB; | 21 using webrtc::RTCPUtility::PT_RTPFB; |
22 using webrtc::RTCPUtility::PT_SDES; | |
23 using webrtc::RTCPUtility::PT_SR; | 22 using webrtc::RTCPUtility::PT_SR; |
24 | 23 |
25 using webrtc::RTCPUtility::RTCPPacketAPP; | 24 using webrtc::RTCPUtility::RTCPPacketAPP; |
26 using webrtc::RTCPUtility::RTCPPacketReportBlockItem; | 25 using webrtc::RTCPUtility::RTCPPacketReportBlockItem; |
27 using webrtc::RTCPUtility::RTCPPacketRTPFBNACK; | 26 using webrtc::RTCPUtility::RTCPPacketRTPFBNACK; |
28 using webrtc::RTCPUtility::RTCPPacketRTPFBNACKItem; | 27 using webrtc::RTCPUtility::RTCPPacketRTPFBNACKItem; |
29 using webrtc::RTCPUtility::RTCPPacketSR; | 28 using webrtc::RTCPUtility::RTCPPacketSR; |
30 | 29 |
31 namespace webrtc { | 30 namespace webrtc { |
32 namespace rtcp { | 31 namespace rtcp { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | 90 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
92 | 91 |
93 void CreateReportBlocks(const std::vector<ReportBlock>& blocks, | 92 void CreateReportBlocks(const std::vector<ReportBlock>& blocks, |
94 uint8_t* buffer, | 93 uint8_t* buffer, |
95 size_t* pos) { | 94 size_t* pos) { |
96 for (const ReportBlock& block : blocks) { | 95 for (const ReportBlock& block : blocks) { |
97 block.Create(buffer + *pos); | 96 block.Create(buffer + *pos); |
98 *pos += ReportBlock::kLength; | 97 *pos += ReportBlock::kLength; |
99 } | 98 } |
100 } | 99 } |
101 | |
102 // Source Description (SDES) (RFC 3550). | |
103 // | |
104 // 0 1 2 3 | |
105 // 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 | |
106 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
107 // header |V=2|P| SC | PT=SDES=202 | length | | |
108 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | |
109 // chunk | SSRC/CSRC_1 | | |
110 // 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
111 // | SDES items | | |
112 // | ... | | |
113 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | |
114 // chunk | SSRC/CSRC_2 | | |
115 // 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
116 // | SDES items | | |
117 // | ... | | |
118 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | |
119 // | |
120 // Canonical End-Point Identifier SDES Item (CNAME) | |
121 // | |
122 // 0 1 2 3 | |
123 // 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 | |
124 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
125 // | CNAME=1 | length | user and domain name ... | |
126 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
127 | |
128 void CreateSdes(const std::vector<Sdes::Chunk>& chunks, | |
129 uint8_t* buffer, | |
130 size_t* pos) { | |
131 const uint8_t kSdesItemType = 1; | |
132 for (std::vector<Sdes::Chunk>::const_iterator it = chunks.begin(); | |
133 it != chunks.end(); ++it) { | |
134 AssignUWord32(buffer, pos, (*it).ssrc); | |
135 AssignUWord8(buffer, pos, kSdesItemType); | |
136 AssignUWord8(buffer, pos, (*it).name.length()); | |
137 memcpy(buffer + *pos, (*it).name.data(), (*it).name.length()); | |
138 *pos += (*it).name.length(); | |
139 memset(buffer + *pos, 0, (*it).null_octets); | |
140 *pos += (*it).null_octets; | |
141 } | |
142 } | |
143 } // namespace | 100 } // namespace |
144 | 101 |
145 void RtcpPacket::Append(RtcpPacket* packet) { | 102 void RtcpPacket::Append(RtcpPacket* packet) { |
146 assert(packet); | 103 assert(packet); |
147 appended_packets_.push_back(packet); | 104 appended_packets_.push_back(packet); |
148 } | 105 } |
149 | 106 |
150 rtc::scoped_ptr<RawPacket> RtcpPacket::Build() const { | 107 rtc::scoped_ptr<RawPacket> RtcpPacket::Build() const { |
151 size_t length = 0; | 108 size_t length = 0; |
152 rtc::scoped_ptr<RawPacket> packet(new RawPacket(IP_PACKET_SIZE)); | 109 rtc::scoped_ptr<RawPacket> packet(new RawPacket(IP_PACKET_SIZE)); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 bool SenderReport::WithReportBlock(const ReportBlock& block) { | 212 bool SenderReport::WithReportBlock(const ReportBlock& block) { |
256 if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { | 213 if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { |
257 LOG(LS_WARNING) << "Max report blocks reached."; | 214 LOG(LS_WARNING) << "Max report blocks reached."; |
258 return false; | 215 return false; |
259 } | 216 } |
260 report_blocks_.push_back(block); | 217 report_blocks_.push_back(block); |
261 sr_.NumberOfReportBlocks = report_blocks_.size(); | 218 sr_.NumberOfReportBlocks = report_blocks_.size(); |
262 return true; | 219 return true; |
263 } | 220 } |
264 | 221 |
265 bool Sdes::Create(uint8_t* packet, | |
266 size_t* index, | |
267 size_t max_length, | |
268 RtcpPacket::PacketReadyCallback* callback) const { | |
269 assert(!chunks_.empty()); | |
270 while (*index + BlockLength() > max_length) { | |
271 if (!OnBufferFull(packet, index, callback)) | |
272 return false; | |
273 } | |
274 CreateHeader(chunks_.size(), PT_SDES, HeaderLength(), packet, index); | |
275 CreateSdes(chunks_, packet, index); | |
276 return true; | |
277 } | |
278 | |
279 bool Sdes::WithCName(uint32_t ssrc, const std::string& cname) { | |
280 assert(cname.length() <= 0xff); | |
281 if (chunks_.size() >= kMaxNumberOfChunks) { | |
282 LOG(LS_WARNING) << "Max SDES chunks reached."; | |
283 return false; | |
284 } | |
285 // In each chunk, the list of items must be terminated by one or more null | |
286 // octets. The next chunk must start on a 32-bit boundary. | |
287 // CNAME (1 byte) | length (1 byte) | name | padding. | |
288 int null_octets = 4 - ((2 + cname.length()) % 4); | |
289 Chunk chunk; | |
290 chunk.ssrc = ssrc; | |
291 chunk.name = cname; | |
292 chunk.null_octets = null_octets; | |
293 chunks_.push_back(chunk); | |
294 return true; | |
295 } | |
296 | |
297 size_t Sdes::BlockLength() const { | |
298 // Header (4 bytes). | |
299 // Chunk: | |
300 // SSRC/CSRC (4 bytes) | CNAME (1 byte) | length (1 byte) | name | padding. | |
301 size_t length = kHeaderLength; | |
302 for (const Chunk& chunk : chunks_) | |
303 length += 6 + chunk.name.length() + chunk.null_octets; | |
304 assert(length % 4 == 0); | |
305 return length; | |
306 } | |
307 | |
308 RawPacket::RawPacket(size_t buffer_length) | 222 RawPacket::RawPacket(size_t buffer_length) |
309 : buffer_length_(buffer_length), length_(0) { | 223 : buffer_length_(buffer_length), length_(0) { |
310 buffer_.reset(new uint8_t[buffer_length]); | 224 buffer_.reset(new uint8_t[buffer_length]); |
311 } | 225 } |
312 | 226 |
313 RawPacket::RawPacket(const uint8_t* packet, size_t packet_length) | 227 RawPacket::RawPacket(const uint8_t* packet, size_t packet_length) |
314 : buffer_length_(packet_length), length_(packet_length) { | 228 : buffer_length_(packet_length), length_(packet_length) { |
315 buffer_.reset(new uint8_t[packet_length]); | 229 buffer_.reset(new uint8_t[packet_length]); |
316 memcpy(buffer_.get(), packet, packet_length); | 230 memcpy(buffer_.get(), packet, packet_length); |
317 } | 231 } |
(...skipping 14 matching lines...) Expand all Loading... |
332 return length_; | 246 return length_; |
333 } | 247 } |
334 | 248 |
335 void RawPacket::SetLength(size_t length) { | 249 void RawPacket::SetLength(size_t length) { |
336 assert(length <= buffer_length_); | 250 assert(length <= buffer_length_); |
337 length_ = length; | 251 length_ = length; |
338 } | 252 } |
339 | 253 |
340 } // namespace rtcp | 254 } // namespace rtcp |
341 } // namespace webrtc | 255 } // namespace webrtc |
OLD | NEW |