Home | History | Annotate | Download | only in rtcp
      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