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

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

Powered by Google App Engine
This is Rietveld 408576698