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::kBtDlrr; | 19 using webrtc::RTCPUtility::kBtDlrr; |
20 using webrtc::RTCPUtility::kBtReceiverReferenceTime; | 20 using webrtc::RTCPUtility::kBtReceiverReferenceTime; |
21 using webrtc::RTCPUtility::kBtVoipMetric; | 21 using webrtc::RTCPUtility::kBtVoipMetric; |
22 | 22 |
23 using webrtc::RTCPUtility::PT_APP; | 23 using webrtc::RTCPUtility::PT_APP; |
24 using webrtc::RTCPUtility::PT_IJ; | 24 using webrtc::RTCPUtility::PT_IJ; |
25 using webrtc::RTCPUtility::PT_PSFB; | 25 using webrtc::RTCPUtility::PT_PSFB; |
26 using webrtc::RTCPUtility::PT_RTPFB; | 26 using webrtc::RTCPUtility::PT_RTPFB; |
27 using webrtc::RTCPUtility::PT_SDES; | 27 using webrtc::RTCPUtility::PT_SDES; |
28 using webrtc::RTCPUtility::PT_SR; | |
29 using webrtc::RTCPUtility::PT_XR; | 28 using webrtc::RTCPUtility::PT_XR; |
30 | 29 |
31 using webrtc::RTCPUtility::RTCPPacketAPP; | 30 using webrtc::RTCPUtility::RTCPPacketAPP; |
32 using webrtc::RTCPUtility::RTCPPacketPSFBAPP; | 31 using webrtc::RTCPUtility::RTCPPacketPSFBAPP; |
33 using webrtc::RTCPUtility::RTCPPacketPSFBFIR; | 32 using webrtc::RTCPUtility::RTCPPacketPSFBFIR; |
34 using webrtc::RTCPUtility::RTCPPacketPSFBFIRItem; | 33 using webrtc::RTCPUtility::RTCPPacketPSFBFIRItem; |
35 using webrtc::RTCPUtility::RTCPPacketPSFBREMBItem; | 34 using webrtc::RTCPUtility::RTCPPacketPSFBREMBItem; |
36 using webrtc::RTCPUtility::RTCPPacketPSFBRPSI; | 35 using webrtc::RTCPUtility::RTCPPacketPSFBRPSI; |
37 using webrtc::RTCPUtility::RTCPPacketPSFBSLI; | 36 using webrtc::RTCPUtility::RTCPPacketPSFBSLI; |
38 using webrtc::RTCPUtility::RTCPPacketPSFBSLIItem; | 37 using webrtc::RTCPUtility::RTCPPacketPSFBSLIItem; |
39 using webrtc::RTCPUtility::RTCPPacketReportBlockItem; | |
40 using webrtc::RTCPUtility::RTCPPacketRTPFBNACK; | 38 using webrtc::RTCPUtility::RTCPPacketRTPFBNACK; |
41 using webrtc::RTCPUtility::RTCPPacketRTPFBNACKItem; | 39 using webrtc::RTCPUtility::RTCPPacketRTPFBNACKItem; |
42 using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBN; | 40 using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBN; |
43 using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBNItem; | 41 using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBNItem; |
44 using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBR; | 42 using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBR; |
45 using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBRItem; | 43 using webrtc::RTCPUtility::RTCPPacketRTPFBTMMBRItem; |
46 using webrtc::RTCPUtility::RTCPPacketSR; | |
47 using webrtc::RTCPUtility::RTCPPacketXRDLRRReportBlockItem; | 44 using webrtc::RTCPUtility::RTCPPacketXRDLRRReportBlockItem; |
48 using webrtc::RTCPUtility::RTCPPacketXR; | 45 using webrtc::RTCPUtility::RTCPPacketXR; |
49 | 46 |
50 namespace webrtc { | 47 namespace webrtc { |
51 namespace rtcp { | 48 namespace rtcp { |
52 namespace { | 49 namespace { |
53 // Unused SSRC of media source, set to 0. | 50 // Unused SSRC of media source, set to 0. |
54 const uint32_t kUnusedMediaSourceSsrc0 = 0; | 51 const uint32_t kUnusedMediaSourceSsrc0 = 0; |
55 | 52 |
56 void AssignUWord8(uint8_t* buffer, size_t* offset, uint8_t value) { | 53 void AssignUWord8(uint8_t* buffer, size_t* offset, uint8_t value) { |
(...skipping 23 matching lines...) Expand all Loading... |
80 for (uint32_t i = 0; i < 64; ++i) { | 77 for (uint32_t i = 0; i < 64; ++i) { |
81 if (input_base10 <= (mantissa_max << i)) { | 78 if (input_base10 <= (mantissa_max << i)) { |
82 exponent = i; | 79 exponent = i; |
83 break; | 80 break; |
84 } | 81 } |
85 } | 82 } |
86 *exp = exponent; | 83 *exp = exponent; |
87 *mantissa = (input_base10 >> exponent); | 84 *mantissa = (input_base10 >> exponent); |
88 } | 85 } |
89 | 86 |
90 // Sender report (SR) (RFC 3550). | |
91 // 0 1 2 3 | |
92 // 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 | |
93 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
94 // |V=2|P| RC | PT=SR=200 | length | | |
95 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
96 // | SSRC of sender | | |
97 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | |
98 // | NTP timestamp, most significant word | | |
99 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
100 // | NTP timestamp, least significant word | | |
101 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
102 // | RTP timestamp | | |
103 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
104 // | sender's packet count | | |
105 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
106 // | sender's octet count | | |
107 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | |
108 | |
109 void CreateSenderReport(const RTCPPacketSR& sr, | |
110 uint8_t* buffer, | |
111 size_t* pos) { | |
112 AssignUWord32(buffer, pos, sr.SenderSSRC); | |
113 AssignUWord32(buffer, pos, sr.NTPMostSignificant); | |
114 AssignUWord32(buffer, pos, sr.NTPLeastSignificant); | |
115 AssignUWord32(buffer, pos, sr.RTPTimestamp); | |
116 AssignUWord32(buffer, pos, sr.SenderPacketCount); | |
117 AssignUWord32(buffer, pos, sr.SenderOctetCount); | |
118 } | |
119 | |
120 // Report block (RFC 3550). | |
121 // | |
122 // 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 | |
123 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | |
124 // | SSRC_1 (SSRC of first source) | | |
125 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
126 // | fraction lost | cumulative number of packets lost | | |
127 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
128 // | extended highest sequence number received | | |
129 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
130 // | interarrival jitter | | |
131 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
132 // | last SR (LSR) | | |
133 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
134 // | delay since last SR (DLSR) | | |
135 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | |
136 | |
137 void CreateReportBlocks(const std::vector<ReportBlock>& blocks, | |
138 uint8_t* buffer, | |
139 size_t* pos) { | |
140 for (const ReportBlock& block : blocks) { | |
141 block.Create(buffer + *pos); | |
142 *pos += ReportBlock::kLength; | |
143 } | |
144 } | |
145 | |
146 // Source Description (SDES) (RFC 3550). | 87 // Source Description (SDES) (RFC 3550). |
147 // | 88 // |
148 // 0 1 2 3 | 89 // 0 1 2 3 |
149 // 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 | 90 // 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 |
150 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 91 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
151 // header |V=2|P| SC | PT=SDES=202 | length | | 92 // header |V=2|P| SC | PT=SDES=202 | length | |
152 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | 93 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
153 // chunk | SSRC/CSRC_1 | | 94 // chunk | SSRC/CSRC_1 | |
154 // 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 95 // 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
155 // | SDES items | | 96 // | SDES items | |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 size_t* index, | 425 size_t* index, |
485 size_t max_length, | 426 size_t max_length, |
486 RtcpPacket::PacketReadyCallback* callback) const { | 427 RtcpPacket::PacketReadyCallback* callback) const { |
487 return true; | 428 return true; |
488 } | 429 } |
489 | 430 |
490 size_t Empty::BlockLength() const { | 431 size_t Empty::BlockLength() const { |
491 return 0; | 432 return 0; |
492 } | 433 } |
493 | 434 |
494 bool SenderReport::Create(uint8_t* packet, | |
495 size_t* index, | |
496 size_t max_length, | |
497 RtcpPacket::PacketReadyCallback* callback) const { | |
498 while (*index + BlockLength() > max_length) { | |
499 if (!OnBufferFull(packet, index, callback)) | |
500 return false; | |
501 } | |
502 CreateHeader(sr_.NumberOfReportBlocks, PT_SR, HeaderLength(), packet, index); | |
503 CreateSenderReport(sr_, packet, index); | |
504 CreateReportBlocks(report_blocks_, packet, index); | |
505 return true; | |
506 } | |
507 | |
508 bool SenderReport::WithReportBlock(const ReportBlock& block) { | |
509 if (report_blocks_.size() >= kMaxNumberOfReportBlocks) { | |
510 LOG(LS_WARNING) << "Max report blocks reached."; | |
511 return false; | |
512 } | |
513 report_blocks_.push_back(block); | |
514 sr_.NumberOfReportBlocks = report_blocks_.size(); | |
515 return true; | |
516 } | |
517 | |
518 bool Sdes::Create(uint8_t* packet, | 435 bool Sdes::Create(uint8_t* packet, |
519 size_t* index, | 436 size_t* index, |
520 size_t max_length, | 437 size_t max_length, |
521 RtcpPacket::PacketReadyCallback* callback) const { | 438 RtcpPacket::PacketReadyCallback* callback) const { |
522 assert(!chunks_.empty()); | 439 assert(!chunks_.empty()); |
523 while (*index + BlockLength() > max_length) { | 440 while (*index + BlockLength() > max_length) { |
524 if (!OnBufferFull(packet, index, callback)) | 441 if (!OnBufferFull(packet, index, callback)) |
525 return false; | 442 return false; |
526 } | 443 } |
527 CreateHeader(chunks_.size(), PT_SDES, HeaderLength(), packet, index); | 444 CreateHeader(chunks_.size(), PT_SDES, HeaderLength(), packet, index); |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 return length_; | 699 return length_; |
783 } | 700 } |
784 | 701 |
785 void RawPacket::SetLength(size_t length) { | 702 void RawPacket::SetLength(size_t length) { |
786 assert(length <= buffer_length_); | 703 assert(length <= buffer_length_); |
787 length_ = length; | 704 length_ = length; |
788 } | 705 } |
789 | 706 |
790 } // namespace rtcp | 707 } // namespace rtcp |
791 } // namespace webrtc | 708 } // namespace webrtc |
OLD | NEW |