- add sources.
[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
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(kJitter);
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>(kRembBitrate / 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 const uint8* TestRtcpPacketBuilder::Packet() {
215   PatchLengthField();
216   return buffer_;
217 }
218
219 void TestRtcpPacketBuilder::PatchLengthField() {
220   if (ptr_of_length_) {
221     // Back-patch the packet length. The client must have taken
222     // care of proper padding to 32-bit words.
223     int this_packet_length = (big_endian_writer_.ptr() - ptr_of_length_ - 2);
224     DCHECK_EQ(0, this_packet_length % 4)
225         << "Packets must be a multiple of 32 bits long";
226     *ptr_of_length_ = this_packet_length >> 10;
227     *(ptr_of_length_ + 1) = (this_packet_length >> 2) & 0xFF;
228     ptr_of_length_ = NULL;
229   }
230 }
231
232 // Set the 5-bit value in the 1st byte of the header
233 // and the payload type. Set aside room for the length field,
234 // and make provision for back-patching it.
235 void TestRtcpPacketBuilder::AddRtcpHeader(int payload, int format_or_count) {
236   PatchLengthField();
237   big_endian_writer_.WriteU8(0x80 | (format_or_count & 0x1F));
238   big_endian_writer_.WriteU8(payload);
239   ptr_of_length_ = big_endian_writer_.ptr();
240
241   // Initialize length to "clearly illegal".
242   big_endian_writer_.WriteU16(0xDEAD);
243 }
244
245 }  // namespace cast
246 }  // namespace media