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

Side by Side Diff: media/cast/transport/rtcp/rtcp_builder.cc

Issue 109413004: Cast:Adding cast_transport_config and cleaning up (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nits Created 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/cast/transport/rtcp/rtcp_builder.h" 5 #include "media/cast/transport/rtcp/rtcp_builder.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "media/cast/rtcp/rtcp_utility.h"
13 #include "media/cast/transport/cast_transport_defines.h" 12 #include "media/cast/transport/cast_transport_defines.h"
14 #include "media/cast/transport/pacing/paced_sender.h" 13 #include "media/cast/transport/pacing/paced_sender.h"
15 #include "net/base/big_endian.h" 14 #include "net/base/big_endian.h"
16 15
17 static const size_t kRtcpCastLogHeaderSize = 12; 16 static const size_t kRtcpCastLogHeaderSize = 12;
18 static const size_t kRtcpSenderFrameLogSize = 4; 17 static const size_t kRtcpSenderFrameLogSize = 4;
19 18
20 namespace media { 19 namespace media {
21 namespace cast { 20 namespace cast {
22 namespace transport { 21 namespace transport {
23 22
23 namespace {
24 // RFC 3550 page 44, including end null.
25 static const size_t kRtcpCnameSize = 256;
26 static const uint32 kCast = ('C' << 24) + ('A' << 16) + ('S' << 8) + 'T';
27 static const uint8 kSenderLogSubtype = 1;
28 };
29
24 RtcpBuilder::RtcpBuilder(PacedPacketSender* outgoing_transport, 30 RtcpBuilder::RtcpBuilder(PacedPacketSender* outgoing_transport,
25 uint32 sending_ssrc, 31 uint32 sending_ssrc,
26 const std::string& c_name) 32 const std::string& c_name)
27 : ssrc_(sending_ssrc), 33 : ssrc_(sending_ssrc),
28 c_name_(c_name), 34 c_name_(c_name),
29 transport_(outgoing_transport) { 35 transport_(outgoing_transport) {
30 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config"; 36 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config";
31 } 37 }
32 38
33 RtcpBuilder::~RtcpBuilder() {} 39 RtcpBuilder::~RtcpBuilder() {}
34 40
35 void RtcpBuilder::SendRtcpFromRtpSender(uint32 packet_type_flags, 41 void RtcpBuilder::SendRtcpFromRtpSender(uint32 packet_type_flags,
36 const RtcpSenderInfo* sender_info, 42 const RtcpSenderInfo* sender_info,
37 const RtcpDlrrReportBlock* dlrr, 43 const RtcpDlrrReportBlock* dlrr,
38 RtcpSenderLogMessage* sender_log) { 44 RtcpSenderLogMessage* sender_log) {
39 if (packet_type_flags & kRtcpRr || 45 if (packet_type_flags & kRtcpRr ||
40 packet_type_flags & kRtcpPli || 46 packet_type_flags & kRtcpPli ||
41 packet_type_flags & kRtcpRrtr || 47 packet_type_flags & kRtcpRrtr ||
42 packet_type_flags & kRtcpCast || 48 packet_type_flags & kRtcpCast ||
43 packet_type_flags & kRtcpReceiverLog || 49 packet_type_flags & kRtcpReceiverLog ||
44 packet_type_flags & kRtcpRpsi || 50 packet_type_flags & kRtcpRpsi ||
45 packet_type_flags & kRtcpRemb || 51 packet_type_flags & kRtcpRemb ||
46 packet_type_flags & kRtcpNack) { 52 packet_type_flags & kRtcpNack) {
47 NOTREACHED() << "Invalid argument"; 53 NOTREACHED() << "Invalid argument";
48 } 54 }
49 55
50 std::vector<uint8> packet; 56 std::vector<uint8> packet;
51 packet.reserve(kIpPacketSize); 57 packet.reserve(kMaxIpPacketSize);
52 if (packet_type_flags & kRtcpSr) { 58 if (packet_type_flags & kRtcpSr) {
53 DCHECK(sender_info) << "Invalid argument"; 59 DCHECK(sender_info) << "Invalid argument";
54 BuildSR(*sender_info, NULL, &packet); 60 BuildSR(*sender_info, NULL, &packet);
55 BuildSdec(&packet); 61 BuildSdec(&packet);
56 } 62 }
57 if (packet_type_flags & kRtcpBye) { 63 if (packet_type_flags & kRtcpBye) {
58 BuildBye(&packet); 64 BuildBye(&packet);
59 } 65 }
60 if (packet_type_flags & kRtcpDlrr) { 66 if (packet_type_flags & kRtcpDlrr) {
61 DCHECK(dlrr) << "Invalid argument"; 67 DCHECK(dlrr) << "Invalid argument";
62 BuildDlrrRb(dlrr, &packet); 68 BuildDlrrRb(dlrr, &packet);
63 } 69 }
64 if (packet_type_flags & kRtcpSenderLog) { 70 if (packet_type_flags & kRtcpSenderLog) {
65 DCHECK(sender_log) << "Invalid argument"; 71 DCHECK(sender_log) << "Invalid argument";
66 BuildSenderLog(sender_log, &packet); 72 BuildSenderLog(sender_log, &packet);
67 } 73 }
68 if (packet.empty()) 74 if (packet.empty())
69 return; // Sanity don't send empty packets. 75 return; // Sanity - don't send empty packets.
70 76
71 transport_->SendRtcpPacket(packet); 77 transport_->SendRtcpPacket(packet);
72 } 78 }
73 79
74 void RtcpBuilder::BuildSR(const RtcpSenderInfo& sender_info, 80 void RtcpBuilder::BuildSR(const RtcpSenderInfo& sender_info,
75 const RtcpReportBlock* report_block, 81 const RtcpReportBlock* report_block,
76 std::vector<uint8>* packet) const { 82 std::vector<uint8>* packet) const {
77 // Sender report. 83 // Sender report.
78 size_t start_size = packet->size(); 84 size_t start_size = packet->size();
79 DCHECK_LT(start_size + 52, kIpPacketSize) << "Not enough buffer space"; 85 DCHECK_LT(start_size + 52, kMaxIpPacketSize) << "Not enough buffer space";
80 if (start_size + 52 > kIpPacketSize) return; 86 if (start_size + 52 > kMaxIpPacketSize) return;
81 87
82 uint16 number_of_rows = (report_block) ? 12 : 6; 88 uint16 number_of_rows = (report_block) ? 12 : 6;
83 packet->resize(start_size + 28); 89 packet->resize(start_size + 28);
84 90
85 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 28); 91 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 28);
86 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); 92 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0));
87 big_endian_writer.WriteU8(kPacketTypeSenderReport); 93 big_endian_writer.WriteU8(kPacketTypeSenderReport);
88 big_endian_writer.WriteU16(number_of_rows); 94 big_endian_writer.WriteU16(number_of_rows);
89 big_endian_writer.WriteU32(ssrc_); 95 big_endian_writer.WriteU32(ssrc_);
90 big_endian_writer.WriteU32(sender_info.ntp_seconds); 96 big_endian_writer.WriteU32(sender_info.ntp_seconds);
91 big_endian_writer.WriteU32(sender_info.ntp_fraction); 97 big_endian_writer.WriteU32(sender_info.ntp_fraction);
92 big_endian_writer.WriteU32(sender_info.rtp_timestamp); 98 big_endian_writer.WriteU32(sender_info.rtp_timestamp);
93 big_endian_writer.WriteU32(sender_info.send_packet_count); 99 big_endian_writer.WriteU32(sender_info.send_packet_count);
94 big_endian_writer.WriteU32(static_cast<uint32>(sender_info.send_octet_count)); 100 big_endian_writer.WriteU32(static_cast<uint32>(sender_info.send_octet_count));
95 101
96 if (report_block) { 102 if (report_block) {
97 AddReportBlocks(*report_block, packet); // Adds 24 bytes. 103 AddReportBlocks(*report_block, packet); // Adds 24 bytes.
98 } 104 }
99 } 105 }
100 106
101 void RtcpBuilder::AddReportBlocks(const RtcpReportBlock& report_block, 107 void RtcpBuilder::AddReportBlocks(const RtcpReportBlock& report_block,
102 std::vector<uint8>* packet) const { 108 std::vector<uint8>* packet) const {
103 size_t start_size = packet->size(); 109 size_t start_size = packet->size();
104 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space"; 110 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space";
105 if (start_size + 24 > kIpPacketSize) return; 111 if (start_size + 24 > kMaxIpPacketSize) return;
106 112
107 packet->resize(start_size + 24); 113 packet->resize(start_size + 24);
108 114
109 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); 115 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24);
110 big_endian_writer.WriteU32(report_block.media_ssrc); 116 big_endian_writer.WriteU32(report_block.media_ssrc);
111 big_endian_writer.WriteU8(report_block.fraction_lost); 117 big_endian_writer.WriteU8(report_block.fraction_lost);
112 big_endian_writer.WriteU8(report_block.cumulative_lost >> 16); 118 big_endian_writer.WriteU8(report_block.cumulative_lost >> 16);
113 big_endian_writer.WriteU8(report_block.cumulative_lost >> 8); 119 big_endian_writer.WriteU8(report_block.cumulative_lost >> 8);
114 big_endian_writer.WriteU8(report_block.cumulative_lost); 120 big_endian_writer.WriteU8(report_block.cumulative_lost);
115 121
116 // Extended highest seq_no, contain the highest sequence number received. 122 // Extended highest seq_no, contain the highest sequence number received.
117 big_endian_writer.WriteU32(report_block.extended_high_sequence_number); 123 big_endian_writer.WriteU32(report_block.extended_high_sequence_number);
118 big_endian_writer.WriteU32(report_block.jitter); 124 big_endian_writer.WriteU32(report_block.jitter);
119 125
120 // Last SR timestamp; our NTP time when we received the last report. 126 // Last SR timestamp; our NTP time when we received the last report.
121 // This is the value that we read from the send report packet not when we 127 // This is the value that we read from the send report packet not when we
122 // received it. 128 // received it.
123 big_endian_writer.WriteU32(report_block.last_sr); 129 big_endian_writer.WriteU32(report_block.last_sr);
124 130
125 // Delay since last received report, time since we received the report. 131 // Delay since last received report, time since we received the report.
126 big_endian_writer.WriteU32(report_block.delay_since_last_sr); 132 big_endian_writer.WriteU32(report_block.delay_since_last_sr);
127 } 133 }
128 134
129 void RtcpBuilder::BuildSdec(std::vector<uint8>* packet) const { 135 void RtcpBuilder::BuildSdec(std::vector<uint8>* packet) const {
130 size_t start_size = packet->size(); 136 size_t start_size = packet->size();
131 DCHECK_LT(start_size + 12 + c_name_.length(), kIpPacketSize) 137 DCHECK_LT(start_size + 12 + c_name_.length(), kMaxIpPacketSize)
132 << "Not enough buffer space"; 138 << "Not enough buffer space";
133 if (start_size + 12 > kIpPacketSize) return; 139 if (start_size + 12 > kMaxIpPacketSize) return;
134 140
135 // SDES Source Description. 141 // SDES Source Description.
136 packet->resize(start_size + 10); 142 packet->resize(start_size + 10);
137 143
138 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 10); 144 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 10);
139 // We always need to add one SDES CNAME. 145 // We always need to add one SDES CNAME.
140 big_endian_writer.WriteU8(0x80 + 1); 146 big_endian_writer.WriteU8(0x80 + 1);
141 big_endian_writer.WriteU8(kPacketTypeSdes); 147 big_endian_writer.WriteU8(kPacketTypeSdes);
142 148
143 // Handle SDES length later on. 149 // Handle SDES length later on.
(...skipping 20 matching lines...) Expand all
164 } 170 }
165 sdes_length += padding; 171 sdes_length += padding;
166 172
167 // In 32-bit words minus one and we don't count the header. 173 // In 32-bit words minus one and we don't count the header.
168 uint8 buffer_length = static_cast<uint8>((sdes_length / 4) - 1); 174 uint8 buffer_length = static_cast<uint8>((sdes_length / 4) - 1);
169 (*packet)[sdes_length_position] = buffer_length; 175 (*packet)[sdes_length_position] = buffer_length;
170 } 176 }
171 177
172 void RtcpBuilder::BuildBye(std::vector<uint8>* packet) const { 178 void RtcpBuilder::BuildBye(std::vector<uint8>* packet) const {
173 size_t start_size = packet->size(); 179 size_t start_size = packet->size();
174 DCHECK_LT(start_size + 8, kIpPacketSize) << "Not enough buffer space"; 180 DCHECK_LT(start_size + 8, kMaxIpPacketSize) << "Not enough buffer space";
175 if (start_size + 8 > kIpPacketSize) return; 181 if (start_size + 8 > kMaxIpPacketSize) return;
176 182
177 packet->resize(start_size + 8); 183 packet->resize(start_size + 8);
178 184
179 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); 185 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8);
180 big_endian_writer.WriteU8(0x80 + 1); 186 big_endian_writer.WriteU8(0x80 + 1);
181 big_endian_writer.WriteU8(kPacketTypeBye); 187 big_endian_writer.WriteU8(kPacketTypeBye);
182 big_endian_writer.WriteU16(1); // Length. 188 big_endian_writer.WriteU16(1); // Length.
183 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 189 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
184 } 190 }
185 191
186 /* 192 /*
187 0 1 2 3 193 0 1 2 3
188 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 194 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
189 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 195 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
190 |V=2|P|reserved | PT=XR=207 | length | 196 |V=2|P|reserved | PT=XR=207 | length |
191 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 197 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
192 | SSRC | 198 | SSRC |
193 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 199 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
194 | BT=5 | reserved | block length | 200 | BT=5 | reserved | block length |
195 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 201 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
196 | SSRC_1 (SSRC of first receiver) | sub- 202 | SSRC_1 (SSRC of first receiver) | sub-
197 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block 203 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
198 | last RR (LRR) | 1 204 | last RR (LRR) | 1
199 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 205 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
200 | delay since last RR (DLRR) | 206 | delay since last RR (DLRR) |
201 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 207 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
202 */ 208 */
203 void RtcpBuilder::BuildDlrrRb(const RtcpDlrrReportBlock* dlrr, 209 void RtcpBuilder::BuildDlrrRb(const RtcpDlrrReportBlock* dlrr,
204 std::vector<uint8>* packet) const { 210 std::vector<uint8>* packet) const {
205 size_t start_size = packet->size(); 211 size_t start_size = packet->size();
206 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space"; 212 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space";
207 if (start_size + 24 > kIpPacketSize) return; 213 if (start_size + 24 > kMaxIpPacketSize) return;
208 214
209 packet->resize(start_size + 24); 215 packet->resize(start_size + 24);
210 216
211 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); 217 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24);
212 big_endian_writer.WriteU8(0x80); 218 big_endian_writer.WriteU8(0x80);
213 big_endian_writer.WriteU8(kPacketTypeXr); 219 big_endian_writer.WriteU8(kPacketTypeXr);
214 big_endian_writer.WriteU16(5); // Length. 220 big_endian_writer.WriteU16(5); // Length.
215 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 221 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
216 big_endian_writer.WriteU8(5); // Add block type. 222 big_endian_writer.WriteU8(5); // Add block type.
217 big_endian_writer.WriteU8(0); // Add reserved. 223 big_endian_writer.WriteU8(0); // Add reserved.
218 big_endian_writer.WriteU16(3); // Block length. 224 big_endian_writer.WriteU16(3); // Block length.
219 big_endian_writer.WriteU32(ssrc_); // Add the media (received RTP) SSRC. 225 big_endian_writer.WriteU32(ssrc_); // Add the media (received RTP) SSRC.
220 big_endian_writer.WriteU32(dlrr->last_rr); 226 big_endian_writer.WriteU32(dlrr->last_rr);
221 big_endian_writer.WriteU32(dlrr->delay_since_last_rr); 227 big_endian_writer.WriteU32(dlrr->delay_since_last_rr);
222 } 228 }
223 229
224 void RtcpBuilder::BuildSenderLog(RtcpSenderLogMessage* sender_log_message, 230 void RtcpBuilder::BuildSenderLog(RtcpSenderLogMessage* sender_log_message,
225 std::vector<uint8>* packet) const { 231 std::vector<uint8>* packet) const {
226 DCHECK(sender_log_message); 232 DCHECK(sender_log_message);
227 DCHECK(packet); 233 DCHECK(packet);
228 size_t start_size = packet->size(); 234 size_t start_size = packet->size();
229 size_t remaining_space = kIpPacketSize - start_size; 235 size_t remaining_space = kMaxIpPacketSize - start_size;
230 DCHECK_GE(remaining_space, kRtcpCastLogHeaderSize + kRtcpSenderFrameLogSize) 236 DCHECK_GE(remaining_space, kRtcpCastLogHeaderSize + kRtcpSenderFrameLogSize)
231 << "Not enough buffer space"; 237 << "Not enough buffer space";
232 if (remaining_space < kRtcpCastLogHeaderSize + kRtcpSenderFrameLogSize) 238 if (remaining_space < kRtcpCastLogHeaderSize + kRtcpSenderFrameLogSize)
233 return; 239 return;
234 240
235 size_t space_for_x_messages = 241 size_t space_for_x_messages =
236 (remaining_space - kRtcpCastLogHeaderSize) / kRtcpSenderFrameLogSize; 242 (remaining_space - kRtcpCastLogHeaderSize) / kRtcpSenderFrameLogSize;
237 size_t number_of_messages = std::min(space_for_x_messages, 243 size_t number_of_messages = std::min(space_for_x_messages,
238 sender_log_message->size()); 244 sender_log_message->size());
239 245
(...skipping 16 matching lines...) Expand all
256 big_endian_writer.WriteU8(static_cast<uint8>(message.rtp_timestamp >> 16)); 262 big_endian_writer.WriteU8(static_cast<uint8>(message.rtp_timestamp >> 16));
257 big_endian_writer.WriteU8(static_cast<uint8>(message.rtp_timestamp >> 8)); 263 big_endian_writer.WriteU8(static_cast<uint8>(message.rtp_timestamp >> 8));
258 big_endian_writer.WriteU8(static_cast<uint8>(message.rtp_timestamp)); 264 big_endian_writer.WriteU8(static_cast<uint8>(message.rtp_timestamp));
259 sender_log_message->pop_front(); 265 sender_log_message->pop_front();
260 } 266 }
261 } 267 }
262 268
263 } // namespace transport 269 } // namespace transport
264 } // namespace cast 270 } // namespace cast
265 } // namespace media 271 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/transport/rtcp/rtcp_builder.h ('k') | media/cast/transport/rtcp/rtcp_builder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698