Upstream version 7.36.149.0
[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 #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::AddSenderLog(uint32 sender_ssrc) {
217   AddRtcpHeader(204, 1);
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::AddSenderFrameLog(uint8 event_id,
226                                               uint32 rtp_timestamp) {
227   big_endian_writer_.WriteU32((static_cast<uint32>(event_id) << 24) +
228                               (rtp_timestamp & 0xffffff));
229 }
230
231 void TestRtcpPacketBuilder::AddReceiverLog(uint32 sender_ssrc) {
232   AddRtcpHeader(204, 2);
233   big_endian_writer_.WriteU32(sender_ssrc);
234   big_endian_writer_.WriteU8('C');
235   big_endian_writer_.WriteU8('A');
236   big_endian_writer_.WriteU8('S');
237   big_endian_writer_.WriteU8('T');
238 }
239
240 void TestRtcpPacketBuilder::AddReceiverFrameLog(uint32 rtp_timestamp,
241                                                 int num_events,
242                                                 uint32 event_timesamp_base) {
243   big_endian_writer_.WriteU32(rtp_timestamp);
244   big_endian_writer_.WriteU8(static_cast<uint8>(num_events - 1));
245   big_endian_writer_.WriteU8(static_cast<uint8>(event_timesamp_base >> 16));
246   big_endian_writer_.WriteU8(static_cast<uint8>(event_timesamp_base >> 8));
247   big_endian_writer_.WriteU8(static_cast<uint8>(event_timesamp_base));
248 }
249
250 void TestRtcpPacketBuilder::AddReceiverEventLog(uint16 event_data,
251                                                 CastLoggingEvent event,
252                                                 uint16 event_timesamp_delta) {
253   big_endian_writer_.WriteU16(event_data);
254   uint8 event_id = ConvertEventTypeToWireFormat(event);
255   uint16 type_and_delta = static_cast<uint16>(event_id) << 12;
256   type_and_delta += event_timesamp_delta & 0x0fff;
257   big_endian_writer_.WriteU16(type_and_delta);
258 }
259
260 scoped_ptr<media::cast::Packet> TestRtcpPacketBuilder::GetPacket() {
261   PatchLengthField();
262   return scoped_ptr<media::cast::Packet>(
263       new media::cast::Packet(buffer_, buffer_ + Length()));
264 }
265
266 const uint8* TestRtcpPacketBuilder::Data() {
267   PatchLengthField();
268   return buffer_;
269 }
270
271 void TestRtcpPacketBuilder::PatchLengthField() {
272   if (ptr_of_length_) {
273     // Back-patch the packet length. The client must have taken
274     // care of proper padding to 32-bit words.
275     int this_packet_length = (big_endian_writer_.ptr() - ptr_of_length_ - 2);
276     DCHECK_EQ(0, this_packet_length % 4)
277         << "Packets must be a multiple of 32 bits long";
278     *ptr_of_length_ = this_packet_length >> 10;
279     *(ptr_of_length_ + 1) = (this_packet_length >> 2) & 0xFF;
280     ptr_of_length_ = NULL;
281   }
282 }
283
284 // Set the 5-bit value in the 1st byte of the header
285 // and the payload type. Set aside room for the length field,
286 // and make provision for back-patching it.
287 void TestRtcpPacketBuilder::AddRtcpHeader(int payload, int format_or_count) {
288   PatchLengthField();
289   big_endian_writer_.WriteU8(0x80 | (format_or_count & 0x1F));
290   big_endian_writer_.WriteU8(payload);
291   ptr_of_length_ = big_endian_writer_.ptr();
292
293   // Initialize length to "clearly illegal".
294   big_endian_writer_.WriteU16(0xDEAD);
295 }
296
297 }  // namespace cast
298 }  // namespace media