- add sources.
[platform/framework/web/crosswalk.git] / src / media / base / seekable_buffer_unittest.cc
1 // Copyright (c) 2012 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 "base/logging.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/time/time.h"
8 #include "media/base/data_buffer.h"
9 #include "media/base/seekable_buffer.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace media {
13
14 class SeekableBufferTest : public testing::Test {
15  public:
16   SeekableBufferTest() : buffer_(kBufferSize, kBufferSize) {
17   }
18
19  protected:
20   static const int kDataSize = 409600;
21   static const int kBufferSize = 4096;
22   static const int kWriteSize = 512;
23
24   virtual void SetUp() {
25     // Setup seed.
26     int seed = static_cast<int32>(base::Time::Now().ToInternalValue());
27     srand(seed);
28     VLOG(1) << "Random seed: " << seed;
29
30     // Creates a test data.
31     for (int i = 0; i < kDataSize; i++)
32       data_[i] = static_cast<char>(rand());
33   }
34
35   int GetRandomInt(int maximum) {
36     return rand() % maximum + 1;
37   }
38
39   SeekableBuffer buffer_;
40   uint8 data_[kDataSize];
41   uint8 write_buffer_[kDataSize];
42 };
43
44 TEST_F(SeekableBufferTest, RandomReadWrite) {
45   int write_position = 0;
46   int read_position = 0;
47   while (read_position < kDataSize) {
48     // Write a random amount of data.
49     int write_size = GetRandomInt(kBufferSize);
50     write_size = std::min(write_size, kDataSize - write_position);
51     bool should_append = buffer_.Append(data_ + write_position, write_size);
52     write_position += write_size;
53     EXPECT_GE(write_position, read_position);
54     EXPECT_EQ(write_position - read_position, buffer_.forward_bytes());
55     EXPECT_EQ(should_append, buffer_.forward_bytes() < kBufferSize)
56         << "Incorrect buffer full reported";
57
58     // Peek a random amount of data.
59     int copy_size = GetRandomInt(kBufferSize);
60     int bytes_copied = buffer_.Peek(write_buffer_, copy_size);
61     EXPECT_GE(copy_size, bytes_copied);
62     EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, bytes_copied));
63
64     // Read a random amount of data.
65     int read_size = GetRandomInt(kBufferSize);
66     int bytes_read = buffer_.Read(write_buffer_, read_size);
67     EXPECT_GE(read_size, bytes_read);
68     EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, bytes_read));
69     read_position += bytes_read;
70     EXPECT_GE(write_position, read_position);
71     EXPECT_EQ(write_position - read_position, buffer_.forward_bytes());
72   }
73 }
74
75 TEST_F(SeekableBufferTest, ReadWriteSeek) {
76   const int kReadSize = kWriteSize / 4;
77
78   for (int i = 0; i < 10; ++i) {
79     // Write until buffer is full.
80     for (int j = 0; j < kBufferSize; j += kWriteSize) {
81       bool should_append = buffer_.Append(data_ + j, kWriteSize);
82       EXPECT_EQ(j < kBufferSize - kWriteSize, should_append)
83           << "Incorrect buffer full reported";
84       EXPECT_EQ(j + kWriteSize, buffer_.forward_bytes());
85     }
86
87     // Simulate a read and seek pattern. Each loop reads 4 times, each time
88     // reading a quarter of |kWriteSize|.
89     int read_position = 0;
90     int forward_bytes = kBufferSize;
91     for (int j = 0; j < kBufferSize; j += kWriteSize) {
92       // Read.
93       EXPECT_EQ(kReadSize, buffer_.Read(write_buffer_, kReadSize));
94       forward_bytes -= kReadSize;
95       EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
96       EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, kReadSize));
97       read_position += kReadSize;
98
99       // Seek forward.
100       EXPECT_TRUE(buffer_.Seek(2 * kReadSize));
101       forward_bytes -= 2 * kReadSize;
102       read_position += 2 * kReadSize;
103       EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
104
105       // Copy.
106       EXPECT_EQ(kReadSize, buffer_.Peek(write_buffer_, kReadSize));
107       EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
108       EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, kReadSize));
109
110       // Read.
111       EXPECT_EQ(kReadSize, buffer_.Read(write_buffer_, kReadSize));
112       forward_bytes -= kReadSize;
113       EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
114       EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, kReadSize));
115       read_position += kReadSize;
116
117       // Seek backward.
118       EXPECT_TRUE(buffer_.Seek(-3 * static_cast<int32>(kReadSize)));
119       forward_bytes += 3 * kReadSize;
120       read_position -= 3 * kReadSize;
121       EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
122
123       // Copy.
124       EXPECT_EQ(kReadSize, buffer_.Peek(write_buffer_, kReadSize));
125       EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
126       EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, kReadSize));
127
128       // Read.
129       EXPECT_EQ(kReadSize, buffer_.Read(write_buffer_, kReadSize));
130       forward_bytes -= kReadSize;
131       EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
132       EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, kReadSize));
133       read_position += kReadSize;
134
135       // Copy.
136       EXPECT_EQ(kReadSize, buffer_.Peek(write_buffer_, kReadSize));
137       EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
138       EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, kReadSize));
139
140       // Read.
141       EXPECT_EQ(kReadSize, buffer_.Read(write_buffer_, kReadSize));
142       forward_bytes -= kReadSize;
143       EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
144       EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, kReadSize));
145       read_position += kReadSize;
146
147       // Seek forward.
148       EXPECT_TRUE(buffer_.Seek(kReadSize));
149       forward_bytes -= kReadSize;
150       read_position += kReadSize;
151       EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
152     }
153   }
154 }
155
156 TEST_F(SeekableBufferTest, BufferFull) {
157   const int kMaxWriteSize = 2 * kBufferSize;
158
159   // Write and expect the buffer to be not full.
160   for (int i = 0; i < kBufferSize - kWriteSize; i += kWriteSize) {
161     EXPECT_TRUE(buffer_.Append(data_ + i, kWriteSize));
162     EXPECT_EQ(i + kWriteSize, buffer_.forward_bytes());
163   }
164
165   // Write until we have kMaxWriteSize bytes in the buffer. Buffer is full in
166   // these writes.
167   for (int i = buffer_.forward_bytes(); i < kMaxWriteSize; i += kWriteSize) {
168     EXPECT_FALSE(buffer_.Append(data_ + i, kWriteSize));
169     EXPECT_EQ(i + kWriteSize, buffer_.forward_bytes());
170   }
171
172   // Read until the buffer is empty.
173   int read_position = 0;
174   while (buffer_.forward_bytes()) {
175     // Read a random amount of data.
176     int read_size = GetRandomInt(kBufferSize);
177     int forward_bytes = buffer_.forward_bytes();
178     int bytes_read = buffer_.Read(write_buffer_, read_size);
179     EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, bytes_read));
180     if (read_size > forward_bytes)
181       EXPECT_EQ(forward_bytes, bytes_read);
182     else
183       EXPECT_EQ(read_size, bytes_read);
184     read_position += bytes_read;
185     EXPECT_GE(kMaxWriteSize, read_position);
186     EXPECT_EQ(kMaxWriteSize - read_position, buffer_.forward_bytes());
187   }
188
189   // Expects we have no bytes left.
190   EXPECT_EQ(0, buffer_.forward_bytes());
191   EXPECT_EQ(0, buffer_.Read(write_buffer_, 1));
192 }
193
194 TEST_F(SeekableBufferTest, SeekBackward) {
195   EXPECT_EQ(0, buffer_.forward_bytes());
196   EXPECT_EQ(0, buffer_.backward_bytes());
197   EXPECT_FALSE(buffer_.Seek(1));
198   EXPECT_FALSE(buffer_.Seek(-1));
199
200   const int kReadSize = 256;
201
202   // Write into buffer until it's full.
203   for (int i = 0; i < kBufferSize; i += kWriteSize) {
204     // Write a random amount of data.
205     buffer_.Append(data_ + i, kWriteSize);
206   }
207
208   // Read until buffer is empty.
209   for (int i = 0; i < kBufferSize; i += kReadSize) {
210     EXPECT_EQ(kReadSize, buffer_.Read(write_buffer_, kReadSize));
211     EXPECT_EQ(0, memcmp(write_buffer_, data_ + i, kReadSize));
212   }
213
214   // Seek backward.
215   EXPECT_TRUE(buffer_.Seek(-static_cast<int32>(kBufferSize)));
216   EXPECT_FALSE(buffer_.Seek(-1));
217
218   // Read again.
219   for (int i = 0; i < kBufferSize; i += kReadSize) {
220     EXPECT_EQ(kReadSize, buffer_.Read(write_buffer_, kReadSize));
221     EXPECT_EQ(0, memcmp(write_buffer_, data_ + i, kReadSize));
222   }
223 }
224
225 TEST_F(SeekableBufferTest, GetCurrentChunk) {
226   const int kSeekSize = kWriteSize / 3;
227
228   scoped_refptr<DataBuffer> buffer = DataBuffer::CopyFrom(data_, kWriteSize);
229
230   const uint8* data;
231   int size;
232   EXPECT_FALSE(buffer_.GetCurrentChunk(&data, &size));
233
234   buffer_.Append(buffer.get());
235   EXPECT_TRUE(buffer_.GetCurrentChunk(&data, &size));
236   EXPECT_EQ(data, buffer->data());
237   EXPECT_EQ(size, buffer->data_size());
238
239   buffer_.Seek(kSeekSize);
240   EXPECT_TRUE(buffer_.GetCurrentChunk(&data, &size));
241   EXPECT_EQ(data, buffer->data() + kSeekSize);
242   EXPECT_EQ(size, buffer->data_size() - kSeekSize);
243 }
244
245 TEST_F(SeekableBufferTest, SeekForward) {
246   int write_position = 0;
247   int read_position = 0;
248   while (read_position < kDataSize) {
249     for (int i = 0; i < 10 && write_position < kDataSize; ++i) {
250       // Write a random amount of data.
251       int write_size = GetRandomInt(kBufferSize);
252       write_size = std::min(write_size, kDataSize - write_position);
253
254       bool should_append = buffer_.Append(data_ + write_position, write_size);
255       write_position += write_size;
256       EXPECT_GE(write_position, read_position);
257       EXPECT_EQ(write_position - read_position, buffer_.forward_bytes());
258       EXPECT_EQ(should_append, buffer_.forward_bytes() < kBufferSize)
259           << "Incorrect buffer full status reported";
260     }
261
262     // Read a random amount of data.
263     int seek_size = GetRandomInt(kBufferSize);
264     if (buffer_.Seek(seek_size))
265       read_position += seek_size;
266     EXPECT_GE(write_position, read_position);
267     EXPECT_EQ(write_position - read_position, buffer_.forward_bytes());
268
269     // Read a random amount of data.
270     int read_size = GetRandomInt(kBufferSize);
271     int bytes_read = buffer_.Read(write_buffer_, read_size);
272     EXPECT_GE(read_size, bytes_read);
273     EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, bytes_read));
274     read_position += bytes_read;
275     EXPECT_GE(write_position, read_position);
276     EXPECT_EQ(write_position - read_position, buffer_.forward_bytes());
277   }
278 }
279
280 TEST_F(SeekableBufferTest, AllMethods) {
281   EXPECT_EQ(0, buffer_.Read(write_buffer_, 0));
282   EXPECT_EQ(0, buffer_.Read(write_buffer_, 1));
283   EXPECT_TRUE(buffer_.Seek(0));
284   EXPECT_FALSE(buffer_.Seek(-1));
285   EXPECT_FALSE(buffer_.Seek(1));
286   EXPECT_EQ(0, buffer_.forward_bytes());
287   EXPECT_EQ(0, buffer_.backward_bytes());
288 }
289
290 TEST_F(SeekableBufferTest, GetTime) {
291   const int64 kNoTS = kNoTimestamp().ToInternalValue();
292   const struct {
293     int64 first_time_useconds;
294     int64 duration_useconds;
295     int consume_bytes;
296     int64 expected_time;
297   } tests[] = {
298     { kNoTS, 1000000, 0, kNoTS },
299     { kNoTS, 4000000, 0, kNoTS },
300     { kNoTS, 8000000, 0, kNoTS },
301     { kNoTS, 1000000, kWriteSize / 2, kNoTS },
302     { kNoTS, 4000000, kWriteSize / 2, kNoTS },
303     { kNoTS, 8000000, kWriteSize / 2, kNoTS },
304     { kNoTS, 1000000, kWriteSize, kNoTS },
305     { kNoTS, 4000000, kWriteSize, kNoTS },
306     { kNoTS, 8000000, kWriteSize, kNoTS },
307     { 0, 1000000, 0, 0 },
308     { 0, 4000000, 0, 0 },
309     { 0, 8000000, 0, 0 },
310     { 0, 1000000, kWriteSize / 2, 500000 },
311     { 0, 4000000, kWriteSize / 2, 2000000 },
312     { 0, 8000000, kWriteSize / 2, 4000000 },
313     { 0, 1000000, kWriteSize, 1000000 },
314     { 0, 4000000, kWriteSize, 4000000 },
315     { 0, 8000000, kWriteSize, 8000000 },
316     { 5, 1000000, 0, 5 },
317     { 5, 4000000, 0, 5 },
318     { 5, 8000000, 0, 5 },
319     { 5, 1000000, kWriteSize / 2, 500005 },
320     { 5, 4000000, kWriteSize / 2, 2000005 },
321     { 5, 8000000, kWriteSize / 2, 4000005 },
322     { 5, 1000000, kWriteSize, 1000005 },
323     { 5, 4000000, kWriteSize, 4000005 },
324     { 5, 8000000, kWriteSize, 8000005 },
325   };
326
327   // current_time() must initially return kNoTimestamp().
328   EXPECT_EQ(kNoTimestamp().ToInternalValue(),
329             buffer_.current_time().ToInternalValue());
330
331   scoped_refptr<DataBuffer> buffer = DataBuffer::CopyFrom(data_, kWriteSize);
332
333   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
334     buffer->set_timestamp(base::TimeDelta::FromMicroseconds(
335         tests[i].first_time_useconds));
336     buffer->set_duration(base::TimeDelta::FromMicroseconds(
337         tests[i].duration_useconds));
338     buffer_.Append(buffer.get());
339     EXPECT_TRUE(buffer_.Seek(tests[i].consume_bytes));
340
341     int64 actual = buffer_.current_time().ToInternalValue();
342
343     EXPECT_EQ(tests[i].expected_time, actual) << "With test = { start:"
344         << tests[i].first_time_useconds << ", duration:"
345         << tests[i].duration_useconds << ", consumed:"
346         << tests[i].consume_bytes << " }\n";
347
348     buffer_.Clear();
349   }
350 }
351
352 }  // namespace media