| OLD | NEW |
| (Empty) |
| 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 const int padding = 4 - ((c_name.size() + 2) % 4); | |
| 69 for (int j = 0; j < padding; ++j) { | |
| 70 big_endian_writer_.WriteU8(0); | |
| 71 } | |
| 72 } | |
| 73 | |
| 74 void TestRtcpPacketBuilder::AddXrHeader(uint32 sender_ssrc) { | |
| 75 AddRtcpHeader(207, 0); | |
| 76 big_endian_writer_.WriteU32(sender_ssrc); | |
| 77 } | |
| 78 | |
| 79 void TestRtcpPacketBuilder::AddXrUnknownBlock() { | |
| 80 big_endian_writer_.WriteU8(9); // Block type. | |
| 81 big_endian_writer_.WriteU8(0); // Reserved. | |
| 82 big_endian_writer_.WriteU16(4); // Block length. | |
| 83 // First receiver same as sender of this report. | |
| 84 big_endian_writer_.WriteU32(0); | |
| 85 big_endian_writer_.WriteU32(0); | |
| 86 big_endian_writer_.WriteU32(0); | |
| 87 big_endian_writer_.WriteU32(0); | |
| 88 } | |
| 89 | |
| 90 void TestRtcpPacketBuilder::AddXrDlrrBlock(uint32 sender_ssrc) { | |
| 91 big_endian_writer_.WriteU8(5); // Block type. | |
| 92 big_endian_writer_.WriteU8(0); // Reserved. | |
| 93 big_endian_writer_.WriteU16(3); // Block length. | |
| 94 | |
| 95 // First receiver same as sender of this report. | |
| 96 big_endian_writer_.WriteU32(sender_ssrc); | |
| 97 big_endian_writer_.WriteU32(kLastRr); | |
| 98 big_endian_writer_.WriteU32(kDelayLastRr); | |
| 99 } | |
| 100 | |
| 101 void TestRtcpPacketBuilder::AddXrExtendedDlrrBlock(uint32 sender_ssrc) { | |
| 102 big_endian_writer_.WriteU8(5); // Block type. | |
| 103 big_endian_writer_.WriteU8(0); // Reserved. | |
| 104 big_endian_writer_.WriteU16(9); // Block length. | |
| 105 big_endian_writer_.WriteU32(0xaaaaaaaa); | |
| 106 big_endian_writer_.WriteU32(0xaaaaaaaa); | |
| 107 big_endian_writer_.WriteU32(0xaaaaaaaa); | |
| 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 big_endian_writer_.WriteU32(0xbbbbbbbb); | |
| 114 big_endian_writer_.WriteU32(0xbbbbbbbb); | |
| 115 big_endian_writer_.WriteU32(0xbbbbbbbb); | |
| 116 } | |
| 117 | |
| 118 void TestRtcpPacketBuilder::AddXrRrtrBlock() { | |
| 119 big_endian_writer_.WriteU8(4); // Block type. | |
| 120 big_endian_writer_.WriteU8(0); // Reserved. | |
| 121 big_endian_writer_.WriteU16(2); // Block length. | |
| 122 big_endian_writer_.WriteU32(kNtpHigh); | |
| 123 big_endian_writer_.WriteU32(kNtpLow); | |
| 124 } | |
| 125 | |
| 126 void TestRtcpPacketBuilder::AddNack(uint32 sender_ssrc, uint32 media_ssrc) { | |
| 127 AddRtcpHeader(205, 1); | |
| 128 big_endian_writer_.WriteU32(sender_ssrc); | |
| 129 big_endian_writer_.WriteU32(media_ssrc); | |
| 130 big_endian_writer_.WriteU16(kMissingPacket); | |
| 131 big_endian_writer_.WriteU16(0); | |
| 132 } | |
| 133 | |
| 134 void TestRtcpPacketBuilder::AddSendReportRequest(uint32 sender_ssrc, | |
| 135 uint32 media_ssrc) { | |
| 136 AddRtcpHeader(205, 5); | |
| 137 big_endian_writer_.WriteU32(sender_ssrc); | |
| 138 big_endian_writer_.WriteU32(media_ssrc); | |
| 139 } | |
| 140 | |
| 141 void TestRtcpPacketBuilder::AddPli(uint32 sender_ssrc, uint32 media_ssrc) { | |
| 142 AddRtcpHeader(206, 1); | |
| 143 big_endian_writer_.WriteU32(sender_ssrc); | |
| 144 big_endian_writer_.WriteU32(media_ssrc); | |
| 145 } | |
| 146 | |
| 147 void TestRtcpPacketBuilder::AddRpsi(uint32 sender_ssrc, uint32 media_ssrc) { | |
| 148 AddRtcpHeader(206, 3); | |
| 149 big_endian_writer_.WriteU32(sender_ssrc); | |
| 150 big_endian_writer_.WriteU32(media_ssrc); | |
| 151 big_endian_writer_.WriteU8(0); // Padding bits. | |
| 152 big_endian_writer_.WriteU8(kPayloadtype); | |
| 153 uint64 picture_id = kPictureId; | |
| 154 | |
| 155 for (int i = 9; i > 0; i--) { | |
| 156 big_endian_writer_.WriteU8(0x80 | | |
| 157 static_cast<uint8>(picture_id >> (i * 7))); | |
| 158 } | |
| 159 // Add last byte of picture ID. | |
| 160 big_endian_writer_.WriteU8(static_cast<uint8>(picture_id & 0x7f)); | |
| 161 } | |
| 162 | |
| 163 void TestRtcpPacketBuilder::AddRemb(uint32 sender_ssrc, uint32 media_ssrc) { | |
| 164 AddRtcpHeader(206, 15); | |
| 165 big_endian_writer_.WriteU32(sender_ssrc); | |
| 166 big_endian_writer_.WriteU32(0); | |
| 167 big_endian_writer_.WriteU8('R'); | |
| 168 big_endian_writer_.WriteU8('E'); | |
| 169 big_endian_writer_.WriteU8('M'); | |
| 170 big_endian_writer_.WriteU8('B'); | |
| 171 big_endian_writer_.WriteU8(1); // Number of SSRCs. | |
| 172 big_endian_writer_.WriteU8(1); // BR Exp. | |
| 173 // BR Mantissa. | |
| 174 big_endian_writer_.WriteU16(static_cast<uint16>(kTestRembBitrate / 2)); | |
| 175 big_endian_writer_.WriteU32(media_ssrc); | |
| 176 } | |
| 177 | |
| 178 void TestRtcpPacketBuilder::AddCast(uint32 sender_ssrc, | |
| 179 uint32 media_ssrc, | |
| 180 base::TimeDelta target_delay) { | |
| 181 AddRtcpHeader(206, 15); | |
| 182 big_endian_writer_.WriteU32(sender_ssrc); | |
| 183 big_endian_writer_.WriteU32(media_ssrc); | |
| 184 big_endian_writer_.WriteU8('C'); | |
| 185 big_endian_writer_.WriteU8('A'); | |
| 186 big_endian_writer_.WriteU8('S'); | |
| 187 big_endian_writer_.WriteU8('T'); | |
| 188 big_endian_writer_.WriteU8(kAckFrameId); | |
| 189 big_endian_writer_.WriteU8(3); // Loss fields. | |
| 190 big_endian_writer_.WriteU16(target_delay.InMilliseconds()); | |
| 191 big_endian_writer_.WriteU8(kLostFrameId); | |
| 192 big_endian_writer_.WriteU16(kRtcpCastAllPacketsLost); | |
| 193 big_endian_writer_.WriteU8(0); // Lost packet id mask. | |
| 194 big_endian_writer_.WriteU8(kFrameIdWithLostPackets); | |
| 195 big_endian_writer_.WriteU16(kLostPacketId1); | |
| 196 big_endian_writer_.WriteU8(0x2); // Lost packet id mask. | |
| 197 big_endian_writer_.WriteU8(kFrameIdWithLostPackets); | |
| 198 big_endian_writer_.WriteU16(kLostPacketId3); | |
| 199 big_endian_writer_.WriteU8(0); // Lost packet id mask. | |
| 200 } | |
| 201 | |
| 202 void TestRtcpPacketBuilder::AddReceiverLog(uint32 sender_ssrc) { | |
| 203 AddRtcpHeader(204, 2); | |
| 204 big_endian_writer_.WriteU32(sender_ssrc); | |
| 205 big_endian_writer_.WriteU8('C'); | |
| 206 big_endian_writer_.WriteU8('A'); | |
| 207 big_endian_writer_.WriteU8('S'); | |
| 208 big_endian_writer_.WriteU8('T'); | |
| 209 } | |
| 210 | |
| 211 void TestRtcpPacketBuilder::AddReceiverFrameLog(uint32 rtp_timestamp, | |
| 212 int num_events, | |
| 213 uint32 event_timesamp_base) { | |
| 214 big_endian_writer_.WriteU32(rtp_timestamp); | |
| 215 big_endian_writer_.WriteU8(static_cast<uint8>(num_events - 1)); | |
| 216 big_endian_writer_.WriteU8(static_cast<uint8>(event_timesamp_base >> 16)); | |
| 217 big_endian_writer_.WriteU8(static_cast<uint8>(event_timesamp_base >> 8)); | |
| 218 big_endian_writer_.WriteU8(static_cast<uint8>(event_timesamp_base)); | |
| 219 } | |
| 220 | |
| 221 void TestRtcpPacketBuilder::AddReceiverEventLog(uint16 event_data, | |
| 222 CastLoggingEvent event, | |
| 223 uint16 event_timesamp_delta) { | |
| 224 big_endian_writer_.WriteU16(event_data); | |
| 225 uint8 event_id = ConvertEventTypeToWireFormat(event); | |
| 226 uint16 type_and_delta = static_cast<uint16>(event_id) << 12; | |
| 227 type_and_delta += event_timesamp_delta & 0x0fff; | |
| 228 big_endian_writer_.WriteU16(type_and_delta); | |
| 229 } | |
| 230 | |
| 231 scoped_ptr<media::cast::Packet> TestRtcpPacketBuilder::GetPacket() { | |
| 232 PatchLengthField(); | |
| 233 return scoped_ptr<media::cast::Packet>( | |
| 234 new media::cast::Packet(buffer_, buffer_ + Length())); | |
| 235 } | |
| 236 | |
| 237 const uint8* TestRtcpPacketBuilder::Data() { | |
| 238 PatchLengthField(); | |
| 239 return buffer_; | |
| 240 } | |
| 241 | |
| 242 void TestRtcpPacketBuilder::PatchLengthField() { | |
| 243 if (ptr_of_length_) { | |
| 244 // Back-patch the packet length. The client must have taken | |
| 245 // care of proper padding to 32-bit words. | |
| 246 int this_packet_length = (big_endian_writer_.ptr() - ptr_of_length_ - 2); | |
| 247 DCHECK_EQ(0, this_packet_length % 4) | |
| 248 << "Packets must be a multiple of 32 bits long"; | |
| 249 *ptr_of_length_ = this_packet_length >> 10; | |
| 250 *(ptr_of_length_ + 1) = (this_packet_length >> 2) & 0xFF; | |
| 251 ptr_of_length_ = NULL; | |
| 252 } | |
| 253 } | |
| 254 | |
| 255 // Set the 5-bit value in the 1st byte of the header | |
| 256 // and the payload type. Set aside room for the length field, | |
| 257 // and make provision for back-patching it. | |
| 258 void TestRtcpPacketBuilder::AddRtcpHeader(int payload, int format_or_count) { | |
| 259 PatchLengthField(); | |
| 260 big_endian_writer_.WriteU8(0x80 | (format_or_count & 0x1F)); | |
| 261 big_endian_writer_.WriteU8(payload); | |
| 262 ptr_of_length_ = big_endian_writer_.ptr(); | |
| 263 | |
| 264 // Initialize length to "clearly illegal". | |
| 265 big_endian_writer_.WriteU16(0xDEAD); | |
| 266 } | |
| 267 | |
| 268 } // namespace cast | |
| 269 } // namespace media | |
| OLD | NEW |