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 "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"
14 class SeekableBufferTest
: public testing::Test
{
16 SeekableBufferTest() : buffer_(kBufferSize
, kBufferSize
) {
20 static const int kDataSize
= 409600;
21 static const int kBufferSize
= 4096;
22 static const int kWriteSize
= 512;
24 virtual void SetUp() {
26 int seed
= static_cast<int32
>(base::Time::Now().ToInternalValue());
28 VLOG(1) << "Random seed: " << seed
;
30 // Creates a test data.
31 for (int i
= 0; i
< kDataSize
; i
++)
32 data_
[i
] = static_cast<char>(rand());
35 int GetRandomInt(int maximum
) {
36 return rand() % maximum
+ 1;
39 SeekableBuffer buffer_
;
40 uint8 data_
[kDataSize
];
41 uint8 write_buffer_
[kDataSize
];
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";
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
));
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());
75 TEST_F(SeekableBufferTest
, ReadWriteSeek
) {
76 const int kReadSize
= kWriteSize
/ 4;
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());
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
) {
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
;
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());
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
));
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
;
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());
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
));
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
;
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
));
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
;
148 EXPECT_TRUE(buffer_
.Seek(kReadSize
));
149 forward_bytes
-= kReadSize
;
150 read_position
+= kReadSize
;
151 EXPECT_EQ(forward_bytes
, buffer_
.forward_bytes());
156 TEST_F(SeekableBufferTest
, BufferFull
) {
157 const int kMaxWriteSize
= 2 * kBufferSize
;
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());
165 // Write until we have kMaxWriteSize bytes in the buffer. Buffer is full in
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());
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
);
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());
189 // Expects we have no bytes left.
190 EXPECT_EQ(0, buffer_
.forward_bytes());
191 EXPECT_EQ(0, buffer_
.Read(write_buffer_
, 1));
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));
200 const int kReadSize
= 256;
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
);
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
));
215 EXPECT_TRUE(buffer_
.Seek(-static_cast<int32
>(kBufferSize
)));
216 EXPECT_FALSE(buffer_
.Seek(-1));
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
));
225 TEST_F(SeekableBufferTest
, GetCurrentChunk
) {
226 const int kSeekSize
= kWriteSize
/ 3;
228 scoped_refptr
<DataBuffer
> buffer
= DataBuffer::CopyFrom(data_
, kWriteSize
);
232 EXPECT_FALSE(buffer_
.GetCurrentChunk(&data
, &size
));
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());
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
);
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
);
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";
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());
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());
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());
290 TEST_F(SeekableBufferTest
, GetTime
) {
291 const int64 kNoTS
= kNoTimestamp().ToInternalValue();
293 int64 first_time_useconds
;
294 int64 duration_useconds
;
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 },
327 // current_time() must initially return kNoTimestamp().
328 EXPECT_EQ(kNoTimestamp().ToInternalValue(),
329 buffer_
.current_time().ToInternalValue());
331 scoped_refptr
<DataBuffer
> buffer
= DataBuffer::CopyFrom(data_
, kWriteSize
);
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
));
341 int64 actual
= buffer_
.current_time().ToInternalValue();
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";