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 <cstdlib> 6 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" 13 14 namespace media { 15 16 class SeekableBufferTest : public testing::Test { 17 public: 18 SeekableBufferTest() : buffer_(kBufferSize, kBufferSize) { 19 } 20 21 protected: 22 static const int kDataSize = 409600; 23 static const int kBufferSize = 4096; 24 static const int kWriteSize = 512; 25 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; 31 srand(kKnownSeed); 32 33 // Create random test data samples. 34 for (int i = 0; i < kDataSize; i++) 35 data_[i] = static_cast<char>(rand()); 36 } 37 38 int GetRandomInt(int maximum) { 39 return rand() % (maximum + 1); 40 } 41 42 SeekableBuffer buffer_; 43 uint8 data_[kDataSize]; 44 uint8 write_buffer_[kDataSize]; 45 }; 46 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"; 60 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)); 66 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()); 75 } 76 } 77 78 TEST_F(SeekableBufferTest, ReadWriteSeek) { 79 const int kReadSize = kWriteSize / 4; 80 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()); 88 } 89 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; 101 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()); 107 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)); 112 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; 119 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()); 125 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)); 130 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; 137 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)); 142 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; 149 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()); 155 } 156 } 157 } 158 159 TEST_F(SeekableBufferTest, BufferFull) { 160 const int kMaxWriteSize = 2 * kBufferSize; 161 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()); 166 } 167 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()); 173 } 174 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()); 190 } 191 192 // Expects we have no bytes left. 193 EXPECT_EQ(0, buffer_.forward_bytes()); 194 EXPECT_EQ(0, buffer_.Read(write_buffer_, 1)); 195 } 196 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)); 202 203 const int kReadSize = 256; 204 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); 209 } 210 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)); 215 } 216 217 // Seek backward. 218 EXPECT_TRUE(buffer_.Seek(-static_cast<int32>(kBufferSize))); 219 EXPECT_FALSE(buffer_.Seek(-1)); 220 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)); 225 } 226 } 227 228 TEST_F(SeekableBufferTest, GetCurrentChunk) { 229 const int kSeekSize = kWriteSize / 3; 230 231 scoped_refptr<DataBuffer> buffer = DataBuffer::CopyFrom(data_, kWriteSize); 232 233 const uint8* data; 234 int size; 235 EXPECT_FALSE(buffer_.GetCurrentChunk(&data, &size)); 236 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()); 241 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); 246 } 247 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); 256 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"; 263 } 264 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()); 271 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()); 280 } 281 } 282 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()); 291 } 292 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 }, 328 }; 329 330 // current_time() must initially return kNoTimestamp(). 331 EXPECT_EQ(kNoTimestamp().ToInternalValue(), 332 buffer_.current_time().ToInternalValue()); 333 334 scoped_refptr<DataBuffer> buffer = DataBuffer::CopyFrom(data_, kWriteSize); 335 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)); 343 344 int64 actual = buffer_.current_time().ToInternalValue(); 345 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"; 350 351 buffer_.Clear(); 352 } 353 } 354 355 } // namespace media 356