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 #include "media/cast/rtcp/rtcp_utility.h" 9 10 namespace media { 11 namespace cast { 12 13 TestRtcpPacketBuilder::TestRtcpPacketBuilder() 14 : ptr_of_length_(NULL), 15 big_endian_writer_(reinterpret_cast<char*>(buffer_), kMaxIpPacketSize) {} 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(0x80 | 171 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, 193 uint32 media_ssrc, 194 uint16 target_delay_ms) { 195 AddRtcpHeader(206, 15); 196 big_endian_writer_.WriteU32(sender_ssrc); 197 big_endian_writer_.WriteU32(media_ssrc); 198 big_endian_writer_.WriteU8('C'); 199 big_endian_writer_.WriteU8('A'); 200 big_endian_writer_.WriteU8('S'); 201 big_endian_writer_.WriteU8('T'); 202 big_endian_writer_.WriteU8(kAckFrameId); 203 big_endian_writer_.WriteU8(3); // Loss fields. 204 big_endian_writer_.WriteU16(target_delay_ms); 205 big_endian_writer_.WriteU8(kLostFrameId); 206 big_endian_writer_.WriteU16(kRtcpCastAllPacketsLost); 207 big_endian_writer_.WriteU8(0); // Lost packet id mask. 208 big_endian_writer_.WriteU8(kFrameIdWithLostPackets); 209 big_endian_writer_.WriteU16(kLostPacketId1); 210 big_endian_writer_.WriteU8(0x2); // Lost packet id mask. 211 big_endian_writer_.WriteU8(kFrameIdWithLostPackets); 212 big_endian_writer_.WriteU16(kLostPacketId3); 213 big_endian_writer_.WriteU8(0); // Lost packet id mask. 214 } 215 216 void TestRtcpPacketBuilder::AddReceiverLog(uint32 sender_ssrc) { 217 AddRtcpHeader(204, 2); 218 big_endian_writer_.WriteU32(sender_ssrc); 219 big_endian_writer_.WriteU8('C'); 220 big_endian_writer_.WriteU8('A'); 221 big_endian_writer_.WriteU8('S'); 222 big_endian_writer_.WriteU8('T'); 223 } 224 225 void TestRtcpPacketBuilder::AddReceiverFrameLog(uint32 rtp_timestamp, 226 int num_events, 227 uint32 event_timesamp_base) { 228 big_endian_writer_.WriteU32(rtp_timestamp); 229 big_endian_writer_.WriteU8(static_cast<uint8>(num_events - 1)); 230 big_endian_writer_.WriteU8(static_cast<uint8>(event_timesamp_base >> 16)); 231 big_endian_writer_.WriteU8(static_cast<uint8>(event_timesamp_base >> 8)); 232 big_endian_writer_.WriteU8(static_cast<uint8>(event_timesamp_base)); 233 } 234 235 void TestRtcpPacketBuilder::AddReceiverEventLog(uint16 event_data, 236 CastLoggingEvent event, 237 uint16 event_timesamp_delta) { 238 big_endian_writer_.WriteU16(event_data); 239 uint8 event_id = ConvertEventTypeToWireFormat(event); 240 uint16 type_and_delta = static_cast<uint16>(event_id) << 12; 241 type_and_delta += event_timesamp_delta & 0x0fff; 242 big_endian_writer_.WriteU16(type_and_delta); 243 } 244 245 scoped_ptr<media::cast::Packet> TestRtcpPacketBuilder::GetPacket() { 246 PatchLengthField(); 247 return scoped_ptr<media::cast::Packet>( 248 new media::cast::Packet(buffer_, buffer_ + Length())); 249 } 250 251 const uint8* TestRtcpPacketBuilder::Data() { 252 PatchLengthField(); 253 return buffer_; 254 } 255 256 void TestRtcpPacketBuilder::PatchLengthField() { 257 if (ptr_of_length_) { 258 // Back-patch the packet length. The client must have taken 259 // care of proper padding to 32-bit words. 260 int this_packet_length = (big_endian_writer_.ptr() - ptr_of_length_ - 2); 261 DCHECK_EQ(0, this_packet_length % 4) 262 << "Packets must be a multiple of 32 bits long"; 263 *ptr_of_length_ = this_packet_length >> 10; 264 *(ptr_of_length_ + 1) = (this_packet_length >> 2) & 0xFF; 265 ptr_of_length_ = NULL; 266 } 267 } 268 269 // Set the 5-bit value in the 1st byte of the header 270 // and the payload type. Set aside room for the length field, 271 // and make provision for back-patching it. 272 void TestRtcpPacketBuilder::AddRtcpHeader(int payload, int format_or_count) { 273 PatchLengthField(); 274 big_endian_writer_.WriteU8(0x80 | (format_or_count & 0x1F)); 275 big_endian_writer_.WriteU8(payload); 276 ptr_of_length_ = big_endian_writer_.ptr(); 277 278 // Initialize length to "clearly illegal". 279 big_endian_writer_.WriteU16(0xDEAD); 280 } 281 282 } // namespace cast 283 } // namespace media 284