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