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

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: Fixed nits Created 7 years, 1 month 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
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/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
11 #include "base/logging.h" 11 #include "base/logging.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 namespace {
17
18 uint16 MergeEventTypeAndTimestampForWireFormat(
19 const media::cast::CastLoggingEvent& event,
20 const base::TimeDelta& time_delta) {
21 int64 time_delta_ms = time_delta.InMilliseconds();
22 // Max delta is 4096 milliseconds.
23 DCHECK_GE(GG_INT64_C(0xfff), time_delta_ms);
24
25 uint16 event_type_and_timestamp_delta =
26 static_cast<uint16>(time_delta_ms & 0xfff);
27
28 uint16 event_type = 0;
29 switch (event) {
30 case media::cast::kAckSent:
31 event_type = 1;
32 break;
33 case media::cast::kAudioPlayoutDelay:
34 event_type = 2;
35 break;
36 case media::cast::kAudioFrameDecoded:
37 event_type = 3;
38 break;
39 case media::cast::kVideoFrameDecoded:
40 event_type = 4;
41 break;
42 case media::cast::kVideoRenderDelay:
43 event_type = 5;
44 break;
45 case media::cast::kPacketReceived:
46 event_type = 6;
47 break;
48 default:
49 NOTREACHED();
mikhal 2013/11/21 16:43:20 The receiver also includes jitter and packet loss
pwestin 2013/11/22 18:50:47 The difference is that this is intended for timing
50 }
51 DCHECK(!(event_type & 0xfff0));
52 return (event_type << 12) + event_type_and_timestamp_delta;
53 }
54
55 bool ScanRtcpReceiverLogMessage(
56 const media::cast::RtcpReceiverLogMessage& receiver_log_message,
57 size_t start_size,
58 size_t* number_of_frames,
59 size_t* total_number_of_messages_to_send,
60 size_t* rtcp_log_size) {
61 if (receiver_log_message.empty()) return false;
62
63 size_t remaining_space = media::cast::kIpPacketSize - start_size;
64
65 // We must have space for at least one message
66 DCHECK_GE(remaining_space, 16) << "Not enough buffer space";
67 if (remaining_space < 16) return false;
68
69 // Account for the RTCP header for an application-defined packet.
70 remaining_space -= 12;
mikhal 2013/11/21 16:43:20 use consts, here and elsewhere.
pwestin 2013/11/22 18:50:47 Done.
71
72 media::cast::RtcpReceiverLogMessage::const_iterator frame_it =
73 receiver_log_message.begin();
74 for (; frame_it != receiver_log_message.end(); ++frame_it) {
75 (*number_of_frames)++;
76 remaining_space -= 8;
77
78 size_t messages_in_frame = frame_it->event_log_messages.size();
79 size_t remaining_space_in_messages = remaining_space / 4;
80 size_t messages_to_send = std::min(messages_in_frame,
81 remaining_space_in_messages);
82 if (messages_to_send > media::cast::kRtcpMaxReceiverLogMessages) {
83 // We can't send more than 256 messages.
84 remaining_space -= media::cast::kRtcpMaxReceiverLogMessages * 4;
85 *total_number_of_messages_to_send +=
86 media::cast::kRtcpMaxReceiverLogMessages;
87 break;
88 }
89 remaining_space -= messages_to_send * 4;
90 *total_number_of_messages_to_send += messages_to_send;
91
92 if (remaining_space < 12) {
93 // Make sure that we have room for at least one more message.
94 break;
95 }
96 }
97 *rtcp_log_size = 12 + *number_of_frames * 8 +
98 *total_number_of_messages_to_send * 4;
99 DCHECK_GE(media::cast::kIpPacketSize,
100 start_size + *rtcp_log_size) << "Not enough buffer space";
101
102 VLOG(1) << "number of frames " << *number_of_frames;
103 VLOG(1) << "total messages to send " << *total_number_of_messages_to_send;
104 VLOG(1) << "rtcp log size " << *rtcp_log_size;
105 return true;
106 }
107 } // namespace
108
16 namespace media { 109 namespace media {
17 namespace cast { 110 namespace cast {
18 111
19 static const size_t kRtcpMaxNackFields = 253;
20 static const size_t kRtcpMaxCastLossFields = 100;
21
22 RtcpSender::RtcpSender(PacedPacketSender* outgoing_transport, 112 RtcpSender::RtcpSender(PacedPacketSender* outgoing_transport,
23 uint32 sending_ssrc, 113 uint32 sending_ssrc,
24 const std::string& c_name) 114 const std::string& c_name)
25 : ssrc_(sending_ssrc), 115 : ssrc_(sending_ssrc),
26 c_name_(c_name), 116 c_name_(c_name),
27 transport_(outgoing_transport) { 117 transport_(outgoing_transport) {
28 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config"; 118 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config";
29 } 119 }
30 120
31 RtcpSender::~RtcpSender() {} 121 RtcpSender::~RtcpSender() {}
32 122
33 void RtcpSender::SendRtcpFromRtpSender(uint32 packet_type_flags, 123 void RtcpSender::SendRtcpFromRtpSender(uint32 packet_type_flags,
34 const RtcpSenderInfo* sender_info, 124 const RtcpSenderInfo* sender_info,
35 const RtcpDlrrReportBlock* dlrr, 125 const RtcpDlrrReportBlock* dlrr,
36 const RtcpSenderLogMessage* sender_log) { 126 RtcpSenderLogMessage* sender_log) {
37 if (packet_type_flags & kRtcpRr || 127 if (packet_type_flags & kRtcpRr ||
38 packet_type_flags & kRtcpPli || 128 packet_type_flags & kRtcpPli ||
39 packet_type_flags & kRtcpRrtr || 129 packet_type_flags & kRtcpRrtr ||
40 packet_type_flags & kRtcpCast || 130 packet_type_flags & kRtcpCast ||
41 packet_type_flags & kRtcpReceiverLog || 131 packet_type_flags & kRtcpReceiverLog ||
42 packet_type_flags & kRtcpRpsi || 132 packet_type_flags & kRtcpRpsi ||
43 packet_type_flags & kRtcpRemb || 133 packet_type_flags & kRtcpRemb ||
44 packet_type_flags & kRtcpNack) { 134 packet_type_flags & kRtcpNack) {
45 NOTREACHED() << "Invalid argument"; 135 NOTREACHED() << "Invalid argument";
46 } 136 }
(...skipping 20 matching lines...) Expand all
67 return; // Sanity don't send empty packets. 157 return; // Sanity don't send empty packets.
68 158
69 transport_->SendRtcpPacket(packet); 159 transport_->SendRtcpPacket(packet);
70 } 160 }
71 161
72 void RtcpSender::SendRtcpFromRtpReceiver( 162 void RtcpSender::SendRtcpFromRtpReceiver(
73 uint32 packet_type_flags, 163 uint32 packet_type_flags,
74 const RtcpReportBlock* report_block, 164 const RtcpReportBlock* report_block,
75 const RtcpReceiverReferenceTimeReport* rrtr, 165 const RtcpReceiverReferenceTimeReport* rrtr,
76 const RtcpCastMessage* cast_message, 166 const RtcpCastMessage* cast_message,
77 const RtcpReceiverLogMessage* receiver_log) { 167 RtcpReceiverLogMessage* receiver_log) {
78 if (packet_type_flags & kRtcpSr || 168 if (packet_type_flags & kRtcpSr ||
79 packet_type_flags & kRtcpDlrr || 169 packet_type_flags & kRtcpDlrr ||
80 packet_type_flags & kRtcpSenderLog) { 170 packet_type_flags & kRtcpSenderLog) {
81 NOTREACHED() << "Invalid argument"; 171 NOTREACHED() << "Invalid argument";
82 } 172 }
83 if (packet_type_flags & kRtcpPli || 173 if (packet_type_flags & kRtcpPli ||
84 packet_type_flags & kRtcpRpsi || 174 packet_type_flags & kRtcpRpsi ||
85 packet_type_flags & kRtcpRemb || 175 packet_type_flags & kRtcpRemb ||
86 packet_type_flags & kRtcpNack) { 176 packet_type_flags & kRtcpNack) {
87 // Implement these for webrtc interop. 177 // Implement these for webrtc interop.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 // Sender report. 212 // Sender report.
123 size_t start_size = packet->size(); 213 size_t start_size = packet->size();
124 DCHECK_LT(start_size + 52, kIpPacketSize) << "Not enough buffer space"; 214 DCHECK_LT(start_size + 52, kIpPacketSize) << "Not enough buffer space";
125 if (start_size + 52 > kIpPacketSize) return; 215 if (start_size + 52 > kIpPacketSize) return;
126 216
127 uint16 number_of_rows = (report_block) ? 12 : 6; 217 uint16 number_of_rows = (report_block) ? 12 : 6;
128 packet->resize(start_size + 28); 218 packet->resize(start_size + 28);
129 219
130 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 28); 220 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 28);
131 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); 221 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0));
132 big_endian_writer.WriteU8(200); 222 big_endian_writer.WriteU8(kPacketTypeSenderReport);
133 big_endian_writer.WriteU16(number_of_rows); 223 big_endian_writer.WriteU16(number_of_rows);
134 big_endian_writer.WriteU32(ssrc_); 224 big_endian_writer.WriteU32(ssrc_);
135 big_endian_writer.WriteU32(sender_info.ntp_seconds); 225 big_endian_writer.WriteU32(sender_info.ntp_seconds);
136 big_endian_writer.WriteU32(sender_info.ntp_fraction); 226 big_endian_writer.WriteU32(sender_info.ntp_fraction);
137 big_endian_writer.WriteU32(sender_info.rtp_timestamp); 227 big_endian_writer.WriteU32(sender_info.rtp_timestamp);
138 big_endian_writer.WriteU32(sender_info.send_packet_count); 228 big_endian_writer.WriteU32(sender_info.send_packet_count);
139 big_endian_writer.WriteU32(static_cast<uint32>(sender_info.send_octet_count)); 229 big_endian_writer.WriteU32(static_cast<uint32>(sender_info.send_octet_count));
140 230
141 if (report_block) { 231 if (report_block) {
142 AddReportBlocks(*report_block, packet); // Adds 24 bytes. 232 AddReportBlocks(*report_block, packet); // Adds 24 bytes.
143 } 233 }
144 } 234 }
145 235
146 void RtcpSender::BuildRR(const RtcpReportBlock* report_block, 236 void RtcpSender::BuildRR(const RtcpReportBlock* report_block,
147 std::vector<uint8>* packet) const { 237 std::vector<uint8>* packet) const {
148 size_t start_size = packet->size(); 238 size_t start_size = packet->size();
149 DCHECK_LT(start_size + 32, kIpPacketSize) << "Not enough buffer space"; 239 DCHECK_LT(start_size + 32, kIpPacketSize) << "Not enough buffer space";
150 if (start_size + 32 > kIpPacketSize) return; 240 if (start_size + 32 > kIpPacketSize) return;
151 241
152 uint16 number_of_rows = (report_block) ? 7 : 1; 242 uint16 number_of_rows = (report_block) ? 7 : 1;
153 packet->resize(start_size + 8); 243 packet->resize(start_size + 8);
154 244
155 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); 245 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8);
156 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); 246 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0));
157 big_endian_writer.WriteU8(201); 247 big_endian_writer.WriteU8(kPacketTypeReceiverReport);
158 big_endian_writer.WriteU16(number_of_rows); 248 big_endian_writer.WriteU16(number_of_rows);
159 big_endian_writer.WriteU32(ssrc_); 249 big_endian_writer.WriteU32(ssrc_);
160 250
161 if (report_block) { 251 if (report_block) {
162 AddReportBlocks(*report_block, packet); // Adds 24 bytes. 252 AddReportBlocks(*report_block, packet); // Adds 24 bytes.
163 } 253 }
164 } 254 }
165 255
166 void RtcpSender::AddReportBlocks(const RtcpReportBlock& report_block, 256 void RtcpSender::AddReportBlocks(const RtcpReportBlock& report_block,
167 std::vector<uint8>* packet) const { 257 std::vector<uint8>* packet) const {
(...skipping 28 matching lines...) Expand all
196 DCHECK_LT(start_size + 12 + c_name_.length(), kIpPacketSize) 286 DCHECK_LT(start_size + 12 + c_name_.length(), kIpPacketSize)
197 << "Not enough buffer space"; 287 << "Not enough buffer space";
198 if (start_size + 12 > kIpPacketSize) return; 288 if (start_size + 12 > kIpPacketSize) return;
199 289
200 // SDES Source Description. 290 // SDES Source Description.
201 packet->resize(start_size + 10); 291 packet->resize(start_size + 10);
202 292
203 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 10); 293 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 10);
204 // We always need to add one SDES CNAME. 294 // We always need to add one SDES CNAME.
205 big_endian_writer.WriteU8(0x80 + 1); 295 big_endian_writer.WriteU8(0x80 + 1);
206 big_endian_writer.WriteU8(202); 296 big_endian_writer.WriteU8(kPacketTypeSdes);
207 297
208 // Handle SDES length later on. 298 // Handle SDES length later on.
209 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; 299 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3;
210 big_endian_writer.WriteU16(0); 300 big_endian_writer.WriteU16(0);
211 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 301 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
212 big_endian_writer.WriteU8(1); // CNAME = 1 302 big_endian_writer.WriteU8(1); // CNAME = 1
213 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); 303 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length()));
214 304
215 size_t sdes_length = 10 + c_name_.length(); 305 size_t sdes_length = 10 + c_name_.length();
216 packet->insert(packet->end(), c_name_.c_str(), 306 packet->insert(packet->end(), c_name_.c_str(),
(...skipping 21 matching lines...) Expand all
238 std::vector<uint8>* packet) const { 328 std::vector<uint8>* packet) const {
239 size_t start_size = packet->size(); 329 size_t start_size = packet->size();
240 DCHECK_LT(start_size + 12, kIpPacketSize) << "Not enough buffer space"; 330 DCHECK_LT(start_size + 12, kIpPacketSize) << "Not enough buffer space";
241 if (start_size + 12 > kIpPacketSize) return; 331 if (start_size + 12 > kIpPacketSize) return;
242 332
243 packet->resize(start_size + 12); 333 packet->resize(start_size + 12);
244 334
245 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 12); 335 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 12);
246 uint8 FMT = 1; // Picture loss indicator. 336 uint8 FMT = 1; // Picture loss indicator.
247 big_endian_writer.WriteU8(0x80 + FMT); 337 big_endian_writer.WriteU8(0x80 + FMT);
248 big_endian_writer.WriteU8(206); 338 big_endian_writer.WriteU8(kPacketTypePayloadSpecific);
249 big_endian_writer.WriteU16(2); // Used fixed length of 2. 339 big_endian_writer.WriteU16(2); // Used fixed length of 2.
250 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 340 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
251 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. 341 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC.
252 TRACE_EVENT_INSTANT2("cast_rtcp", "RtcpSender::PLI", TRACE_EVENT_SCOPE_THREAD, 342 TRACE_EVENT_INSTANT2("cast_rtcp", "RtcpSender::PLI", TRACE_EVENT_SCOPE_THREAD,
253 "remote_ssrc", remote_ssrc, 343 "remote_ssrc", remote_ssrc,
254 "ssrc", ssrc_); 344 "ssrc", ssrc_);
255 } 345 }
256 346
257 /* 347 /*
258 0 1 2 3 348 0 1 2 3
259 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 349 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
260 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 350 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
261 | PB |0| Payload Type| Native Rpsi bit string | 351 | PB |0| Payload Type| Native Rpsi bit string |
262 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 352 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
263 | defined per codec ... | Padding (0) | 353 | defined per codec ... | Padding (0) |
264 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 354 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
265 */ 355 */
266 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, 356 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi,
267 std::vector<uint8>* packet) const { 357 std::vector<uint8>* packet) const {
268 size_t start_size = packet->size(); 358 size_t start_size = packet->size();
269 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space"; 359 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space";
270 if (start_size + 24 > kIpPacketSize) return; 360 if (start_size + 24 > kIpPacketSize) return;
271 361
272 packet->resize(start_size + 24); 362 packet->resize(start_size + 24);
273 363
274 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); 364 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24);
275 uint8 FMT = 3; // Reference Picture Selection Indication. 365 uint8 FMT = 3; // Reference Picture Selection Indication.
276 big_endian_writer.WriteU8(0x80 + FMT); 366 big_endian_writer.WriteU8(0x80 + FMT);
277 big_endian_writer.WriteU8(206); 367 big_endian_writer.WriteU8(kPacketTypePayloadSpecific);
278 368
279 // Calculate length. 369 // Calculate length.
280 uint32 bits_required = 7; 370 uint32 bits_required = 7;
281 uint8 bytes_required = 1; 371 uint8 bytes_required = 1;
282 while ((rpsi->picture_id >> bits_required) > 0) { 372 while ((rpsi->picture_id >> bits_required) > 0) {
283 bits_required += 7; 373 bits_required += 7;
284 bytes_required++; 374 bytes_required++;
285 } 375 }
286 uint8 size = 3; 376 uint8 size = 3;
287 if (bytes_required > 6) { 377 if (bytes_required > 6) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 << "Not enough buffer space"; 414 << "Not enough buffer space";
325 if (start_size + remb_size > kIpPacketSize) return; 415 if (start_size + remb_size > kIpPacketSize) return;
326 416
327 packet->resize(start_size + remb_size); 417 packet->resize(start_size + remb_size);
328 418
329 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), remb_size); 419 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), remb_size);
330 420
331 // Add application layer feedback. 421 // Add application layer feedback.
332 uint8 FMT = 15; 422 uint8 FMT = 15;
333 big_endian_writer.WriteU8(0x80 + FMT); 423 big_endian_writer.WriteU8(0x80 + FMT);
334 big_endian_writer.WriteU8(206); 424 big_endian_writer.WriteU8(kPacketTypePayloadSpecific);
335 big_endian_writer.WriteU8(0); 425 big_endian_writer.WriteU8(0);
336 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); 426 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4));
337 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 427 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
338 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. 428 big_endian_writer.WriteU32(0); // Remote SSRC must be 0.
339 big_endian_writer.WriteU32(kRemb); 429 big_endian_writer.WriteU32(kRemb);
340 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size())); 430 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size()));
341 431
342 // 6 bit exponent and a 18 bit mantissa. 432 // 6 bit exponent and a 18 bit mantissa.
343 uint8 bitrate_exponent; 433 uint8 bitrate_exponent;
344 uint32 bitrate_mantissa; 434 uint32 bitrate_mantissa;
(...skipping 19 matching lines...) Expand all
364 size_t start_size = packet->size(); 454 size_t start_size = packet->size();
365 DCHECK_LT(start_size + 16, kIpPacketSize) << "Not enough buffer space"; 455 DCHECK_LT(start_size + 16, kIpPacketSize) << "Not enough buffer space";
366 if (start_size + 16 > kIpPacketSize) return; 456 if (start_size + 16 > kIpPacketSize) return;
367 457
368 packet->resize(start_size + 16); 458 packet->resize(start_size + 16);
369 459
370 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 16); 460 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 16);
371 461
372 uint8 FMT = 1; 462 uint8 FMT = 1;
373 big_endian_writer.WriteU8(0x80 + FMT); 463 big_endian_writer.WriteU8(0x80 + FMT);
374 big_endian_writer.WriteU8(205); 464 big_endian_writer.WriteU8(kPacketTypeGenericRtpFeedback);
375 big_endian_writer.WriteU8(0); 465 big_endian_writer.WriteU8(0);
376 size_t nack_size_pos = start_size + 3; 466 size_t nack_size_pos = start_size + 3;
377 big_endian_writer.WriteU8(3); 467 big_endian_writer.WriteU8(3);
378 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 468 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
379 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC. 469 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC.
380 470
381 // Build NACK bitmasks and write them to the Rtcp message. 471 // Build NACK bitmasks and write them to the Rtcp message.
382 // The nack list should be sorted and not contain duplicates. 472 // The nack list should be sorted and not contain duplicates.
383 size_t number_of_nack_fields = 0; 473 size_t number_of_nack_fields = 0;
384 size_t max_number_of_nack_fields = std::min<size_t>(kRtcpMaxNackFields, 474 size_t max_number_of_nack_fields = std::min<size_t>(kRtcpMaxNackFields,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 508
419 void RtcpSender::BuildBye(std::vector<uint8>* packet) const { 509 void RtcpSender::BuildBye(std::vector<uint8>* packet) const {
420 size_t start_size = packet->size(); 510 size_t start_size = packet->size();
421 DCHECK_LT(start_size + 8, kIpPacketSize) << "Not enough buffer space"; 511 DCHECK_LT(start_size + 8, kIpPacketSize) << "Not enough buffer space";
422 if (start_size + 8 > kIpPacketSize) return; 512 if (start_size + 8 > kIpPacketSize) return;
423 513
424 packet->resize(start_size + 8); 514 packet->resize(start_size + 8);
425 515
426 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); 516 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8);
427 big_endian_writer.WriteU8(0x80 + 1); 517 big_endian_writer.WriteU8(0x80 + 1);
428 big_endian_writer.WriteU8(203); 518 big_endian_writer.WriteU8(kPacketTypeBye);
429 big_endian_writer.WriteU16(1); // Length. 519 big_endian_writer.WriteU16(1); // Length.
430 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 520 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
431 } 521 }
432 522
433 /* 523 /*
434 0 1 2 3 524 0 1 2 3
435 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 525 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
436 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 526 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
437 |V=2|P|reserved | PT=XR=207 | length | 527 |V=2|P|reserved | PT=XR=207 | length |
438 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 528 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
(...skipping 11 matching lines...) Expand all
450 void RtcpSender::BuildDlrrRb(const RtcpDlrrReportBlock* dlrr, 540 void RtcpSender::BuildDlrrRb(const RtcpDlrrReportBlock* dlrr,
451 std::vector<uint8>* packet) const { 541 std::vector<uint8>* packet) const {
452 size_t start_size = packet->size(); 542 size_t start_size = packet->size();
453 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space"; 543 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space";
454 if (start_size + 24 > kIpPacketSize) return; 544 if (start_size + 24 > kIpPacketSize) return;
455 545
456 packet->resize(start_size + 24); 546 packet->resize(start_size + 24);
457 547
458 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); 548 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24);
459 big_endian_writer.WriteU8(0x80); 549 big_endian_writer.WriteU8(0x80);
460 big_endian_writer.WriteU8(207); 550 big_endian_writer.WriteU8(kPacketTypeXr);
461 big_endian_writer.WriteU16(5); // Length. 551 big_endian_writer.WriteU16(5); // Length.
462 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 552 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
463 big_endian_writer.WriteU8(5); // Add block type. 553 big_endian_writer.WriteU8(5); // Add block type.
464 big_endian_writer.WriteU8(0); // Add reserved. 554 big_endian_writer.WriteU8(0); // Add reserved.
465 big_endian_writer.WriteU16(3); // Block length. 555 big_endian_writer.WriteU16(3); // Block length.
466 big_endian_writer.WriteU32(ssrc_); // Add the media (received RTP) SSRC. 556 big_endian_writer.WriteU32(ssrc_); // Add the media (received RTP) SSRC.
467 big_endian_writer.WriteU32(dlrr->last_rr); 557 big_endian_writer.WriteU32(dlrr->last_rr);
468 big_endian_writer.WriteU32(dlrr->delay_since_last_rr); 558 big_endian_writer.WriteU32(dlrr->delay_since_last_rr);
469 } 559 }
470 560
471 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, 561 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr,
472 std::vector<uint8>* packet) const { 562 std::vector<uint8>* packet) const {
473 size_t start_size = packet->size(); 563 size_t start_size = packet->size();
474 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space"; 564 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space";
475 if (start_size + 20 > kIpPacketSize) return; 565 if (start_size + 20 > kIpPacketSize) return;
476 566
477 packet->resize(start_size + 20); 567 packet->resize(start_size + 20);
478 568
479 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); 569 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20);
480 570
481 big_endian_writer.WriteU8(0x80); 571 big_endian_writer.WriteU8(0x80);
482 big_endian_writer.WriteU8(207); 572 big_endian_writer.WriteU8(kPacketTypeXr);
483 big_endian_writer.WriteU16(4); // Length. 573 big_endian_writer.WriteU16(4); // Length.
484 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 574 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
485 big_endian_writer.WriteU8(4); // Add block type. 575 big_endian_writer.WriteU8(4); // Add block type.
486 big_endian_writer.WriteU8(0); // Add reserved. 576 big_endian_writer.WriteU8(0); // Add reserved.
487 big_endian_writer.WriteU16(2); // Block length. 577 big_endian_writer.WriteU16(2); // Block length.
488 578
489 // Add the media (received RTP) SSRC. 579 // Add the media (received RTP) SSRC.
490 big_endian_writer.WriteU32(rrtr->ntp_seconds); 580 big_endian_writer.WriteU32(rrtr->ntp_seconds);
491 big_endian_writer.WriteU32(rrtr->ntp_fraction); 581 big_endian_writer.WriteU32(rrtr->ntp_fraction);
492 } 582 }
493 583
494 void RtcpSender::BuildCast(const RtcpCastMessage* cast, 584 void RtcpSender::BuildCast(const RtcpCastMessage* cast,
495 std::vector<uint8>* packet) const { 585 std::vector<uint8>* packet) const {
496 size_t start_size = packet->size(); 586 size_t start_size = packet->size();
497 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space"; 587 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space";
498 if (start_size + 20 > kIpPacketSize) return; 588 if (start_size + 20 > kIpPacketSize) return;
499 589
500 packet->resize(start_size + 20); 590 packet->resize(start_size + 20);
501 591
502 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); 592 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20);
503 uint8 FMT = 15; // Application layer feedback. 593 uint8 FMT = 15; // Application layer feedback.
504 big_endian_writer.WriteU8(0x80 + FMT); 594 big_endian_writer.WriteU8(0x80 + FMT);
505 big_endian_writer.WriteU8(206); 595 big_endian_writer.WriteU8(kPacketTypePayloadSpecific);
506 big_endian_writer.WriteU8(0); 596 big_endian_writer.WriteU8(0);
507 size_t cast_size_pos = start_size + 3; // Save length position. 597 size_t cast_size_pos = start_size + 3; // Save length position.
508 big_endian_writer.WriteU8(4); 598 big_endian_writer.WriteU8(4);
509 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 599 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
510 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. 600 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC.
511 big_endian_writer.WriteU32(kCast); 601 big_endian_writer.WriteU32(kCast);
512 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); 602 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_));
513 size_t cast_loss_field_pos = start_size + 17; // Save loss field position. 603 size_t cast_loss_field_pos = start_size + 17; // Save loss field position.
514 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields. 604 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields.
515 big_endian_writer.WriteU8(0); // Reserved. 605 big_endian_writer.WriteU8(0); // Reserved.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 } 656 }
567 DCHECK_LE(number_of_loss_fields, kRtcpMaxCastLossFields); 657 DCHECK_LE(number_of_loss_fields, kRtcpMaxCastLossFields);
568 (*packet)[cast_size_pos] = static_cast<uint8>(4 + number_of_loss_fields); 658 (*packet)[cast_size_pos] = static_cast<uint8>(4 + number_of_loss_fields);
569 (*packet)[cast_loss_field_pos] = static_cast<uint8>(number_of_loss_fields); 659 (*packet)[cast_loss_field_pos] = static_cast<uint8>(number_of_loss_fields);
570 660
571 // Frames with missing packets. 661 // Frames with missing packets.
572 TRACE_COUNTER_ID1("cast_rtcp", "RtcpSender::CastNACK", ssrc_, 662 TRACE_COUNTER_ID1("cast_rtcp", "RtcpSender::CastNACK", ssrc_,
573 cast->missing_frames_and_packets_.size()); 663 cast->missing_frames_and_packets_.size());
574 } 664 }
575 665
576 void RtcpSender::BuildSenderLog(const RtcpSenderLogMessage* sender_log_message, 666 void RtcpSender::BuildSenderLog(RtcpSenderLogMessage* sender_log_message,
577 std::vector<uint8>* packet) const { 667 std::vector<uint8>* packet) const {
578 // TODO(pwestin): Implement. 668 DCHECK(sender_log_message);
579 NOTIMPLEMENTED(); 669 DCHECK(packet);
670 static const size_t kRtcpMinSendLogSize = 16;
671 size_t start_size = packet->size();
672 size_t remaining_space = kIpPacketSize - start_size;
673 DCHECK_GE(remaining_space, kRtcpMinSendLogSize) << "Not enough buffer space";
674 if (remaining_space < kRtcpMinSendLogSize) return;
675
676 size_t space_for_x_messages = (remaining_space - 12) / 4;
677 size_t number_of_messages = std::min(space_for_x_messages,
678 sender_log_message->size());
679
680 size_t log_size = 12 + number_of_messages * 4;
681 packet->resize(start_size + log_size);
682
683 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), log_size);
684 big_endian_writer.WriteU8(0x80 + kSenderLogSubtype);
685 big_endian_writer.WriteU8(kPacketTypeApplicationDefined);
686 big_endian_writer.WriteU16(2 + number_of_messages);
687 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
688 big_endian_writer.WriteU32(kCast);
689
690 for (; number_of_messages > 0; --number_of_messages) {
691 DCHECK(!sender_log_message->empty());
692 const RtcpSenderFrameLogMessage& message = sender_log_message->front();
693 big_endian_writer.WriteU8(static_cast<uint8>(message.frame_status));
694 // We send the 24 east significant bits of the RTP timestamp.
695 big_endian_writer.WriteU8(static_cast<uint8>(message.rtp_timestamp >> 16));
696 big_endian_writer.WriteU8(static_cast<uint8>(message.rtp_timestamp >> 8));
697 big_endian_writer.WriteU8(static_cast<uint8>(message.rtp_timestamp));
698 sender_log_message->pop_front();
699 }
580 } 700 }
581 701
582 void RtcpSender::BuildReceiverLog( 702 void RtcpSender::BuildReceiverLog(RtcpReceiverLogMessage* receiver_log_message,
583 const RtcpReceiverLogMessage* receiver_log_message, 703 std::vector<uint8>* packet) const {
584 std::vector<uint8>* packet) const { 704 DCHECK(receiver_log_message);
585 // TODO(pwestin): Implement. 705 const size_t packet_start_size = packet->size();
586 NOTIMPLEMENTED(); 706 size_t number_of_frames = 0;
707 size_t total_number_of_messages_to_send = 0;
708 size_t rtcp_log_size = 0;
709
710 if (!ScanRtcpReceiverLogMessage(*receiver_log_message,
711 packet_start_size,
712 &number_of_frames,
713 &total_number_of_messages_to_send,
714 &rtcp_log_size)) {
715 return;
716 }
717 packet->resize(packet_start_size + rtcp_log_size);
718
719 net::BigEndianWriter big_endian_writer(&((*packet)[packet_start_size]),
720 rtcp_log_size);
721 big_endian_writer.WriteU8(0x80 + kReceiverLogSubtype);
722 big_endian_writer.WriteU8(kPacketTypeApplicationDefined);
723 big_endian_writer.WriteU16(2 + 2 * number_of_frames +
724 total_number_of_messages_to_send);
725 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
726 big_endian_writer.WriteU32(kCast);
727
728 while (!receiver_log_message->empty() &&
729 total_number_of_messages_to_send > 0) {
730 RtcpReceiverFrameLogMessage& frame_log_messages =
731 receiver_log_message->front();
732 // Add our frame header.
733 big_endian_writer.WriteU32(frame_log_messages.rtp_timestamp);
734 size_t messages_in_frame = frame_log_messages.event_log_messages.size();
735 if (messages_in_frame > total_number_of_messages_to_send) {
736 // We are running out of space.
737 messages_in_frame = total_number_of_messages_to_send;
738 }
739 // Keep track of how many messages we have left to send.
740 total_number_of_messages_to_send -= messages_in_frame;
741
742 // On the wire format is number of messages - 1.
743 big_endian_writer.WriteU8(messages_in_frame - 1);
744
745 base::TimeTicks event_timestamp_base =
746 frame_log_messages.event_log_messages.front().event_timestamp;
747 uint32 base_timestamp_ms =
748 (event_timestamp_base - base::TimeTicks()).InMilliseconds();
749 big_endian_writer.WriteU8(static_cast<uint8>(base_timestamp_ms >> 16));
750 big_endian_writer.WriteU8(static_cast<uint8>(base_timestamp_ms >> 8));
751 big_endian_writer.WriteU8(static_cast<uint8>(base_timestamp_ms));
752
753 while (!frame_log_messages.event_log_messages.empty() &&
754 messages_in_frame > 0) {
755 const RtcpReceiverEventLogMessage& event_message =
756 frame_log_messages.event_log_messages.front();
757 uint16 event_type_and_timestamp_delta =
758 MergeEventTypeAndTimestampForWireFormat(event_message.type,
759 event_message.event_timestamp - event_timestamp_base);
760 switch (event_message.type) {
761 case kAckSent:
762 case kAudioPlayoutDelay:
763 case kAudioFrameDecoded:
764 case kVideoFrameDecoded:
765 case kVideoRenderDelay:
766 big_endian_writer.WriteU16(static_cast<uint16>(
767 event_message.delay_delta.InMilliseconds()));
768 big_endian_writer.WriteU16(event_type_and_timestamp_delta);
769 break;
770 case kPacketReceived:
771 big_endian_writer.WriteU16(event_message.packet_id);
772 big_endian_writer.WriteU16(event_type_and_timestamp_delta);
773 break;
774 default:
775 NOTREACHED();
776 }
777 messages_in_frame--;
778 frame_log_messages.event_log_messages.pop_front();
779 }
780 if (frame_log_messages.event_log_messages.empty()) {
781 // We sent all messages on this frame; pop the frame header.
782 receiver_log_message->pop_front();
783 }
784 }
785 DCHECK_EQ(total_number_of_messages_to_send, 0);
587 } 786 }
588 787
589 } // namespace cast 788 } // namespace cast
590 } // namespace media 789 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698