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.
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"
16 class SeekableBufferTest
: public testing::Test
{
18 SeekableBufferTest() : buffer_(kBufferSize
, kBufferSize
) {
22 static const int kDataSize
= 409600;
23 static const int kBufferSize
= 4096;
24 static const int kWriteSize
= 512;
26 virtual void SetUp() {
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;
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
) {
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
;
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());
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
));
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
;
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());
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
));
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
;
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
));
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
;
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
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
);
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
));
218 EXPECT_TRUE(buffer_
.Seek(-static_cast<int32
>(kBufferSize
)));
219 EXPECT_FALSE(buffer_
.Seek(-1));
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
);
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();
296 int64 first_time_useconds
;
297 int64 duration_useconds
;
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_UNSAFE(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";