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 353