Home | History | Annotate | Download | only in base
      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