OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |