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

Side by Side Diff: media/cast/rtcp/rtcp_sender.cc

Issue 74613004: Cast: Add capabity to send Receiver and Sender log messages over RTCP. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@rtcp_logging
Patch Set: Added missing static casts Created 7 years 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
« no previous file with comments | « media/cast/rtcp/rtcp_sender.h ('k') | media/cast/rtcp/rtcp_sender_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/rtcp/rtcp_sender.h" 5 #include "media/cast/rtcp/rtcp_sender.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "media/cast/cast_environment.h" 11 #include "media/cast/cast_environment.h"
12 #include "media/cast/pacing/paced_sender.h" 12 #include "media/cast/pacing/paced_sender.h"
13 #include "media/cast/rtcp/rtcp_utility.h" 13 #include "media/cast/rtcp/rtcp_utility.h"
14 #include "net/base/big_endian.h" 14 #include "net/base/big_endian.h"
15 15
16 static const size_t kRtcpCastLogHeaderSize = 12;
17 static const size_t kRtcpSenderFrameLogSize = 4;
18 static const size_t kRtcpReceiverFrameLogSize = 8;
19 static const size_t kRtcpReceiverEventLogSize = 4;
20
21 namespace {
22 uint16 MergeEventTypeAndTimestampForWireFormat(
23 const media::cast::CastLoggingEvent& event,
24 const base::TimeDelta& time_delta) {
25 int64 time_delta_ms = time_delta.InMilliseconds();
26 // Max delta is 4096 milliseconds.
27 DCHECK_GE(GG_INT64_C(0xfff), time_delta_ms);
28
29 uint16 event_type_and_timestamp_delta =
30 static_cast<uint16>(time_delta_ms & 0xfff);
31
32 uint16 event_type = 0;
33 switch (event) {
34 case media::cast::kAckSent:
35 event_type = 1;
36 break;
37 case media::cast::kAudioPlayoutDelay:
38 event_type = 2;
39 break;
40 case media::cast::kAudioFrameDecoded:
41 event_type = 3;
42 break;
43 case media::cast::kVideoFrameDecoded:
44 event_type = 4;
45 break;
46 case media::cast::kVideoRenderDelay:
47 event_type = 5;
48 break;
49 case media::cast::kPacketReceived:
50 event_type = 6;
51 break;
52 default:
53 NOTREACHED();
54 }
55 DCHECK(!(event_type & 0xfff0));
56 return (event_type << 12) + event_type_and_timestamp_delta;
57 }
58
59 bool ScanRtcpReceiverLogMessage(
60 const media::cast::RtcpReceiverLogMessage& receiver_log_message,
61 size_t start_size,
62 size_t* number_of_frames,
63 size_t* total_number_of_messages_to_send,
64 size_t* rtcp_log_size) {
65 if (receiver_log_message.empty()) return false;
66
67 size_t remaining_space = media::cast::kIpPacketSize - start_size;
68
69 // We must have space for at least one message
70 DCHECK_GE(remaining_space, kRtcpCastLogHeaderSize +
71 kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize)
72 << "Not enough buffer space";
73
74 if (remaining_space < kRtcpCastLogHeaderSize + kRtcpReceiverFrameLogSize +
75 kRtcpReceiverEventLogSize) {
76 return false;
77 }
78 // Account for the RTCP header for an application-defined packet.
79 remaining_space -= kRtcpCastLogHeaderSize;
80
81 media::cast::RtcpReceiverLogMessage::const_iterator frame_it =
82 receiver_log_message.begin();
83 for (; frame_it != receiver_log_message.end(); ++frame_it) {
84 (*number_of_frames)++;
85
86 remaining_space -= kRtcpReceiverFrameLogSize;
87
88 size_t messages_in_frame = frame_it->event_log_messages_.size();
89 size_t remaining_space_in_messages =
90 remaining_space / kRtcpReceiverEventLogSize;
91 size_t messages_to_send = std::min(messages_in_frame,
92 remaining_space_in_messages);
93 if (messages_to_send > media::cast::kRtcpMaxReceiverLogMessages) {
94 // We can't send more than 256 messages.
95 remaining_space -= media::cast::kRtcpMaxReceiverLogMessages *
96 kRtcpReceiverEventLogSize;
97 *total_number_of_messages_to_send +=
98 media::cast::kRtcpMaxReceiverLogMessages;
99 break;
100 }
101 remaining_space -= messages_to_send * kRtcpReceiverEventLogSize;
102 *total_number_of_messages_to_send += messages_to_send;
103
104 if (remaining_space <
105 kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize) {
106 // Make sure that we have room for at least one more message.
107 break;
108 }
109 }
110 *rtcp_log_size = kRtcpCastLogHeaderSize +
111 *number_of_frames * kRtcpReceiverFrameLogSize +
112 *total_number_of_messages_to_send * kRtcpReceiverEventLogSize;
113 DCHECK_GE(media::cast::kIpPacketSize,
114 start_size + *rtcp_log_size) << "Not enough buffer space";
115
116 VLOG(1) << "number of frames " << *number_of_frames;
117 VLOG(1) << "total messages to send " << *total_number_of_messages_to_send;
118 VLOG(1) << "rtcp log size " << *rtcp_log_size;
119 return true;
120 }
121 } // namespace
122
16 namespace media { 123 namespace media {
17 namespace cast { 124 namespace cast {
18 125
19 RtcpSender::RtcpSender(scoped_refptr<CastEnvironment> cast_environment, 126 RtcpSender::RtcpSender(scoped_refptr<CastEnvironment> cast_environment,
20 PacedPacketSender* outgoing_transport, 127 PacedPacketSender* outgoing_transport,
21 uint32 sending_ssrc, 128 uint32 sending_ssrc,
22 const std::string& c_name) 129 const std::string& c_name)
23 : ssrc_(sending_ssrc), 130 : ssrc_(sending_ssrc),
24 c_name_(c_name), 131 c_name_(c_name),
25 transport_(outgoing_transport), 132 transport_(outgoing_transport),
26 cast_environment_(cast_environment) { 133 cast_environment_(cast_environment) {
27 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config"; 134 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config";
28 } 135 }
29 136
30 RtcpSender::~RtcpSender() {} 137 RtcpSender::~RtcpSender() {}
31 138
32 void RtcpSender::SendRtcpFromRtpSender(uint32 packet_type_flags, 139 void RtcpSender::SendRtcpFromRtpSender(uint32 packet_type_flags,
33 const RtcpSenderInfo* sender_info, 140 const RtcpSenderInfo* sender_info,
34 const RtcpDlrrReportBlock* dlrr, 141 const RtcpDlrrReportBlock* dlrr,
35 const RtcpSenderLogMessage* sender_log) { 142 RtcpSenderLogMessage* sender_log) {
36 if (packet_type_flags & kRtcpRr || 143 if (packet_type_flags & kRtcpRr ||
37 packet_type_flags & kRtcpPli || 144 packet_type_flags & kRtcpPli ||
38 packet_type_flags & kRtcpRrtr || 145 packet_type_flags & kRtcpRrtr ||
39 packet_type_flags & kRtcpCast || 146 packet_type_flags & kRtcpCast ||
40 packet_type_flags & kRtcpReceiverLog || 147 packet_type_flags & kRtcpReceiverLog ||
41 packet_type_flags & kRtcpRpsi || 148 packet_type_flags & kRtcpRpsi ||
42 packet_type_flags & kRtcpRemb || 149 packet_type_flags & kRtcpRemb ||
43 packet_type_flags & kRtcpNack) { 150 packet_type_flags & kRtcpNack) {
44 NOTREACHED() << "Invalid argument"; 151 NOTREACHED() << "Invalid argument";
45 } 152 }
(...skipping 20 matching lines...) Expand all
66 return; // Sanity don't send empty packets. 173 return; // Sanity don't send empty packets.
67 174
68 transport_->SendRtcpPacket(packet); 175 transport_->SendRtcpPacket(packet);
69 } 176 }
70 177
71 void RtcpSender::SendRtcpFromRtpReceiver( 178 void RtcpSender::SendRtcpFromRtpReceiver(
72 uint32 packet_type_flags, 179 uint32 packet_type_flags,
73 const RtcpReportBlock* report_block, 180 const RtcpReportBlock* report_block,
74 const RtcpReceiverReferenceTimeReport* rrtr, 181 const RtcpReceiverReferenceTimeReport* rrtr,
75 const RtcpCastMessage* cast_message, 182 const RtcpCastMessage* cast_message,
76 const RtcpReceiverLogMessage* receiver_log) { 183 RtcpReceiverLogMessage* receiver_log) {
77 if (packet_type_flags & kRtcpSr || 184 if (packet_type_flags & kRtcpSr ||
78 packet_type_flags & kRtcpDlrr || 185 packet_type_flags & kRtcpDlrr ||
79 packet_type_flags & kRtcpSenderLog) { 186 packet_type_flags & kRtcpSenderLog) {
80 NOTREACHED() << "Invalid argument"; 187 NOTREACHED() << "Invalid argument";
81 } 188 }
82 if (packet_type_flags & kRtcpPli || 189 if (packet_type_flags & kRtcpPli ||
83 packet_type_flags & kRtcpRpsi || 190 packet_type_flags & kRtcpRpsi ||
84 packet_type_flags & kRtcpRemb || 191 packet_type_flags & kRtcpRemb ||
85 packet_type_flags & kRtcpNack) { 192 packet_type_flags & kRtcpNack) {
86 // Implement these for webrtc interop. 193 // Implement these for webrtc interop.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 // Sender report. 228 // Sender report.
122 size_t start_size = packet->size(); 229 size_t start_size = packet->size();
123 DCHECK_LT(start_size + 52, kIpPacketSize) << "Not enough buffer space"; 230 DCHECK_LT(start_size + 52, kIpPacketSize) << "Not enough buffer space";
124 if (start_size + 52 > kIpPacketSize) return; 231 if (start_size + 52 > kIpPacketSize) return;
125 232
126 uint16 number_of_rows = (report_block) ? 12 : 6; 233 uint16 number_of_rows = (report_block) ? 12 : 6;
127 packet->resize(start_size + 28); 234 packet->resize(start_size + 28);
128 235
129 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 28); 236 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 28);
130 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); 237 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0));
131 big_endian_writer.WriteU8(200); 238 big_endian_writer.WriteU8(kPacketTypeSenderReport);
132 big_endian_writer.WriteU16(number_of_rows); 239 big_endian_writer.WriteU16(number_of_rows);
133 big_endian_writer.WriteU32(ssrc_); 240 big_endian_writer.WriteU32(ssrc_);
134 big_endian_writer.WriteU32(sender_info.ntp_seconds); 241 big_endian_writer.WriteU32(sender_info.ntp_seconds);
135 big_endian_writer.WriteU32(sender_info.ntp_fraction); 242 big_endian_writer.WriteU32(sender_info.ntp_fraction);
136 big_endian_writer.WriteU32(sender_info.rtp_timestamp); 243 big_endian_writer.WriteU32(sender_info.rtp_timestamp);
137 big_endian_writer.WriteU32(sender_info.send_packet_count); 244 big_endian_writer.WriteU32(sender_info.send_packet_count);
138 big_endian_writer.WriteU32(static_cast<uint32>(sender_info.send_octet_count)); 245 big_endian_writer.WriteU32(static_cast<uint32>(sender_info.send_octet_count));
139 246
140 if (report_block) { 247 if (report_block) {
141 AddReportBlocks(*report_block, packet); // Adds 24 bytes. 248 AddReportBlocks(*report_block, packet); // Adds 24 bytes.
142 } 249 }
143 } 250 }
144 251
145 void RtcpSender::BuildRR(const RtcpReportBlock* report_block, 252 void RtcpSender::BuildRR(const RtcpReportBlock* report_block,
146 std::vector<uint8>* packet) const { 253 std::vector<uint8>* packet) const {
147 size_t start_size = packet->size(); 254 size_t start_size = packet->size();
148 DCHECK_LT(start_size + 32, kIpPacketSize) << "Not enough buffer space"; 255 DCHECK_LT(start_size + 32, kIpPacketSize) << "Not enough buffer space";
149 if (start_size + 32 > kIpPacketSize) return; 256 if (start_size + 32 > kIpPacketSize) return;
150 257
151 uint16 number_of_rows = (report_block) ? 7 : 1; 258 uint16 number_of_rows = (report_block) ? 7 : 1;
152 packet->resize(start_size + 8); 259 packet->resize(start_size + 8);
153 260
154 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); 261 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8);
155 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); 262 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0));
156 big_endian_writer.WriteU8(201); 263 big_endian_writer.WriteU8(kPacketTypeReceiverReport);
157 big_endian_writer.WriteU16(number_of_rows); 264 big_endian_writer.WriteU16(number_of_rows);
158 big_endian_writer.WriteU32(ssrc_); 265 big_endian_writer.WriteU32(ssrc_);
159 266
160 if (report_block) { 267 if (report_block) {
161 AddReportBlocks(*report_block, packet); // Adds 24 bytes. 268 AddReportBlocks(*report_block, packet); // Adds 24 bytes.
162 } 269 }
163 } 270 }
164 271
165 void RtcpSender::AddReportBlocks(const RtcpReportBlock& report_block, 272 void RtcpSender::AddReportBlocks(const RtcpReportBlock& report_block,
166 std::vector<uint8>* packet) const { 273 std::vector<uint8>* packet) const {
(...skipping 28 matching lines...) Expand all
195 DCHECK_LT(start_size + 12 + c_name_.length(), kIpPacketSize) 302 DCHECK_LT(start_size + 12 + c_name_.length(), kIpPacketSize)
196 << "Not enough buffer space"; 303 << "Not enough buffer space";
197 if (start_size + 12 > kIpPacketSize) return; 304 if (start_size + 12 > kIpPacketSize) return;
198 305
199 // SDES Source Description. 306 // SDES Source Description.
200 packet->resize(start_size + 10); 307 packet->resize(start_size + 10);
201 308
202 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 10); 309 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 10);
203 // We always need to add one SDES CNAME. 310 // We always need to add one SDES CNAME.
204 big_endian_writer.WriteU8(0x80 + 1); 311 big_endian_writer.WriteU8(0x80 + 1);
205 big_endian_writer.WriteU8(202); 312 big_endian_writer.WriteU8(kPacketTypeSdes);
206 313
207 // Handle SDES length later on. 314 // Handle SDES length later on.
208 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; 315 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3;
209 big_endian_writer.WriteU16(0); 316 big_endian_writer.WriteU16(0);
210 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 317 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
211 big_endian_writer.WriteU8(1); // CNAME = 1 318 big_endian_writer.WriteU8(1); // CNAME = 1
212 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); 319 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length()));
213 320
214 size_t sdes_length = 10 + c_name_.length(); 321 size_t sdes_length = 10 + c_name_.length();
215 packet->insert(packet->end(), c_name_.c_str(), 322 packet->insert(packet->end(), c_name_.c_str(),
(...skipping 21 matching lines...) Expand all
237 std::vector<uint8>* packet) const { 344 std::vector<uint8>* packet) const {
238 size_t start_size = packet->size(); 345 size_t start_size = packet->size();
239 DCHECK_LT(start_size + 12, kIpPacketSize) << "Not enough buffer space"; 346 DCHECK_LT(start_size + 12, kIpPacketSize) << "Not enough buffer space";
240 if (start_size + 12 > kIpPacketSize) return; 347 if (start_size + 12 > kIpPacketSize) return;
241 348
242 packet->resize(start_size + 12); 349 packet->resize(start_size + 12);
243 350
244 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 12); 351 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 12);
245 uint8 FMT = 1; // Picture loss indicator. 352 uint8 FMT = 1; // Picture loss indicator.
246 big_endian_writer.WriteU8(0x80 + FMT); 353 big_endian_writer.WriteU8(0x80 + FMT);
247 big_endian_writer.WriteU8(206); 354 big_endian_writer.WriteU8(kPacketTypePayloadSpecific);
248 big_endian_writer.WriteU16(2); // Used fixed length of 2. 355 big_endian_writer.WriteU16(2); // Used fixed length of 2.
249 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 356 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
250 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. 357 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC.
251 } 358 }
252 359
253 /* 360 /*
254 0 1 2 3 361 0 1 2 3
255 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 362 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
256 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 363 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
257 | PB |0| Payload Type| Native Rpsi bit string | 364 | PB |0| Payload Type| Native Rpsi bit string |
258 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 365 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
259 | defined per codec ... | Padding (0) | 366 | defined per codec ... | Padding (0) |
260 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 367 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
261 */ 368 */
262 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, 369 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi,
263 std::vector<uint8>* packet) const { 370 std::vector<uint8>* packet) const {
264 size_t start_size = packet->size(); 371 size_t start_size = packet->size();
265 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space"; 372 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space";
266 if (start_size + 24 > kIpPacketSize) return; 373 if (start_size + 24 > kIpPacketSize) return;
267 374
268 packet->resize(start_size + 24); 375 packet->resize(start_size + 24);
269 376
270 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); 377 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24);
271 uint8 FMT = 3; // Reference Picture Selection Indication. 378 uint8 FMT = 3; // Reference Picture Selection Indication.
272 big_endian_writer.WriteU8(0x80 + FMT); 379 big_endian_writer.WriteU8(0x80 + FMT);
273 big_endian_writer.WriteU8(206); 380 big_endian_writer.WriteU8(kPacketTypePayloadSpecific);
274 381
275 // Calculate length. 382 // Calculate length.
276 uint32 bits_required = 7; 383 uint32 bits_required = 7;
277 uint8 bytes_required = 1; 384 uint8 bytes_required = 1;
278 while ((rpsi->picture_id >> bits_required) > 0) { 385 while ((rpsi->picture_id >> bits_required) > 0) {
279 bits_required += 7; 386 bits_required += 7;
280 bytes_required++; 387 bytes_required++;
281 } 388 }
282 uint8 size = 3; 389 uint8 size = 3;
283 if (bytes_required > 6) { 390 if (bytes_required > 6) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 << "Not enough buffer space"; 427 << "Not enough buffer space";
321 if (start_size + remb_size > kIpPacketSize) return; 428 if (start_size + remb_size > kIpPacketSize) return;
322 429
323 packet->resize(start_size + remb_size); 430 packet->resize(start_size + remb_size);
324 431
325 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), remb_size); 432 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), remb_size);
326 433
327 // Add application layer feedback. 434 // Add application layer feedback.
328 uint8 FMT = 15; 435 uint8 FMT = 15;
329 big_endian_writer.WriteU8(0x80 + FMT); 436 big_endian_writer.WriteU8(0x80 + FMT);
330 big_endian_writer.WriteU8(206); 437 big_endian_writer.WriteU8(kPacketTypePayloadSpecific);
331 big_endian_writer.WriteU8(0); 438 big_endian_writer.WriteU8(0);
332 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); 439 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4));
333 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 440 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
334 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. 441 big_endian_writer.WriteU32(0); // Remote SSRC must be 0.
335 big_endian_writer.WriteU32(kRemb); 442 big_endian_writer.WriteU32(kRemb);
336 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size())); 443 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size()));
337 444
338 // 6 bit exponent and a 18 bit mantissa. 445 // 6 bit exponent and a 18 bit mantissa.
339 uint8 bitrate_exponent; 446 uint8 bitrate_exponent;
340 uint32 bitrate_mantissa; 447 uint32 bitrate_mantissa;
(...skipping 19 matching lines...) Expand all
360 size_t start_size = packet->size(); 467 size_t start_size = packet->size();
361 DCHECK_LT(start_size + 16, kIpPacketSize) << "Not enough buffer space"; 468 DCHECK_LT(start_size + 16, kIpPacketSize) << "Not enough buffer space";
362 if (start_size + 16 > kIpPacketSize) return; 469 if (start_size + 16 > kIpPacketSize) return;
363 470
364 packet->resize(start_size + 16); 471 packet->resize(start_size + 16);
365 472
366 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 16); 473 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 16);
367 474
368 uint8 FMT = 1; 475 uint8 FMT = 1;
369 big_endian_writer.WriteU8(0x80 + FMT); 476 big_endian_writer.WriteU8(0x80 + FMT);
370 big_endian_writer.WriteU8(205); 477 big_endian_writer.WriteU8(kPacketTypeGenericRtpFeedback);
371 big_endian_writer.WriteU8(0); 478 big_endian_writer.WriteU8(0);
372 size_t nack_size_pos = start_size + 3; 479 size_t nack_size_pos = start_size + 3;
373 big_endian_writer.WriteU8(3); 480 big_endian_writer.WriteU8(3);
374 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 481 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
375 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC. 482 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC.
376 483
377 // Build NACK bitmasks and write them to the Rtcp message. 484 // Build NACK bitmasks and write them to the Rtcp message.
378 // The nack list should be sorted and not contain duplicates. 485 // The nack list should be sorted and not contain duplicates.
379 size_t number_of_nack_fields = 0; 486 size_t number_of_nack_fields = 0;
380 size_t max_number_of_nack_fields = std::min<size_t>(kRtcpMaxNackFields, 487 size_t max_number_of_nack_fields = std::min<size_t>(kRtcpMaxNackFields,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 519
413 void RtcpSender::BuildBye(std::vector<uint8>* packet) const { 520 void RtcpSender::BuildBye(std::vector<uint8>* packet) const {
414 size_t start_size = packet->size(); 521 size_t start_size = packet->size();
415 DCHECK_LT(start_size + 8, kIpPacketSize) << "Not enough buffer space"; 522 DCHECK_LT(start_size + 8, kIpPacketSize) << "Not enough buffer space";
416 if (start_size + 8 > kIpPacketSize) return; 523 if (start_size + 8 > kIpPacketSize) return;
417 524
418 packet->resize(start_size + 8); 525 packet->resize(start_size + 8);
419 526
420 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); 527 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8);
421 big_endian_writer.WriteU8(0x80 + 1); 528 big_endian_writer.WriteU8(0x80 + 1);
422 big_endian_writer.WriteU8(203); 529 big_endian_writer.WriteU8(kPacketTypeBye);
423 big_endian_writer.WriteU16(1); // Length. 530 big_endian_writer.WriteU16(1); // Length.
424 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 531 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
425 } 532 }
426 533
427 /* 534 /*
428 0 1 2 3 535 0 1 2 3
429 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 536 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
430 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 537 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
431 |V=2|P|reserved | PT=XR=207 | length | 538 |V=2|P|reserved | PT=XR=207 | length |
432 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 539 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
(...skipping 11 matching lines...) Expand all
444 void RtcpSender::BuildDlrrRb(const RtcpDlrrReportBlock* dlrr, 551 void RtcpSender::BuildDlrrRb(const RtcpDlrrReportBlock* dlrr,
445 std::vector<uint8>* packet) const { 552 std::vector<uint8>* packet) const {
446 size_t start_size = packet->size(); 553 size_t start_size = packet->size();
447 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space"; 554 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space";
448 if (start_size + 24 > kIpPacketSize) return; 555 if (start_size + 24 > kIpPacketSize) return;
449 556
450 packet->resize(start_size + 24); 557 packet->resize(start_size + 24);
451 558
452 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); 559 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24);
453 big_endian_writer.WriteU8(0x80); 560 big_endian_writer.WriteU8(0x80);
454 big_endian_writer.WriteU8(207); 561 big_endian_writer.WriteU8(kPacketTypeXr);
455 big_endian_writer.WriteU16(5); // Length. 562 big_endian_writer.WriteU16(5); // Length.
456 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 563 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
457 big_endian_writer.WriteU8(5); // Add block type. 564 big_endian_writer.WriteU8(5); // Add block type.
458 big_endian_writer.WriteU8(0); // Add reserved. 565 big_endian_writer.WriteU8(0); // Add reserved.
459 big_endian_writer.WriteU16(3); // Block length. 566 big_endian_writer.WriteU16(3); // Block length.
460 big_endian_writer.WriteU32(ssrc_); // Add the media (received RTP) SSRC. 567 big_endian_writer.WriteU32(ssrc_); // Add the media (received RTP) SSRC.
461 big_endian_writer.WriteU32(dlrr->last_rr); 568 big_endian_writer.WriteU32(dlrr->last_rr);
462 big_endian_writer.WriteU32(dlrr->delay_since_last_rr); 569 big_endian_writer.WriteU32(dlrr->delay_since_last_rr);
463 } 570 }
464 571
465 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, 572 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr,
466 std::vector<uint8>* packet) const { 573 std::vector<uint8>* packet) const {
467 size_t start_size = packet->size(); 574 size_t start_size = packet->size();
468 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space"; 575 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space";
469 if (start_size + 20 > kIpPacketSize) return; 576 if (start_size + 20 > kIpPacketSize) return;
470 577
471 packet->resize(start_size + 20); 578 packet->resize(start_size + 20);
472 579
473 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); 580 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20);
474 581
475 big_endian_writer.WriteU8(0x80); 582 big_endian_writer.WriteU8(0x80);
476 big_endian_writer.WriteU8(207); 583 big_endian_writer.WriteU8(kPacketTypeXr);
477 big_endian_writer.WriteU16(4); // Length. 584 big_endian_writer.WriteU16(4); // Length.
478 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 585 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
479 big_endian_writer.WriteU8(4); // Add block type. 586 big_endian_writer.WriteU8(4); // Add block type.
480 big_endian_writer.WriteU8(0); // Add reserved. 587 big_endian_writer.WriteU8(0); // Add reserved.
481 big_endian_writer.WriteU16(2); // Block length. 588 big_endian_writer.WriteU16(2); // Block length.
482 589
483 // Add the media (received RTP) SSRC. 590 // Add the media (received RTP) SSRC.
484 big_endian_writer.WriteU32(rrtr->ntp_seconds); 591 big_endian_writer.WriteU32(rrtr->ntp_seconds);
485 big_endian_writer.WriteU32(rrtr->ntp_fraction); 592 big_endian_writer.WriteU32(rrtr->ntp_fraction);
486 } 593 }
487 594
488 void RtcpSender::BuildCast(const RtcpCastMessage* cast, 595 void RtcpSender::BuildCast(const RtcpCastMessage* cast,
489 std::vector<uint8>* packet) const { 596 std::vector<uint8>* packet) const {
490 size_t start_size = packet->size(); 597 size_t start_size = packet->size();
491 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space"; 598 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space";
492 if (start_size + 20 > kIpPacketSize) return; 599 if (start_size + 20 > kIpPacketSize) return;
493 600
494 packet->resize(start_size + 20); 601 packet->resize(start_size + 20);
495 602
496 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); 603 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20);
497 uint8 FMT = 15; // Application layer feedback. 604 uint8 FMT = 15; // Application layer feedback.
498 big_endian_writer.WriteU8(0x80 + FMT); 605 big_endian_writer.WriteU8(0x80 + FMT);
499 big_endian_writer.WriteU8(206); 606 big_endian_writer.WriteU8(kPacketTypePayloadSpecific);
500 big_endian_writer.WriteU8(0); 607 big_endian_writer.WriteU8(0);
501 size_t cast_size_pos = start_size + 3; // Save length position. 608 size_t cast_size_pos = start_size + 3; // Save length position.
502 big_endian_writer.WriteU8(4); 609 big_endian_writer.WriteU8(4);
503 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 610 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
504 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. 611 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC.
505 big_endian_writer.WriteU32(kCast); 612 big_endian_writer.WriteU32(kCast);
506 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); 613 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_));
507 size_t cast_loss_field_pos = start_size + 17; // Save loss field position. 614 size_t cast_loss_field_pos = start_size + 17; // Save loss field position.
508 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields. 615 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields.
509 big_endian_writer.WriteU8(0); // Reserved. 616 big_endian_writer.WriteU8(0); // Reserved.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 big_endian_nack_writer.WriteU8(bitmask); 663 big_endian_nack_writer.WriteU8(bitmask);
557 ++number_of_loss_fields; 664 ++number_of_loss_fields;
558 } 665 }
559 } 666 }
560 } 667 }
561 DCHECK_LE(number_of_loss_fields, kRtcpMaxCastLossFields); 668 DCHECK_LE(number_of_loss_fields, kRtcpMaxCastLossFields);
562 (*packet)[cast_size_pos] = static_cast<uint8>(4 + number_of_loss_fields); 669 (*packet)[cast_size_pos] = static_cast<uint8>(4 + number_of_loss_fields);
563 (*packet)[cast_loss_field_pos] = static_cast<uint8>(number_of_loss_fields); 670 (*packet)[cast_loss_field_pos] = static_cast<uint8>(number_of_loss_fields);
564 } 671 }
565 672
566 void RtcpSender::BuildSenderLog(const RtcpSenderLogMessage* sender_log_message, 673 void RtcpSender::BuildSenderLog(RtcpSenderLogMessage* sender_log_message,
567 std::vector<uint8>* packet) const { 674 std::vector<uint8>* packet) const {
568 // TODO(pwestin): Implement. 675 DCHECK(sender_log_message);
569 NOTIMPLEMENTED(); 676 DCHECK(packet);
677 size_t start_size = packet->size();
678 size_t remaining_space = kIpPacketSize - start_size;
679 DCHECK_GE(remaining_space, kRtcpCastLogHeaderSize + kRtcpSenderFrameLogSize)
680 << "Not enough buffer space";
681 if (remaining_space < kRtcpCastLogHeaderSize + kRtcpSenderFrameLogSize)
682 return;
683
684 size_t space_for_x_messages =
685 (remaining_space - kRtcpCastLogHeaderSize) / kRtcpSenderFrameLogSize;
686 size_t number_of_messages = std::min(space_for_x_messages,
687 sender_log_message->size());
688
689 size_t log_size = kRtcpCastLogHeaderSize +
690 number_of_messages * kRtcpSenderFrameLogSize;
691 packet->resize(start_size + log_size);
692
693 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), log_size);
694 big_endian_writer.WriteU8(0x80 + kSenderLogSubtype);
695 big_endian_writer.WriteU8(kPacketTypeApplicationDefined);
696 big_endian_writer.WriteU16(static_cast<uint16>(2 + number_of_messages));
697 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
698 big_endian_writer.WriteU32(kCast);
699
700 for (; number_of_messages > 0; --number_of_messages) {
701 DCHECK(!sender_log_message->empty());
702 const RtcpSenderFrameLogMessage& message = sender_log_message->front();
703 big_endian_writer.WriteU8(static_cast<uint8>(message.frame_status));
704 // We send the 24 east significant bits of the RTP timestamp.
705 big_endian_writer.WriteU8(static_cast<uint8>(message.rtp_timestamp >> 16));
706 big_endian_writer.WriteU8(static_cast<uint8>(message.rtp_timestamp >> 8));
707 big_endian_writer.WriteU8(static_cast<uint8>(message.rtp_timestamp));
708 sender_log_message->pop_front();
709 }
570 } 710 }
571 711
572 void RtcpSender::BuildReceiverLog( 712 void RtcpSender::BuildReceiverLog(RtcpReceiverLogMessage* receiver_log_message,
573 const RtcpReceiverLogMessage* receiver_log_message, 713 std::vector<uint8>* packet) const {
574 std::vector<uint8>* packet) const { 714 DCHECK(receiver_log_message);
575 // TODO(pwestin): Implement. 715 const size_t packet_start_size = packet->size();
576 NOTIMPLEMENTED(); 716 size_t number_of_frames = 0;
717 size_t total_number_of_messages_to_send = 0;
718 size_t rtcp_log_size = 0;
719
720 if (!ScanRtcpReceiverLogMessage(*receiver_log_message,
721 packet_start_size,
722 &number_of_frames,
723 &total_number_of_messages_to_send,
724 &rtcp_log_size)) {
725 return;
726 }
727 packet->resize(packet_start_size + rtcp_log_size);
728
729 net::BigEndianWriter big_endian_writer(&((*packet)[packet_start_size]),
730 rtcp_log_size);
731 big_endian_writer.WriteU8(0x80 + kReceiverLogSubtype);
732 big_endian_writer.WriteU8(kPacketTypeApplicationDefined);
733 big_endian_writer.WriteU16(static_cast<uint16>(2 + 2 * number_of_frames +
734 total_number_of_messages_to_send));
735 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
736 big_endian_writer.WriteU32(kCast);
737
738 while (!receiver_log_message->empty() &&
739 total_number_of_messages_to_send > 0) {
740 RtcpReceiverFrameLogMessage& frame_log_messages =
741 receiver_log_message->front();
742 // Add our frame header.
743 big_endian_writer.WriteU32(frame_log_messages.rtp_timestamp_);
744 size_t messages_in_frame = frame_log_messages.event_log_messages_.size();
745 if (messages_in_frame > total_number_of_messages_to_send) {
746 // We are running out of space.
747 messages_in_frame = total_number_of_messages_to_send;
748 }
749 // Keep track of how many messages we have left to send.
750 total_number_of_messages_to_send -= messages_in_frame;
751
752 // On the wire format is number of messages - 1.
753 big_endian_writer.WriteU8(static_cast<uint8>(messages_in_frame - 1));
754
755 base::TimeTicks event_timestamp_base =
756 frame_log_messages.event_log_messages_.front().event_timestamp;
757 uint32 base_timestamp_ms =
758 (event_timestamp_base - base::TimeTicks()).InMilliseconds();
759 big_endian_writer.WriteU8(static_cast<uint8>(base_timestamp_ms >> 16));
760 big_endian_writer.WriteU8(static_cast<uint8>(base_timestamp_ms >> 8));
761 big_endian_writer.WriteU8(static_cast<uint8>(base_timestamp_ms));
762
763 while (!frame_log_messages.event_log_messages_.empty() &&
764 messages_in_frame > 0) {
765 const RtcpReceiverEventLogMessage& event_message =
766 frame_log_messages.event_log_messages_.front();
767 uint16 event_type_and_timestamp_delta =
768 MergeEventTypeAndTimestampForWireFormat(event_message.type,
769 event_message.event_timestamp - event_timestamp_base);
770 switch (event_message.type) {
771 case kAckSent:
772 case kAudioPlayoutDelay:
773 case kAudioFrameDecoded:
774 case kVideoFrameDecoded:
775 case kVideoRenderDelay:
776 big_endian_writer.WriteU16(static_cast<uint16>(
777 event_message.delay_delta.InMilliseconds()));
778 big_endian_writer.WriteU16(event_type_and_timestamp_delta);
779 break;
780 case kPacketReceived:
781 big_endian_writer.WriteU16(event_message.packet_id);
782 big_endian_writer.WriteU16(event_type_and_timestamp_delta);
783 break;
784 default:
785 NOTREACHED();
786 }
787 messages_in_frame--;
788 frame_log_messages.event_log_messages_.pop_front();
789 }
790 if (frame_log_messages.event_log_messages_.empty()) {
791 // We sent all messages on this frame; pop the frame header.
792 receiver_log_message->pop_front();
793 }
794 }
795 DCHECK_EQ(total_number_of_messages_to_send, 0);
577 } 796 }
578 797
579 } // namespace cast 798 } // namespace cast
580 } // namespace media 799 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/rtcp/rtcp_sender.h ('k') | media/cast/rtcp/rtcp_sender_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698