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/test_rtcp_packet_builder.h"
      6 
      7 #include "base/logging.h"
      8 
      9 namespace media {
     10 namespace cast {
     11 
     12 TestRtcpPacketBuilder::TestRtcpPacketBuilder()
     13     : ptr_of_length_(NULL),
     14       big_endian_writer_(buffer_, kIpPacketSize) {
     15 }
     16 
     17 void TestRtcpPacketBuilder::AddSr(uint32 sender_ssrc,
     18                                   int number_of_report_blocks) {
     19   AddRtcpHeader(200, number_of_report_blocks);
     20   big_endian_writer_.WriteU32(sender_ssrc);
     21   big_endian_writer_.WriteU32(kNtpHigh);  // NTP timestamp.
     22   big_endian_writer_.WriteU32(kNtpLow);
     23   big_endian_writer_.WriteU32(kRtpTimestamp);
     24   big_endian_writer_.WriteU32(kSendPacketCount);
     25   big_endian_writer_.WriteU32(kSendOctetCount);
     26 }
     27 
     28 void TestRtcpPacketBuilder::AddSrWithNtp(uint32 sender_ssrc,
     29                                          uint32 ntp_high,
     30                                          uint32 ntp_low,
     31                                          uint32 rtp_timestamp) {
     32   AddRtcpHeader(200, 0);
     33   big_endian_writer_.WriteU32(sender_ssrc);
     34   big_endian_writer_.WriteU32(ntp_high);
     35   big_endian_writer_.WriteU32(ntp_low);
     36   big_endian_writer_.WriteU32(rtp_timestamp);
     37   big_endian_writer_.WriteU32(kSendPacketCount);
     38   big_endian_writer_.WriteU32(kSendOctetCount);
     39 }
     40 
     41 void TestRtcpPacketBuilder::AddRr(uint32 sender_ssrc,
     42                                   int number_of_report_blocks) {
     43   AddRtcpHeader(201, number_of_report_blocks);
     44   big_endian_writer_.WriteU32(sender_ssrc);
     45 }
     46 
     47 void TestRtcpPacketBuilder::AddRb(uint32 rtp_ssrc) {
     48   big_endian_writer_.WriteU32(rtp_ssrc);
     49   big_endian_writer_.WriteU32(kLoss);
     50   big_endian_writer_.WriteU32(kExtendedMax);
     51   big_endian_writer_.WriteU32(kTestJitter);
     52   big_endian_writer_.WriteU32(kLastSr);
     53   big_endian_writer_.WriteU32(kDelayLastSr);
     54 }
     55 
     56 void TestRtcpPacketBuilder::AddSdesCname(uint32 sender_ssrc,
     57                                          const std::string& c_name) {
     58   AddRtcpHeader(202, 1);
     59   big_endian_writer_.WriteU32(sender_ssrc);
     60   big_endian_writer_.WriteU8(1);  // c_name.
     61 
     62   DCHECK_LE(c_name.size(), 255u);
     63   big_endian_writer_.WriteU8(
     64       static_cast<uint8>(c_name.size()));  // c_name length in bytes.
     65   for (size_t i = 0; i < c_name.size(); ++i) {
     66     big_endian_writer_.WriteU8(c_name.c_str()[i]);
     67   }
     68   int padding;
     69   switch (c_name.size() % 4) {
     70     case 0:
     71       padding = 2;
     72       break;
     73     case 1:
     74       padding = 1;
     75       break;
     76     case 2:
     77       padding = 4;
     78       break;
     79     case 3:
     80       padding = 3;
     81       break;
     82   }
     83   for (int j = 0; j < padding; ++j) {
     84     big_endian_writer_.WriteU8(0);
     85   }
     86 }
     87 
     88 void TestRtcpPacketBuilder::AddXrHeader(uint32 sender_ssrc) {
     89   AddRtcpHeader(207, 0);
     90   big_endian_writer_.WriteU32(sender_ssrc);
     91 }
     92 
     93 void TestRtcpPacketBuilder::AddXrUnknownBlock() {
     94   big_endian_writer_.WriteU8(9);  // Block type.
     95   big_endian_writer_.WriteU8(0);  // Reserved.
     96   big_endian_writer_.WriteU16(4);  // Block length.
     97   // First receiver same as sender of this report.
     98   big_endian_writer_.WriteU32(0);
     99   big_endian_writer_.WriteU32(0);
    100   big_endian_writer_.WriteU32(0);
    101   big_endian_writer_.WriteU32(0);
    102 }
    103 
    104 void TestRtcpPacketBuilder::AddXrDlrrBlock(uint32 sender_ssrc) {
    105   big_endian_writer_.WriteU8(5);  // Block type.
    106   big_endian_writer_.WriteU8(0);  // Reserved.
    107   big_endian_writer_.WriteU16(3);  // Block length.
    108 
    109   // First receiver same as sender of this report.
    110   big_endian_writer_.WriteU32(sender_ssrc);
    111   big_endian_writer_.WriteU32(kLastRr);
    112   big_endian_writer_.WriteU32(kDelayLastRr);
    113 }
    114 
    115 void TestRtcpPacketBuilder::AddXrExtendedDlrrBlock(uint32 sender_ssrc) {
    116   big_endian_writer_.WriteU8(5);  // Block type.
    117   big_endian_writer_.WriteU8(0);  // Reserved.
    118   big_endian_writer_.WriteU16(9);  // Block length.
    119   big_endian_writer_.WriteU32(0xaaaaaaaa);
    120   big_endian_writer_.WriteU32(0xaaaaaaaa);
    121   big_endian_writer_.WriteU32(0xaaaaaaaa);
    122 
    123   // First receiver same as sender of this report.
    124   big_endian_writer_.WriteU32(sender_ssrc);
    125   big_endian_writer_.WriteU32(kLastRr);
    126   big_endian_writer_.WriteU32(kDelayLastRr);
    127   big_endian_writer_.WriteU32(0xbbbbbbbb);
    128   big_endian_writer_.WriteU32(0xbbbbbbbb);
    129   big_endian_writer_.WriteU32(0xbbbbbbbb);
    130 }
    131 
    132 void TestRtcpPacketBuilder::AddXrRrtrBlock() {
    133   big_endian_writer_.WriteU8(4);  // Block type.
    134   big_endian_writer_.WriteU8(0);  // Reserved.
    135   big_endian_writer_.WriteU16(2);  // Block length.
    136   big_endian_writer_.WriteU32(kNtpHigh);
    137   big_endian_writer_.WriteU32(kNtpLow);
    138 }
    139 
    140 void TestRtcpPacketBuilder::AddNack(uint32 sender_ssrc, uint32 media_ssrc) {
    141   AddRtcpHeader(205, 1);
    142   big_endian_writer_.WriteU32(sender_ssrc);
    143   big_endian_writer_.WriteU32(media_ssrc);
    144   big_endian_writer_.WriteU16(kMissingPacket);
    145   big_endian_writer_.WriteU16(0);
    146 }
    147 
    148 void TestRtcpPacketBuilder::AddSendReportRequest(uint32 sender_ssrc,
    149                                                  uint32 media_ssrc) {
    150   AddRtcpHeader(205, 5);
    151   big_endian_writer_.WriteU32(sender_ssrc);
    152   big_endian_writer_.WriteU32(media_ssrc);
    153 }
    154 
    155 void TestRtcpPacketBuilder::AddPli(uint32 sender_ssrc, uint32 media_ssrc) {
    156   AddRtcpHeader(206, 1);
    157   big_endian_writer_.WriteU32(sender_ssrc);
    158   big_endian_writer_.WriteU32(media_ssrc);
    159 }
    160 
    161 void TestRtcpPacketBuilder::AddRpsi(uint32 sender_ssrc, uint32 media_ssrc) {
    162   AddRtcpHeader(206, 3);
    163   big_endian_writer_.WriteU32(sender_ssrc);
    164   big_endian_writer_.WriteU32(media_ssrc);
    165   big_endian_writer_.WriteU8(0);  // Padding bits.
    166   big_endian_writer_.WriteU8(kPayloadtype);
    167   uint64 picture_id = kPictureId;
    168 
    169   for (int i = 9; i > 0; i--) {
    170     big_endian_writer_.WriteU8(
    171         0x80 | static_cast<uint8>(picture_id >> (i * 7)));
    172   }
    173   // Add last byte of picture ID.
    174   big_endian_writer_.WriteU8(static_cast<uint8>(picture_id & 0x7f));
    175 }
    176 
    177 void TestRtcpPacketBuilder::AddRemb(uint32 sender_ssrc, uint32 media_ssrc) {
    178   AddRtcpHeader(206, 15);
    179   big_endian_writer_.WriteU32(sender_ssrc);
    180   big_endian_writer_.WriteU32(0);
    181   big_endian_writer_.WriteU8('R');
    182   big_endian_writer_.WriteU8('E');
    183   big_endian_writer_.WriteU8('M');
    184   big_endian_writer_.WriteU8('B');
    185   big_endian_writer_.WriteU8(1);  // Number of SSRCs.
    186   big_endian_writer_.WriteU8(1);  // BR Exp.
    187   //  BR Mantissa.
    188   big_endian_writer_.WriteU16(static_cast<uint16>(kTestRembBitrate / 2));
    189   big_endian_writer_.WriteU32(media_ssrc);
    190 }
    191 
    192 void TestRtcpPacketBuilder::AddCast(uint32 sender_ssrc, uint32 media_ssrc) {
    193   AddRtcpHeader(206, 15);
    194   big_endian_writer_.WriteU32(sender_ssrc);
    195   big_endian_writer_.WriteU32(media_ssrc);
    196   big_endian_writer_.WriteU8('C');
    197   big_endian_writer_.WriteU8('A');
    198   big_endian_writer_.WriteU8('S');
    199   big_endian_writer_.WriteU8('T');
    200   big_endian_writer_.WriteU8(kAckFrameId);
    201   big_endian_writer_.WriteU8(3);  // Loss fields.
    202   big_endian_writer_.WriteU16(0);  // Reserved.
    203   big_endian_writer_.WriteU8(kLostFrameId);
    204   big_endian_writer_.WriteU16(kRtcpCastAllPacketsLost);
    205   big_endian_writer_.WriteU8(0);  // Lost packet id mask.
    206   big_endian_writer_.WriteU8(kFrameIdWithLostPackets);
    207   big_endian_writer_.WriteU16(kLostPacketId1);
    208   big_endian_writer_.WriteU8(0x2);  // Lost packet id mask.
    209   big_endian_writer_.WriteU8(kFrameIdWithLostPackets);
    210   big_endian_writer_.WriteU16(kLostPacketId3);
    211   big_endian_writer_.WriteU8(0);  // Lost packet id mask.
    212 }
    213 
    214 void TestRtcpPacketBuilder::AddSenderLog(uint32 sender_ssrc) {
    215   AddRtcpHeader(204, 1);
    216   big_endian_writer_.WriteU32(sender_ssrc);
    217   big_endian_writer_.WriteU8('C');
    218   big_endian_writer_.WriteU8('A');
    219   big_endian_writer_.WriteU8('S');
    220   big_endian_writer_.WriteU8('T');
    221 }
    222 
    223 void TestRtcpPacketBuilder::AddSenderFrameLog(uint8 event_id,
    224                                               uint32 rtp_timestamp) {
    225   big_endian_writer_.WriteU32(
    226       (static_cast<uint32>(event_id) << 24) + (rtp_timestamp & 0xffffff));
    227 }
    228 
    229 void TestRtcpPacketBuilder::AddReceiverLog(uint32 sender_ssrc) {
    230   AddRtcpHeader(204, 2);
    231   big_endian_writer_.WriteU32(sender_ssrc);
    232   big_endian_writer_.WriteU8('C');
    233   big_endian_writer_.WriteU8('A');
    234   big_endian_writer_.WriteU8('S');
    235   big_endian_writer_.WriteU8('T');
    236 }
    237 
    238 void TestRtcpPacketBuilder::AddReceiverFrameLog(uint32 rtp_timestamp,
    239     int num_events, uint32 event_timesamp_base) {
    240   big_endian_writer_.WriteU32(rtp_timestamp);
    241   big_endian_writer_.WriteU8(static_cast<uint8>(num_events - 1));
    242   big_endian_writer_.WriteU8(static_cast<uint8>(event_timesamp_base >> 16));
    243   big_endian_writer_.WriteU8(static_cast<uint8>(event_timesamp_base >> 8));
    244   big_endian_writer_.WriteU8(static_cast<uint8>(event_timesamp_base));
    245 }
    246 
    247 void TestRtcpPacketBuilder::AddReceiverEventLog(uint16 event_data,
    248     uint8 event_id, uint16 event_timesamp_delta) {
    249   big_endian_writer_.WriteU16(event_data);
    250   uint16 type_and_delta = static_cast<uint16>(event_id) << 12;
    251   type_and_delta += event_timesamp_delta & 0x0fff;
    252   big_endian_writer_.WriteU16(type_and_delta);
    253 }
    254 
    255 const uint8* TestRtcpPacketBuilder::Packet() {
    256   PatchLengthField();
    257   return buffer_;
    258 }
    259 
    260 void TestRtcpPacketBuilder::PatchLengthField() {
    261   if (ptr_of_length_) {
    262     // Back-patch the packet length. The client must have taken
    263     // care of proper padding to 32-bit words.
    264     int this_packet_length = (big_endian_writer_.ptr() - ptr_of_length_ - 2);
    265     DCHECK_EQ(0, this_packet_length % 4)
    266         << "Packets must be a multiple of 32 bits long";
    267     *ptr_of_length_ = this_packet_length >> 10;
    268     *(ptr_of_length_ + 1) = (this_packet_length >> 2) & 0xFF;
    269     ptr_of_length_ = NULL;
    270   }
    271 }
    272 
    273 // Set the 5-bit value in the 1st byte of the header
    274 // and the payload type. Set aside room for the length field,
    275 // and make provision for back-patching it.
    276 void TestRtcpPacketBuilder::AddRtcpHeader(int payload, int format_or_count) {
    277   PatchLengthField();
    278   big_endian_writer_.WriteU8(0x80 | (format_or_count & 0x1F));
    279   big_endian_writer_.WriteU8(payload);
    280   ptr_of_length_ = big_endian_writer_.ptr();
    281 
    282   // Initialize length to "clearly illegal".
    283   big_endian_writer_.WriteU16(0xDEAD);
    284 }
    285 
    286 }  // namespace cast
    287 }  // namespace media
    288