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