Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / media / base / seekable_buffer_unittest.cc
blobc2844254136abc5085cd9252f11e90b028e8b425
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.
5 #include <cstdlib>
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/time/time.h"
10 #include "media/base/data_buffer.h"
11 #include "media/base/seekable_buffer.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 namespace media {
16 class SeekableBufferTest : public testing::Test {
17 public:
18 SeekableBufferTest() : buffer_(kBufferSize, kBufferSize) {
21 protected:
22 static const int kDataSize = 409600;
23 static const int kBufferSize = 4096;
24 static const int kWriteSize = 512;
26 void SetUp() override {
27 // Note: We use srand() and rand() rather than base::RandXXX() to improve
28 // unit test performance. We don't need good random numbers, just
29 // something that generates "mixed data."
30 const unsigned int kKnownSeed = 0x98765432;
31 srand(kKnownSeed);
33 // Create random test data samples.
34 for (int i = 0; i < kDataSize; i++)
35 data_[i] = static_cast<char>(rand());
38 int GetRandomInt(int maximum) {
39 return rand() % (maximum + 1);
42 SeekableBuffer buffer_;
43 uint8 data_[kDataSize];
44 uint8 write_buffer_[kDataSize];
47 TEST_F(SeekableBufferTest, RandomReadWrite) {
48 int write_position = 0;
49 int read_position = 0;
50 while (read_position < kDataSize) {
51 // Write a random amount of data.
52 int write_size = GetRandomInt(kBufferSize);
53 write_size = std::min(write_size, kDataSize - write_position);
54 bool should_append = buffer_.Append(data_ + write_position, write_size);
55 write_position += write_size;
56 EXPECT_GE(write_position, read_position);
57 EXPECT_EQ(write_position - read_position, buffer_.forward_bytes());
58 EXPECT_EQ(should_append, buffer_.forward_bytes() < kBufferSize)
59 << "Incorrect buffer full reported";
61 // Peek a random amount of data.
62 int copy_size = GetRandomInt(kBufferSize);
63 int bytes_copied = buffer_.Peek(write_buffer_, copy_size);
64 EXPECT_GE(copy_size, bytes_copied);
65 EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, bytes_copied));
67 // Read a random amount of data.
68 int read_size = GetRandomInt(kBufferSize);
69 int bytes_read = buffer_.Read(write_buffer_, read_size);
70 EXPECT_GE(read_size, bytes_read);
71 EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, bytes_read));
72 read_position += bytes_read;
73 EXPECT_GE(write_position, read_position);
74 EXPECT_EQ(write_position - read_position, buffer_.forward_bytes());
78 TEST_F(SeekableBufferTest, ReadWriteSeek) {
79 const int kReadSize = kWriteSize / 4;
81 for (int i = 0; i < 10; ++i) {
82 // Write until buffer is full.
83 for (int j = 0; j < kBufferSize; j += kWriteSize) {
84 bool should_append = buffer_.Append(data_ + j, kWriteSize);
85 EXPECT_EQ(j < kBufferSize - kWriteSize, should_append)
86 << "Incorrect buffer full reported";
87 EXPECT_EQ(j + kWriteSize, buffer_.forward_bytes());
90 // Simulate a read and seek pattern. Each loop reads 4 times, each time
91 // reading a quarter of |kWriteSize|.
92 int read_position = 0;
93 int forward_bytes = kBufferSize;
94 for (int j = 0; j < kBufferSize; j += kWriteSize) {
95 // Read.
96 EXPECT_EQ(kReadSize, buffer_.Read(write_buffer_, kReadSize));
97 forward_bytes -= kReadSize;
98 EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
99 EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, kReadSize));
100 read_position += kReadSize;
102 // Seek forward.
103 EXPECT_TRUE(buffer_.Seek(2 * kReadSize));
104 forward_bytes -= 2 * kReadSize;
105 read_position += 2 * kReadSize;
106 EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
108 // Copy.
109 EXPECT_EQ(kReadSize, buffer_.Peek(write_buffer_, kReadSize));
110 EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
111 EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, kReadSize));
113 // Read.
114 EXPECT_EQ(kReadSize, buffer_.Read(write_buffer_, kReadSize));
115 forward_bytes -= kReadSize;
116 EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
117 EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, kReadSize));
118 read_position += kReadSize;
120 // Seek backward.
121 EXPECT_TRUE(buffer_.Seek(-3 * static_cast<int32>(kReadSize)));
122 forward_bytes += 3 * kReadSize;
123 read_position -= 3 * kReadSize;
124 EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
126 // Copy.
127 EXPECT_EQ(kReadSize, buffer_.Peek(write_buffer_, kReadSize));
128 EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
129 EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, kReadSize));
131 // Read.
132 EXPECT_EQ(kReadSize, buffer_.Read(write_buffer_, kReadSize));
133 forward_bytes -= kReadSize;
134 EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
135 EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, kReadSize));
136 read_position += kReadSize;
138 // Copy.
139 EXPECT_EQ(kReadSize, buffer_.Peek(write_buffer_, kReadSize));
140 EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
141 EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, kReadSize));
143 // Read.
144 EXPECT_EQ(kReadSize, buffer_.Read(write_buffer_, kReadSize));
145 forward_bytes -= kReadSize;
146 EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
147 EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, kReadSize));
148 read_position += kReadSize;
150 // Seek forward.
151 EXPECT_TRUE(buffer_.Seek(kReadSize));
152 forward_bytes -= kReadSize;
153 read_position += kReadSize;
154 EXPECT_EQ(forward_bytes, buffer_.forward_bytes());
159 TEST_F(SeekableBufferTest, BufferFull) {
160 const int kMaxWriteSize = 2 * kBufferSize;
162 // Write and expect the buffer to be not full.
163 for (int i = 0; i < kBufferSize - kWriteSize; i += kWriteSize) {
164 EXPECT_TRUE(buffer_.Append(data_ + i, kWriteSize));
165 EXPECT_EQ(i + kWriteSize, buffer_.forward_bytes());
168 // Write until we have kMaxWriteSize bytes in the buffer. Buffer is full in
169 // these writes.
170 for (int i = buffer_.forward_bytes(); i < kMaxWriteSize; i += kWriteSize) {
171 EXPECT_FALSE(buffer_.Append(data_ + i, kWriteSize));
172 EXPECT_EQ(i + kWriteSize, buffer_.forward_bytes());
175 // Read until the buffer is empty.
176 int read_position = 0;
177 while (buffer_.forward_bytes()) {
178 // Read a random amount of data.
179 int read_size = GetRandomInt(kBufferSize);
180 int forward_bytes = buffer_.forward_bytes();
181 int bytes_read = buffer_.Read(write_buffer_, read_size);
182 EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, bytes_read));
183 if (read_size > forward_bytes)
184 EXPECT_EQ(forward_bytes, bytes_read);
185 else
186 EXPECT_EQ(read_size, bytes_read);
187 read_position += bytes_read;
188 EXPECT_GE(kMaxWriteSize, read_position);
189 EXPECT_EQ(kMaxWriteSize - read_position, buffer_.forward_bytes());
192 // Expects we have no bytes left.
193 EXPECT_EQ(0, buffer_.forward_bytes());
194 EXPECT_EQ(0, buffer_.Read(write_buffer_, 1));
197 TEST_F(SeekableBufferTest, SeekBackward) {
198 EXPECT_EQ(0, buffer_.forward_bytes());
199 EXPECT_EQ(0, buffer_.backward_bytes());
200 EXPECT_FALSE(buffer_.Seek(1));
201 EXPECT_FALSE(buffer_.Seek(-1));
203 const int kReadSize = 256;
205 // Write into buffer until it's full.
206 for (int i = 0; i < kBufferSize; i += kWriteSize) {
207 // Write a random amount of data.
208 buffer_.Append(data_ + i, kWriteSize);
211 // Read until buffer is empty.
212 for (int i = 0; i < kBufferSize; i += kReadSize) {
213 EXPECT_EQ(kReadSize, buffer_.Read(write_buffer_, kReadSize));
214 EXPECT_EQ(0, memcmp(write_buffer_, data_ + i, kReadSize));
217 // Seek backward.
218 EXPECT_TRUE(buffer_.Seek(-static_cast<int32>(kBufferSize)));
219 EXPECT_FALSE(buffer_.Seek(-1));
221 // Read again.
222 for (int i = 0; i < kBufferSize; i += kReadSize) {
223 EXPECT_EQ(kReadSize, buffer_.Read(write_buffer_, kReadSize));
224 EXPECT_EQ(0, memcmp(write_buffer_, data_ + i, kReadSize));
228 TEST_F(SeekableBufferTest, GetCurrentChunk) {
229 const int kSeekSize = kWriteSize / 3;
231 scoped_refptr<DataBuffer> buffer = DataBuffer::CopyFrom(data_, kWriteSize);
233 const uint8* data;
234 int size;
235 EXPECT_FALSE(buffer_.GetCurrentChunk(&data, &size));
237 buffer_.Append(buffer.get());
238 EXPECT_TRUE(buffer_.GetCurrentChunk(&data, &size));
239 EXPECT_EQ(data, buffer->data());
240 EXPECT_EQ(size, buffer->data_size());
242 buffer_.Seek(kSeekSize);
243 EXPECT_TRUE(buffer_.GetCurrentChunk(&data, &size));
244 EXPECT_EQ(data, buffer->data() + kSeekSize);
245 EXPECT_EQ(size, buffer->data_size() - kSeekSize);
248 TEST_F(SeekableBufferTest, SeekForward) {
249 int write_position = 0;
250 int read_position = 0;
251 while (read_position < kDataSize) {
252 for (int i = 0; i < 10 && write_position < kDataSize; ++i) {
253 // Write a random amount of data.
254 int write_size = GetRandomInt(kBufferSize);
255 write_size = std::min(write_size, kDataSize - write_position);
257 bool should_append = buffer_.Append(data_ + write_position, write_size);
258 write_position += write_size;
259 EXPECT_GE(write_position, read_position);
260 EXPECT_EQ(write_position - read_position, buffer_.forward_bytes());
261 EXPECT_EQ(should_append, buffer_.forward_bytes() < kBufferSize)
262 << "Incorrect buffer full status reported";
265 // Read a random amount of data.
266 int seek_size = GetRandomInt(kBufferSize);
267 if (buffer_.Seek(seek_size))
268 read_position += seek_size;
269 EXPECT_GE(write_position, read_position);
270 EXPECT_EQ(write_position - read_position, buffer_.forward_bytes());
272 // Read a random amount of data.
273 int read_size = GetRandomInt(kBufferSize);
274 int bytes_read = buffer_.Read(write_buffer_, read_size);
275 EXPECT_GE(read_size, bytes_read);
276 EXPECT_EQ(0, memcmp(write_buffer_, data_ + read_position, bytes_read));
277 read_position += bytes_read;
278 EXPECT_GE(write_position, read_position);
279 EXPECT_EQ(write_position - read_position, buffer_.forward_bytes());
283 TEST_F(SeekableBufferTest, AllMethods) {
284 EXPECT_EQ(0, buffer_.Read(write_buffer_, 0));
285 EXPECT_EQ(0, buffer_.Read(write_buffer_, 1));
286 EXPECT_TRUE(buffer_.Seek(0));
287 EXPECT_FALSE(buffer_.Seek(-1));
288 EXPECT_FALSE(buffer_.Seek(1));
289 EXPECT_EQ(0, buffer_.forward_bytes());
290 EXPECT_EQ(0, buffer_.backward_bytes());
293 TEST_F(SeekableBufferTest, GetTime) {
294 const int64 kNoTS = kNoTimestamp().ToInternalValue();
295 const struct {
296 int64 first_time_useconds;
297 int64 duration_useconds;
298 int consume_bytes;
299 int64 expected_time;
300 } tests[] = {
301 { kNoTS, 1000000, 0, kNoTS },
302 { kNoTS, 4000000, 0, kNoTS },
303 { kNoTS, 8000000, 0, kNoTS },
304 { kNoTS, 1000000, kWriteSize / 2, kNoTS },
305 { kNoTS, 4000000, kWriteSize / 2, kNoTS },
306 { kNoTS, 8000000, kWriteSize / 2, kNoTS },
307 { kNoTS, 1000000, kWriteSize, kNoTS },
308 { kNoTS, 4000000, kWriteSize, kNoTS },
309 { kNoTS, 8000000, kWriteSize, kNoTS },
310 { 0, 1000000, 0, 0 },
311 { 0, 4000000, 0, 0 },
312 { 0, 8000000, 0, 0 },
313 { 0, 1000000, kWriteSize / 2, 500000 },
314 { 0, 4000000, kWriteSize / 2, 2000000 },
315 { 0, 8000000, kWriteSize / 2, 4000000 },
316 { 0, 1000000, kWriteSize, 1000000 },
317 { 0, 4000000, kWriteSize, 4000000 },
318 { 0, 8000000, kWriteSize, 8000000 },
319 { 5, 1000000, 0, 5 },
320 { 5, 4000000, 0, 5 },
321 { 5, 8000000, 0, 5 },
322 { 5, 1000000, kWriteSize / 2, 500005 },
323 { 5, 4000000, kWriteSize / 2, 2000005 },
324 { 5, 8000000, kWriteSize / 2, 4000005 },
325 { 5, 1000000, kWriteSize, 1000005 },
326 { 5, 4000000, kWriteSize, 4000005 },
327 { 5, 8000000, kWriteSize, 8000005 },
330 // current_time() must initially return kNoTimestamp().
331 EXPECT_EQ(kNoTimestamp().ToInternalValue(),
332 buffer_.current_time().ToInternalValue());
334 scoped_refptr<DataBuffer> buffer = DataBuffer::CopyFrom(data_, kWriteSize);
336 for (size_t i = 0; i < arraysize(tests); ++i) {
337 buffer->set_timestamp(base::TimeDelta::FromMicroseconds(
338 tests[i].first_time_useconds));
339 buffer->set_duration(base::TimeDelta::FromMicroseconds(
340 tests[i].duration_useconds));
341 buffer_.Append(buffer.get());
342 EXPECT_TRUE(buffer_.Seek(tests[i].consume_bytes));
344 int64 actual = buffer_.current_time().ToInternalValue();
346 EXPECT_EQ(tests[i].expected_time, actual) << "With test = { start:"
347 << tests[i].first_time_useconds << ", duration:"
348 << tests[i].duration_useconds << ", consumed:"
349 << tests[i].consume_bytes << " }\n";
351 buffer_.Clear();
355 } // namespace media