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