blob: f88ef76722d26834674ed34b4696344c38045576 [file] [log] [blame]
[email protected]5ddaa0a2010-11-17 23:05:151// Copyright (c) 2010 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 <vector>
6
7#include "base/message_loop.h"
8#include "base/string_number_conversions.h"
9#include "net/base/io_buffer.h"
10#include "remoting/proto/video.pb.h"
11#include "remoting/protocol/fake_session.h"
12#include "remoting/protocol/rtp_utils.h"
13#include "remoting/protocol/rtp_video_reader.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
16using net::IOBuffer;
17using std::vector;
18
19namespace remoting {
20namespace protocol {
21
22class RtpVideoReaderTest : public testing::Test,
23 public VideoStub {
24 public:
[email protected]c56acf54ff2010-11-19 23:44:4525 // VideoStub interface.
[email protected]5ddaa0a2010-11-17 23:05:1526 virtual void ProcessVideoPacket(const VideoPacket* video_packet,
27 Task* done) {
28 received_packets_.push_back(VideoPacket());
29 received_packets_.back() = *video_packet;
30 done->Run();
31 delete done;
32 }
33
[email protected]c56acf54ff2010-11-19 23:44:4534 virtual int GetPendingPackets() {
35 return 0;
36 }
37
[email protected]5ddaa0a2010-11-17 23:05:1538 protected:
39 struct FragmentInfo {
40 int sequence_number;
41 int timestamp;
42 bool first;
43 bool last;
44 Vp8Descriptor::FragmentationInfo fragmentation_info;
45 int start;
46 int end;
47 };
48
49 struct ExpectedPacket {
50 int timestamp;
51 int flags;
52 int start;
53 int end;
54 };
55
56 virtual void SetUp() {
57 Reset();
58 InitData(100);
59 }
60
[email protected]c64315f82010-12-10 19:27:4461 virtual void TearDown() {
62 message_loop_.RunAllPending();
63 }
64
[email protected]5ddaa0a2010-11-17 23:05:1565 void Reset() {
66 session_ = new FakeSession();
67 reader_.reset(new RtpVideoReader());
68 reader_->Init(session_, this);
69 received_packets_.clear();
70 }
71
72 void InitData(int size) {
73 data_.resize(size);
74 for (int i = 0; i < size; ++i) {
75 data_[i] = static_cast<char>(i);
76 }
77 }
78
79 bool CompareData(const CompoundBuffer& buffer, char* data, int size) {
80 scoped_refptr<IOBuffer> buffer_data = buffer.ToIOBufferWithSize();
81 return buffer.total_bytes() == size &&
82 memcmp(buffer_data->data(), data, size) == 0;
83 }
84
85 void SplitAndSend(const FragmentInfo fragments[], int count) {
86 for (int i = 0; i < count; ++i) {
[email protected]8e886052010-11-24 04:20:4887 RtpHeader header;
88 header.sequence_number = fragments[i].sequence_number;
89 header.marker = fragments[i].last;
90 header.timestamp = fragments[i].timestamp;
[email protected]5ddaa0a2010-11-17 23:05:1591
[email protected]8e886052010-11-24 04:20:4892 Vp8Descriptor descriptor;
93 descriptor.non_reference_frame = true;
94 descriptor.frame_beginning = fragments[i].first;
95 descriptor.fragmentation_info = fragments[i].fragmentation_info;
[email protected]5ddaa0a2010-11-17 23:05:1596
[email protected]8e886052010-11-24 04:20:4897 int header_size = GetRtpHeaderSize(header);
98 int vp8_desc_size = GetVp8DescriptorSize(descriptor);
99 int payload_size = fragments[i].end - fragments[i].start;
100 int size = header_size + vp8_desc_size + payload_size;
101 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(size);
102
103 PackRtpHeader(header, reinterpret_cast<uint8*>(buffer->data()),
104 header_size);
105 PackVp8Descriptor(descriptor, reinterpret_cast<uint8*>(buffer->data()) +
106 header_size, vp8_desc_size);
107
108 memcpy(buffer->data() + header_size + vp8_desc_size,
109 &*data_.begin() + fragments[i].start, payload_size);
110
111 reader_->rtp_reader_.OnDataReceived(buffer, size);
[email protected]5ddaa0a2010-11-17 23:05:15112 }
113 }
114
115 void CheckResults(const ExpectedPacket expected[], int count) {
116 ASSERT_EQ(count, static_cast<int>(received_packets_.size()));
117 for (int i = 0; i < count; ++i) {
118 SCOPED_TRACE("Packet " + base::IntToString(i));
119
120 int expected_size = expected[i].end - expected[i].start;
121 EXPECT_EQ(expected_size,
122 static_cast<int>(received_packets_[i].data().size()));
123 EXPECT_EQ(0, memcmp(&*received_packets_[i].data().data(),
124 &*data_.begin() + expected[i].start, expected_size));
125 EXPECT_EQ(expected[i].flags, received_packets_[i].flags());
126 EXPECT_EQ(expected[i].timestamp, received_packets_[i].timestamp());
127 }
128 }
129
130 scoped_refptr<FakeSession> session_;
131 scoped_ptr<RtpVideoReader> reader_;
132
133 MessageLoop message_loop_;
134 vector<char> data_;
135 vector<VideoPacket> received_packets_;
136};
137
138// One non-fragmented packet marked as first.
139TEST_F(RtpVideoReaderTest, NotFragmented_FirstPacket) {
140 FragmentInfo fragments[] = {
141 { 300, 123, true, false, Vp8Descriptor::NOT_FRAGMENTED, 0, 100 },
142 };
143 SplitAndSend(fragments, arraysize(fragments));
144
145 ExpectedPacket expected[] = {
146 { 123, VideoPacket::FIRST_PACKET, 0, 100 },
147 };
148 CheckResults(expected, arraysize(expected));
149}
150
151// One non-fragmented packet marked as last.
152TEST_F(RtpVideoReaderTest, NotFragmented_LastPacket) {
153 FragmentInfo fragments[] = {
154 { 3000, 123, false, true, Vp8Descriptor::NOT_FRAGMENTED, 0, 100 },
155 };
156 SplitAndSend(fragments, arraysize(fragments));
157
158 ExpectedPacket expected[] = {
159 { 123, VideoPacket::LAST_PACKET, 0, 100 },
160 };
161 CheckResults(expected, arraysize(expected));
162}
163
164// Duplicated non-fragmented packet. Must be processed only once.
165TEST_F(RtpVideoReaderTest, NotFragmented_Duplicate) {
166 FragmentInfo fragments[] = {
167 { 300, 123, true, false, Vp8Descriptor::NOT_FRAGMENTED, 0, 100 },
168 { 300, 123, true, false, Vp8Descriptor::NOT_FRAGMENTED, 0, 100 },
169 };
170 SplitAndSend(fragments, arraysize(fragments));
171
172 ExpectedPacket expected[] = {
173 { 123, VideoPacket::FIRST_PACKET, 0, 100 },
174 };
175 CheckResults(expected, arraysize(expected));
176}
177
178// First packet split into two fragments.
179TEST_F(RtpVideoReaderTest, TwoFragments_FirstPacket) {
180 FragmentInfo fragments[] = {
181 { 300, 321, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 50 },
182 { 301, 321, false, false, Vp8Descriptor::LAST_FRAGMENT, 50, 100 },
183 };
184 SplitAndSend(fragments, arraysize(fragments));
185
186 ExpectedPacket expected[] = {
187 { 321, VideoPacket::FIRST_PACKET, 0, 100 },
188 };
189 CheckResults(expected, arraysize(expected));
190}
191
192// Last packet split into two fragments.
193TEST_F(RtpVideoReaderTest, TwoFragments_LastPacket) {
194 FragmentInfo fragments[] = {
195 { 3000, 400, false, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 50 },
196 { 3001, 400, false, true, Vp8Descriptor::LAST_FRAGMENT, 50, 100 },
197 };
198 SplitAndSend(fragments, arraysize(fragments));
199
200 ExpectedPacket expected[] = {
201 { 400, VideoPacket::LAST_PACKET, 0, 100 },
202 };
203 CheckResults(expected, arraysize(expected));
204}
205
206// Duplicated second fragment.
207TEST_F(RtpVideoReaderTest, TwoFragments_WithDuplicate) {
208 FragmentInfo fragments[] = {
209 { 3000, 400, false, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 50 },
210 { 3001, 400, false, true, Vp8Descriptor::LAST_FRAGMENT, 50, 100 },
211 { 3001, 400, false, true, Vp8Descriptor::LAST_FRAGMENT, 50, 100 },
212 };
213 SplitAndSend(fragments, arraysize(fragments));
214
215 ExpectedPacket expected[] = {
216 { 400, VideoPacket::LAST_PACKET, 0, 100 },
217 };
218 CheckResults(expected, arraysize(expected));
219}
220
221// Packet split into three fragments.
222TEST_F(RtpVideoReaderTest, ThreeFragments_Ordered) {
223 FragmentInfo fragments[] = {
224 { 300, 400, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 50 },
225 { 301, 400, false, false, Vp8Descriptor::MIDDLE_FRAGMENT, 50, 90 },
226 { 302, 400, false, false, Vp8Descriptor::LAST_FRAGMENT, 90, 100 },
227 };
228 SplitAndSend(fragments, arraysize(fragments));
229
230 ExpectedPacket expected[] = {
231 { 400, VideoPacket::FIRST_PACKET, 0, 100 },
232 };
233 CheckResults(expected, arraysize(expected));
234}
235
236// Packet split into three fragments received in reverse order.
237TEST_F(RtpVideoReaderTest, ThreeFragments_ReverseOrder) {
238 FragmentInfo fragments[] = {
239 { 302, 400, false, false, Vp8Descriptor::LAST_FRAGMENT, 90, 100 },
240 { 301, 400, false, false, Vp8Descriptor::MIDDLE_FRAGMENT, 50, 90 },
241 { 300, 400, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 50 },
242 };
243 SplitAndSend(fragments, arraysize(fragments));
244
245 ExpectedPacket expected[] = {
246 { 400, VideoPacket::FIRST_PACKET, 0, 100 },
247 };
248 CheckResults(expected, arraysize(expected));
249}
250
251// Two fragmented packets.
252TEST_F(RtpVideoReaderTest, TwoPackets) {
253 FragmentInfo fragments[] = {
254 { 300, 100, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 10 },
255 { 301, 100, false, false, Vp8Descriptor::MIDDLE_FRAGMENT, 10, 20 },
256 { 302, 100, false, false, Vp8Descriptor::LAST_FRAGMENT, 20, 40 },
257
258 { 303, 200, false, false, Vp8Descriptor::FIRST_FRAGMENT, 40, 70 },
259 { 304, 200, false, true, Vp8Descriptor::LAST_FRAGMENT, 70, 100 },
260 };
261 SplitAndSend(fragments, arraysize(fragments));
262
263 ExpectedPacket expected[] = {
264 { 100, VideoPacket::FIRST_PACKET, 0, 40 },
265 { 200, VideoPacket::LAST_PACKET, 40, 100 },
266 };
267 CheckResults(expected, arraysize(expected));
268}
269
270// Sequence of three packets, with one lost fragment lost in the second packet.
271TEST_F(RtpVideoReaderTest, LostFragment) {
272 FragmentInfo fragments[] = {
273 { 300, 100, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 10 },
274 { 301, 100, false, false, Vp8Descriptor::MIDDLE_FRAGMENT, 10, 20 },
275 { 302, 100, false, false, Vp8Descriptor::LAST_FRAGMENT, 20, 30 },
276
277 // Lost: { 303, 200, false, false, Vp8Descriptor::FIRST_FRAGMENT, 40, 50 },
278 { 304, 200, false, true, Vp8Descriptor::LAST_FRAGMENT, 30, 40 },
279
280 { 305, 300, true, false, Vp8Descriptor::FIRST_FRAGMENT, 50, 70 },
281 { 306, 300, false, true, Vp8Descriptor::LAST_FRAGMENT, 70, 100 },
282 };
283 SplitAndSend(fragments, arraysize(fragments));
284
285 ExpectedPacket expected[] = {
286 { 100, VideoPacket::FIRST_PACKET, 0, 30 },
287 { 300, VideoPacket::FIRST_PACKET | VideoPacket::LAST_PACKET, 50, 100 },
288 };
289 CheckResults(expected, arraysize(expected));
290}
291
292// Sequence of four packets, with two lost fragments.
293TEST_F(RtpVideoReaderTest, TwoLostFragments) {
294 // Fragments 303 and 306 should not be combined because they belong to
295 // different Vp8 partitions.
296 FragmentInfo fragments[] = {
297 { 300, 100, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 10 },
298 { 301, 100, false, false, Vp8Descriptor::MIDDLE_FRAGMENT, 10, 20 },
299 { 302, 100, false, false, Vp8Descriptor::LAST_FRAGMENT, 20, 30 },
300
301 { 303, 200, false, false, Vp8Descriptor::FIRST_FRAGMENT, 40, 50 },
302 // Lost: { 304, 200, false, true, Vp8Descriptor::LAST_FRAGMENT, 30, 40 },
303
304 // Lost: { 305, 300, true, false, Vp8Descriptor::FIRST_FRAGMENT, 50, 60 },
305 { 306, 300, false, true, Vp8Descriptor::LAST_FRAGMENT, 60, 70 },
306
307 { 307, 400, true, false, Vp8Descriptor::FIRST_FRAGMENT, 70, 80 },
308 { 308, 400, false, true, Vp8Descriptor::LAST_FRAGMENT, 80, 100 },
309 };
310 SplitAndSend(fragments, arraysize(fragments));
311
312 ExpectedPacket expected[] = {
313 { 100, VideoPacket::FIRST_PACKET, 0, 30 },
314 { 400, VideoPacket::FIRST_PACKET | VideoPacket::LAST_PACKET, 70, 100 },
315 };
316 CheckResults(expected, arraysize(expected));
317}
318
319// Sequence number wrapping.
320TEST_F(RtpVideoReaderTest, SequenceNumberWrapping) {
321 FragmentInfo fragments[] = {
322 { 65534, 400, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 50 },
323 { 65535, 400, false, false, Vp8Descriptor::MIDDLE_FRAGMENT, 50, 90 },
324 { 0, 400, false, false, Vp8Descriptor::LAST_FRAGMENT, 90, 100 },
325 };
326 SplitAndSend(fragments, arraysize(fragments));
327
328 ExpectedPacket expected[] = {
329 { 400, VideoPacket::FIRST_PACKET, 0, 100 },
330 };
331 CheckResults(expected, arraysize(expected));
332}
333
334// Sequence number wrapping for fragments received out of order.
335TEST_F(RtpVideoReaderTest, SequenceNumberWrappingReordered) {
336 FragmentInfo fragments[] = {
337 { 0, 400, false, false, Vp8Descriptor::LAST_FRAGMENT, 90, 100 },
338 { 65534, 400, true, false, Vp8Descriptor::FIRST_FRAGMENT, 0, 50 },
339 { 65535, 400, false, false, Vp8Descriptor::MIDDLE_FRAGMENT, 50, 90 },
340 };
341 SplitAndSend(fragments, arraysize(fragments));
342
343 ExpectedPacket expected[] = {
344 { 400, VideoPacket::FIRST_PACKET, 0, 100 },
345 };
346 CheckResults(expected, arraysize(expected));
347}
348
349// An old packet with invalid sequence number.
350TEST_F(RtpVideoReaderTest, OldPacket) {
351 FragmentInfo fragments[] = {
352 { 32000, 123, true, true, Vp8Descriptor::NOT_FRAGMENTED, 0, 30 },
353
354 // Should be ignored.
355 { 10000, 532, true, true, Vp8Descriptor::NOT_FRAGMENTED, 30, 40 },
356
357 { 32001, 223, true, true, Vp8Descriptor::NOT_FRAGMENTED, 40, 50 },
358 };
359 SplitAndSend(fragments, arraysize(fragments));
360
361 ExpectedPacket expected[] = {
362 { 123, VideoPacket::FIRST_PACKET | VideoPacket::LAST_PACKET, 0, 30 },
363 { 223, VideoPacket::FIRST_PACKET | VideoPacket::LAST_PACKET, 40, 50 },
364 };
365 CheckResults(expected, arraysize(expected));
366}
367
368} // namespace protocol
369} // namespace remoting