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 "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