| 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 |