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 3 // found in the LICENSE file. 4 5 #include "media/cast/rtcp/rtcp_sender.h" 6 7 #include <algorithm> 8 #include <vector> 9 10 #include "base/logging.h" 11 #include "media/cast/cast_environment.h" 12 #include "media/cast/net/pacing/paced_sender.h" 13 #include "media/cast/rtcp/rtcp_utility.h" 14 #include "net/base/big_endian.h" 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 123 namespace media { 124 namespace cast { 125 126 RtcpSender::RtcpSender(scoped_refptr<CastEnvironment> cast_environment, 127 PacedPacketSender* outgoing_transport, 128 uint32 sending_ssrc, 129 const std::string& c_name) 130 : ssrc_(sending_ssrc), 131 c_name_(c_name), 132 transport_(outgoing_transport), 133 cast_environment_(cast_environment) { 134 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config"; 135 } 136 137 RtcpSender::~RtcpSender() {} 138 139 void RtcpSender::SendRtcpFromRtpSender(uint32 packet_type_flags, 140 const RtcpSenderInfo* sender_info, 141 const RtcpDlrrReportBlock* dlrr, 142 RtcpSenderLogMessage* sender_log) { 143 if (packet_type_flags & kRtcpRr || 144 packet_type_flags & kRtcpPli || 145 packet_type_flags & kRtcpRrtr || 146 packet_type_flags & kRtcpCast || 147 packet_type_flags & kRtcpReceiverLog || 148 packet_type_flags & kRtcpRpsi || 149 packet_type_flags & kRtcpRemb || 150 packet_type_flags & kRtcpNack) { 151 NOTREACHED() << "Invalid argument"; 152 } 153 154 std::vector<uint8> packet; 155 packet.reserve(kIpPacketSize); 156 if (packet_type_flags & kRtcpSr) { 157 DCHECK(sender_info) << "Invalid argument"; 158 BuildSR(*sender_info, NULL, &packet); 159 BuildSdec(&packet); 160 } 161 if (packet_type_flags & kRtcpBye) { 162 BuildBye(&packet); 163 } 164 if (packet_type_flags & kRtcpDlrr) { 165 DCHECK(dlrr) << "Invalid argument"; 166 BuildDlrrRb(dlrr, &packet); 167 } 168 if (packet_type_flags & kRtcpSenderLog) { 169 DCHECK(sender_log) << "Invalid argument"; 170 BuildSenderLog(sender_log, &packet); 171 } 172 if (packet.empty()) 173 return; // Sanity don't send empty packets. 174 175 transport_->SendRtcpPacket(packet); 176 } 177 178 void RtcpSender::SendRtcpFromRtpReceiver( 179 uint32 packet_type_flags, 180 const RtcpReportBlock* report_block, 181 const RtcpReceiverReferenceTimeReport* rrtr, 182 const RtcpCastMessage* cast_message, 183 RtcpReceiverLogMessage* receiver_log) { 184 if (packet_type_flags & kRtcpSr || 185 packet_type_flags & kRtcpDlrr || 186 packet_type_flags & kRtcpSenderLog) { 187 NOTREACHED() << "Invalid argument"; 188 } 189 if (packet_type_flags & kRtcpPli || 190 packet_type_flags & kRtcpRpsi || 191 packet_type_flags & kRtcpRemb || 192 packet_type_flags & kRtcpNack) { 193 // Implement these for webrtc interop. 194 NOTIMPLEMENTED(); 195 } 196 std::vector<uint8> packet; 197 packet.reserve(kIpPacketSize); 198 199 if (packet_type_flags & kRtcpRr) { 200 BuildRR(report_block, &packet); 201 if (!c_name_.empty()) { 202 BuildSdec(&packet); 203 } 204 } 205 if (packet_type_flags & kRtcpBye) { 206 BuildBye(&packet); 207 } 208 if (packet_type_flags & kRtcpRrtr) { 209 DCHECK(rrtr) << "Invalid argument"; 210 BuildRrtr(rrtr, &packet); 211 } 212 if (packet_type_flags & kRtcpCast) { 213 DCHECK(cast_message) << "Invalid argument"; 214 BuildCast(cast_message, &packet); 215 } 216 if (packet_type_flags & kRtcpReceiverLog) { 217 DCHECK(receiver_log) << "Invalid argument"; 218 BuildReceiverLog(receiver_log, &packet); 219 } 220 if (packet.empty()) return; // Sanity don't send empty packets. 221 222 transport_->SendRtcpPacket(packet); 223 } 224 225 void RtcpSender::BuildSR(const RtcpSenderInfo& sender_info, 226 const RtcpReportBlock* report_block, 227 std::vector<uint8>* packet) const { 228 // Sender report. 229 size_t start_size = packet->size(); 230 DCHECK_LT(start_size + 52, kIpPacketSize) << "Not enough buffer space"; 231 if (start_size + 52 > kIpPacketSize) return; 232 233 uint16 number_of_rows = (report_block) ? 12 : 6; 234 packet->resize(start_size + 28); 235 236 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 28); 237 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); 238 big_endian_writer.WriteU8(kPacketTypeSenderReport); 239 big_endian_writer.WriteU16(number_of_rows); 240 big_endian_writer.WriteU32(ssrc_); 241 big_endian_writer.WriteU32(sender_info.ntp_seconds); 242 big_endian_writer.WriteU32(sender_info.ntp_fraction); 243 big_endian_writer.WriteU32(sender_info.rtp_timestamp); 244 big_endian_writer.WriteU32(sender_info.send_packet_count); 245 big_endian_writer.WriteU32(static_cast<uint32>(sender_info.send_octet_count)); 246 247 if (report_block) { 248 AddReportBlocks(*report_block, packet); // Adds 24 bytes. 249 } 250 } 251 252 void RtcpSender::BuildRR(const RtcpReportBlock* report_block, 253 std::vector<uint8>* packet) const { 254 size_t start_size = packet->size(); 255 DCHECK_LT(start_size + 32, kIpPacketSize) << "Not enough buffer space"; 256 if (start_size + 32 > kIpPacketSize) return; 257 258 uint16 number_of_rows = (report_block) ? 7 : 1; 259 packet->resize(start_size + 8); 260 261 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); 262 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); 263 big_endian_writer.WriteU8(kPacketTypeReceiverReport); 264 big_endian_writer.WriteU16(number_of_rows); 265 big_endian_writer.WriteU32(ssrc_); 266 267 if (report_block) { 268 AddReportBlocks(*report_block, packet); // Adds 24 bytes. 269 } 270 } 271 272 void RtcpSender::AddReportBlocks(const RtcpReportBlock& report_block, 273 std::vector<uint8>* packet) const { 274 size_t start_size = packet->size(); 275 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space"; 276 if (start_size + 24 > kIpPacketSize) return; 277 278 packet->resize(start_size + 24); 279 280 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); 281 big_endian_writer.WriteU32(report_block.media_ssrc); 282 big_endian_writer.WriteU8(report_block.fraction_lost); 283 big_endian_writer.WriteU8(report_block.cumulative_lost >> 16); 284 big_endian_writer.WriteU8(report_block.cumulative_lost >> 8); 285 big_endian_writer.WriteU8(report_block.cumulative_lost); 286 287 // Extended highest seq_no, contain the highest sequence number received. 288 big_endian_writer.WriteU32(report_block.extended_high_sequence_number); 289 big_endian_writer.WriteU32(report_block.jitter); 290 291 // Last SR timestamp; our NTP time when we received the last report. 292 // This is the value that we read from the send report packet not when we 293 // received it. 294 big_endian_writer.WriteU32(report_block.last_sr); 295 296 // Delay since last received report, time since we received the report. 297 big_endian_writer.WriteU32(report_block.delay_since_last_sr); 298 } 299 300 void RtcpSender::BuildSdec(std::vector<uint8>* packet) const { 301 size_t start_size = packet->size(); 302 DCHECK_LT(start_size + 12 + c_name_.length(), kIpPacketSize) 303 << "Not enough buffer space"; 304 if (start_size + 12 > kIpPacketSize) return; 305 306 // SDES Source Description. 307 packet->resize(start_size + 10); 308 309 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 10); 310 // We always need to add one SDES CNAME. 311 big_endian_writer.WriteU8(0x80 + 1); 312 big_endian_writer.WriteU8(kPacketTypeSdes); 313 314 // Handle SDES length later on. 315 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; 316 big_endian_writer.WriteU16(0); 317 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 318 big_endian_writer.WriteU8(1); // CNAME = 1 319 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); 320 321 size_t sdes_length = 10 + c_name_.length(); 322 packet->insert(packet->end(), c_name_.c_str(), 323 c_name_.c_str() + c_name_.length()); 324 325 size_t padding = 0; 326 327 // We must have a zero field even if we have an even multiple of 4 bytes. 328 if ((packet->size() % 4) == 0) { 329 padding++; 330 packet->push_back(0); 331 } 332 while ((packet->size() % 4) != 0) { 333 padding++; 334 packet->push_back(0); 335 } 336 sdes_length += padding; 337 338 // In 32-bit words minus one and we don't count the header. 339 uint8 buffer_length = static_cast<uint8>((sdes_length / 4) - 1); 340 (*packet)[sdes_length_position] = buffer_length; 341 } 342 343 void RtcpSender::BuildPli(uint32 remote_ssrc, 344 std::vector<uint8>* packet) const { 345 size_t start_size = packet->size(); 346 DCHECK_LT(start_size + 12, kIpPacketSize) << "Not enough buffer space"; 347 if (start_size + 12 > kIpPacketSize) return; 348 349 packet->resize(start_size + 12); 350 351 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 12); 352 uint8 FMT = 1; // Picture loss indicator. 353 big_endian_writer.WriteU8(0x80 + FMT); 354 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); 355 big_endian_writer.WriteU16(2); // Used fixed length of 2. 356 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 357 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. 358 } 359 360 /* 361 0 1 2 3 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 363 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 364 | PB |0| Payload Type| Native Rpsi bit string | 365 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 366 | defined per codec ... | Padding (0) | 367 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 368 */ 369 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, 370 std::vector<uint8>* packet) const { 371 size_t start_size = packet->size(); 372 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space"; 373 if (start_size + 24 > kIpPacketSize) return; 374 375 packet->resize(start_size + 24); 376 377 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); 378 uint8 FMT = 3; // Reference Picture Selection Indication. 379 big_endian_writer.WriteU8(0x80 + FMT); 380 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); 381 382 // Calculate length. 383 uint32 bits_required = 7; 384 uint8 bytes_required = 1; 385 while ((rpsi->picture_id >> bits_required) > 0) { 386 bits_required += 7; 387 bytes_required++; 388 } 389 uint8 size = 3; 390 if (bytes_required > 6) { 391 size = 5; 392 } else if (bytes_required > 2) { 393 size = 4; 394 } 395 big_endian_writer.WriteU8(0); 396 big_endian_writer.WriteU8(size); 397 big_endian_writer.WriteU32(ssrc_); 398 big_endian_writer.WriteU32(rpsi->remote_ssrc); 399 400 uint8 padding_bytes = 4 - ((2 + bytes_required) % 4); 401 if (padding_bytes == 4) { 402 padding_bytes = 0; 403 } 404 // Add padding length in bits, padding can be 0, 8, 16 or 24. 405 big_endian_writer.WriteU8(padding_bytes * 8); 406 big_endian_writer.WriteU8(rpsi->payload_type); 407 408 // Add picture ID. 409 for (int i = bytes_required - 1; i > 0; i--) { 410 big_endian_writer.WriteU8( 411 0x80 | static_cast<uint8>(rpsi->picture_id >> (i * 7))); 412 } 413 // Add last byte of picture ID. 414 big_endian_writer.WriteU8(static_cast<uint8>(rpsi->picture_id & 0x7f)); 415 416 // Add padding. 417 for (int j = 0; j < padding_bytes; ++j) { 418 big_endian_writer.WriteU8(0); 419 } 420 } 421 422 void RtcpSender::BuildRemb(const RtcpRembMessage* remb, 423 std::vector<uint8>* packet) const { 424 size_t start_size = packet->size(); 425 size_t remb_size = 20 + 4 * remb->remb_ssrcs.size(); 426 DCHECK_LT(start_size + remb_size, kIpPacketSize) 427 << "Not enough buffer space"; 428 if (start_size + remb_size > kIpPacketSize) return; 429 430 packet->resize(start_size + remb_size); 431 432 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), remb_size); 433 434 // Add application layer feedback. 435 uint8 FMT = 15; 436 big_endian_writer.WriteU8(0x80 + FMT); 437 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); 438 big_endian_writer.WriteU8(0); 439 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); 440 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 441 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. 442 big_endian_writer.WriteU32(kRemb); 443 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size())); 444 445 // 6 bit exponent and a 18 bit mantissa. 446 uint8 bitrate_exponent; 447 uint32 bitrate_mantissa; 448 BitrateToRembExponentBitrate(remb->remb_bitrate, 449 &bitrate_exponent, 450 &bitrate_mantissa); 451 452 big_endian_writer.WriteU8(static_cast<uint8>((bitrate_exponent << 2) + 453 ((bitrate_mantissa >> 16) & 0x03))); 454 big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa >> 8)); 455 big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa)); 456 457 std::list<uint32>::const_iterator it = remb->remb_ssrcs.begin(); 458 for (; it != remb->remb_ssrcs.end(); ++it) { 459 big_endian_writer.WriteU32(*it); 460 } 461 cast_environment_->Logging()->InsertGenericEvent(kRembBitrate, 462 remb->remb_bitrate); 463 } 464 465 void RtcpSender::BuildNack(const RtcpNackMessage* nack, 466 std::vector<uint8>* packet) const { 467 size_t start_size = packet->size(); 468 DCHECK_LT(start_size + 16, kIpPacketSize) << "Not enough buffer space"; 469 if (start_size + 16 > kIpPacketSize) return; 470 471 packet->resize(start_size + 16); 472 473 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 16); 474 475 uint8 FMT = 1; 476 big_endian_writer.WriteU8(0x80 + FMT); 477 big_endian_writer.WriteU8(kPacketTypeGenericRtpFeedback); 478 big_endian_writer.WriteU8(0); 479 size_t nack_size_pos = start_size + 3; 480 big_endian_writer.WriteU8(3); 481 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 482 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC. 483 484 // Build NACK bitmasks and write them to the Rtcp message. 485 // The nack list should be sorted and not contain duplicates. 486 size_t number_of_nack_fields = 0; 487 size_t max_number_of_nack_fields = std::min<size_t>(kRtcpMaxNackFields, 488 (kIpPacketSize - packet->size()) / 4); 489 490 std::list<uint16>::const_iterator it = nack->nack_list.begin(); 491 while (it != nack->nack_list.end() && 492 number_of_nack_fields < max_number_of_nack_fields) { 493 uint16 nack_sequence_number = *it; 494 uint16 bitmask = 0; 495 ++it; 496 while (it != nack->nack_list.end()) { 497 int shift = static_cast<uint16>(*it - nack_sequence_number) - 1; 498 if (shift >= 0 && shift <= 15) { 499 bitmask |= (1 << shift); 500 ++it; 501 } else { 502 break; 503 } 504 } 505 // Write the sequence number and the bitmask to the packet. 506 start_size = packet->size(); 507 DCHECK_LT(start_size + 4, kIpPacketSize) << "Not enough buffer space"; 508 if (start_size + 4 > kIpPacketSize) return; 509 510 packet->resize(start_size + 4); 511 net::BigEndianWriter big_endian_nack_writer(&((*packet)[start_size]), 4); 512 big_endian_nack_writer.WriteU16(nack_sequence_number); 513 big_endian_nack_writer.WriteU16(bitmask); 514 number_of_nack_fields++; 515 } 516 DCHECK_GE(kRtcpMaxNackFields, number_of_nack_fields); 517 (*packet)[nack_size_pos] = static_cast<uint8>(2 + number_of_nack_fields); 518 } 519 520 void RtcpSender::BuildBye(std::vector<uint8>* packet) const { 521 size_t start_size = packet->size(); 522 DCHECK_LT(start_size + 8, kIpPacketSize) << "Not enough buffer space"; 523 if (start_size + 8 > kIpPacketSize) return; 524 525 packet->resize(start_size + 8); 526 527 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); 528 big_endian_writer.WriteU8(0x80 + 1); 529 big_endian_writer.WriteU8(kPacketTypeBye); 530 big_endian_writer.WriteU16(1); // Length. 531 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 532 } 533 534 /* 535 0 1 2 3 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 537 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 538 |V=2|P|reserved | PT=XR=207 | length | 539 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 540 | SSRC | 541 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 542 | BT=5 | reserved | block length | 543 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 544 | SSRC_1 (SSRC of first receiver) | sub- 545 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block 546 | last RR (LRR) | 1 547 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 548 | delay since last RR (DLRR) | 549 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 550 */ 551 void RtcpSender::BuildDlrrRb(const RtcpDlrrReportBlock* dlrr, 552 std::vector<uint8>* packet) const { 553 size_t start_size = packet->size(); 554 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space"; 555 if (start_size + 24 > kIpPacketSize) return; 556 557 packet->resize(start_size + 24); 558 559 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); 560 big_endian_writer.WriteU8(0x80); 561 big_endian_writer.WriteU8(kPacketTypeXr); 562 big_endian_writer.WriteU16(5); // Length. 563 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 564 big_endian_writer.WriteU8(5); // Add block type. 565 big_endian_writer.WriteU8(0); // Add reserved. 566 big_endian_writer.WriteU16(3); // Block length. 567 big_endian_writer.WriteU32(ssrc_); // Add the media (received RTP) SSRC. 568 big_endian_writer.WriteU32(dlrr->last_rr); 569 big_endian_writer.WriteU32(dlrr->delay_since_last_rr); 570 } 571 572 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, 573 std::vector<uint8>* packet) const { 574 size_t start_size = packet->size(); 575 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space"; 576 if (start_size + 20 > kIpPacketSize) return; 577 578 packet->resize(start_size + 20); 579 580 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); 581 582 big_endian_writer.WriteU8(0x80); 583 big_endian_writer.WriteU8(kPacketTypeXr); 584 big_endian_writer.WriteU16(4); // Length. 585 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 586 big_endian_writer.WriteU8(4); // Add block type. 587 big_endian_writer.WriteU8(0); // Add reserved. 588 big_endian_writer.WriteU16(2); // Block length. 589 590 // Add the media (received RTP) SSRC. 591 big_endian_writer.WriteU32(rrtr->ntp_seconds); 592 big_endian_writer.WriteU32(rrtr->ntp_fraction); 593 } 594 595 void RtcpSender::BuildCast(const RtcpCastMessage* cast, 596 std::vector<uint8>* packet) const { 597 size_t start_size = packet->size(); 598 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space"; 599 if (start_size + 20 > kIpPacketSize) return; 600 601 packet->resize(start_size + 20); 602 603 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); 604 uint8 FMT = 15; // Application layer feedback. 605 big_endian_writer.WriteU8(0x80 + FMT); 606 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); 607 big_endian_writer.WriteU8(0); 608 size_t cast_size_pos = start_size + 3; // Save length position. 609 big_endian_writer.WriteU8(4); 610 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 611 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. 612 big_endian_writer.WriteU32(kCast); 613 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); 614 size_t cast_loss_field_pos = start_size + 17; // Save loss field position. 615 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields. 616 big_endian_writer.WriteU8(0); // Reserved. 617 big_endian_writer.WriteU8(0); // Reserved. 618 619 size_t number_of_loss_fields = 0; 620 size_t max_number_of_loss_fields = std::min<size_t>(kRtcpMaxCastLossFields, 621 (kIpPacketSize - packet->size()) / 4); 622 623 MissingFramesAndPacketsMap::const_iterator frame_it = 624 cast->missing_frames_and_packets_.begin(); 625 626 for (; frame_it != cast->missing_frames_and_packets_.end() && 627 number_of_loss_fields < max_number_of_loss_fields; ++frame_it) { 628 // Iterate through all frames with missing packets. 629 if (frame_it->second.empty()) { 630 // Special case all packets in a frame is missing. 631 start_size = packet->size(); 632 packet->resize(start_size + 4); 633 net::BigEndianWriter big_endian_nack_writer(&((*packet)[start_size]), 4); 634 big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first)); 635 big_endian_nack_writer.WriteU16(kRtcpCastAllPacketsLost); 636 big_endian_nack_writer.WriteU8(0); 637 ++number_of_loss_fields; 638 } else { 639 PacketIdSet::const_iterator packet_it = frame_it->second.begin(); 640 while (packet_it != frame_it->second.end()) { 641 uint16 packet_id = *packet_it; 642 643 start_size = packet->size(); 644 packet->resize(start_size + 4); 645 net::BigEndianWriter big_endian_nack_writer( 646 &((*packet)[start_size]), 4); 647 648 // Write frame and packet id to buffer before calculating bitmask. 649 big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first)); 650 big_endian_nack_writer.WriteU16(packet_id); 651 652 uint8 bitmask = 0; 653 ++packet_it; 654 while (packet_it != frame_it->second.end()) { 655 int shift = static_cast<uint8>(*packet_it - packet_id) - 1; 656 if (shift >= 0 && shift <= 7) { 657 bitmask |= (1 << shift); 658 ++packet_it; 659 } else { 660 break; 661 } 662 } 663 big_endian_nack_writer.WriteU8(bitmask); 664 ++number_of_loss_fields; 665 } 666 } 667 } 668 DCHECK_LE(number_of_loss_fields, kRtcpMaxCastLossFields); 669 (*packet)[cast_size_pos] = static_cast<uint8>(4 + number_of_loss_fields); 670 (*packet)[cast_loss_field_pos] = static_cast<uint8>(number_of_loss_fields); 671 } 672 673 void RtcpSender::BuildSenderLog(RtcpSenderLogMessage* sender_log_message, 674 std::vector<uint8>* packet) const { 675 DCHECK(sender_log_message); 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 } 710 } 711 712 void RtcpSender::BuildReceiverLog(RtcpReceiverLogMessage* receiver_log_message, 713 std::vector<uint8>* packet) const { 714 DCHECK(receiver_log_message); 715 const size_t packet_start_size = packet->size(); 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); 796 } 797 798 } // namespace cast 799 } // namespace media 800