Home | History | Annotate | Download | only in filters
      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/basictypes.h"
      6 #include "base/bind.h"
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "media/base/decoder_buffer.h"
     10 #include "media/base/demuxer_stream.h"
     11 #include "media/filters/fake_demuxer_stream.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 namespace media {
     15 
     16 const int kNumBuffersInOneConfig = 9;
     17 const int kNumBuffersToReadFirst = 5;
     18 const int kNumConfigs = 3;
     19 COMPILE_ASSERT(kNumBuffersToReadFirst < kNumBuffersInOneConfig,
     20                do_not_read_too_many_buffers);
     21 COMPILE_ASSERT(kNumConfigs > 0, need_multiple_configs_to_trigger_config_change);
     22 
     23 class FakeDemuxerStreamTest : public testing::Test {
     24  public:
     25   FakeDemuxerStreamTest()
     26       : status_(DemuxerStream::kAborted),
     27         read_pending_(false),
     28         num_buffers_received_(0) {}
     29   virtual ~FakeDemuxerStreamTest() {}
     30 
     31   void BufferReady(DemuxerStream::Status status,
     32                    const scoped_refptr<DecoderBuffer>& buffer) {
     33     DCHECK(read_pending_);
     34     read_pending_ = false;
     35     status_ = status;
     36     buffer_ = buffer;
     37     if (status == DemuxerStream::kOk && !buffer->end_of_stream())
     38       num_buffers_received_++;
     39   }
     40 
     41   enum ReadResult {
     42     OK,
     43     ABORTED,
     44     CONFIG_CHANGED,
     45     EOS,
     46     PENDING
     47   };
     48 
     49   void EnterNormalReadState() {
     50     stream_.reset(
     51         new FakeDemuxerStream(kNumConfigs, kNumBuffersInOneConfig, false));
     52     for (int i = 0; i < kNumBuffersToReadFirst; ++i)
     53       ReadAndExpect(OK);
     54     DCHECK_EQ(kNumBuffersToReadFirst, num_buffers_received_);
     55   }
     56 
     57   void EnterBeforeEOSState() {
     58     stream_.reset(new FakeDemuxerStream(1, kNumBuffersInOneConfig, false));
     59     for (int i = 0; i < kNumBuffersInOneConfig; ++i)
     60       ReadAndExpect(OK);
     61     DCHECK_EQ(kNumBuffersInOneConfig, num_buffers_received_);
     62   }
     63 
     64   void ExpectReadResult(ReadResult result) {
     65     switch (result) {
     66       case OK:
     67         EXPECT_FALSE(read_pending_);
     68         EXPECT_EQ(DemuxerStream::kOk, status_);
     69         ASSERT_TRUE(buffer_.get());
     70         EXPECT_FALSE(buffer_->end_of_stream());
     71         break;
     72 
     73       case ABORTED:
     74         EXPECT_FALSE(read_pending_);
     75         EXPECT_EQ(DemuxerStream::kAborted, status_);
     76         EXPECT_FALSE(buffer_.get());
     77         break;
     78 
     79       case CONFIG_CHANGED:
     80         EXPECT_TRUE(stream_->SupportsConfigChanges());
     81         EXPECT_FALSE(read_pending_);
     82         EXPECT_EQ(DemuxerStream::kConfigChanged, status_);
     83         EXPECT_FALSE(buffer_.get());
     84         break;
     85 
     86       case EOS:
     87         EXPECT_FALSE(read_pending_);
     88         EXPECT_EQ(DemuxerStream::kOk, status_);
     89         ASSERT_TRUE(buffer_.get());
     90         EXPECT_TRUE(buffer_->end_of_stream());
     91         break;
     92 
     93       case PENDING:
     94         EXPECT_TRUE(read_pending_);
     95         break;
     96     }
     97   }
     98 
     99   void ReadAndExpect(ReadResult result) {
    100     EXPECT_FALSE(read_pending_);
    101     read_pending_ = true;
    102     stream_->Read(base::Bind(&FakeDemuxerStreamTest::BufferReady,
    103                              base::Unretained(this)));
    104     message_loop_.RunUntilIdle();
    105     ExpectReadResult(result);
    106   }
    107 
    108   void ReadUntilPending() {
    109     while (1) {
    110       read_pending_ = true;
    111       stream_->Read(base::Bind(&FakeDemuxerStreamTest::BufferReady,
    112                                base::Unretained(this)));
    113       message_loop_.RunUntilIdle();
    114       if (read_pending_)
    115         break;
    116     }
    117   }
    118 
    119   void SatisfyReadAndExpect(ReadResult result) {
    120     EXPECT_TRUE(read_pending_);
    121     stream_->SatisfyRead();
    122     message_loop_.RunUntilIdle();
    123     ExpectReadResult(result);
    124   }
    125 
    126   void Reset() {
    127     bool had_read_pending = read_pending_;
    128     stream_->Reset();
    129     message_loop_.RunUntilIdle();
    130 
    131     EXPECT_FALSE(read_pending_);
    132     if (had_read_pending)
    133       ExpectReadResult(ABORTED);
    134   }
    135 
    136   void ReadAllBuffers(int num_configs, int num_buffers_in_one_config) {
    137     DCHECK_EQ(0, num_buffers_received_);
    138     for (int i = 0; i < num_configs; ++i) {
    139       for (int j = 0; j < num_buffers_in_one_config; ++j) {
    140         ReadAndExpect(OK);
    141         EXPECT_EQ(num_buffers_received_, stream_->num_buffers_returned());
    142       }
    143 
    144       if (i == num_configs - 1)
    145         ReadAndExpect(EOS);
    146       else
    147         ReadAndExpect(CONFIG_CHANGED);
    148     }
    149 
    150     // Will always get EOS after we hit EOS.
    151     ReadAndExpect(EOS);
    152 
    153     EXPECT_EQ(num_configs * num_buffers_in_one_config, num_buffers_received_);
    154   }
    155 
    156   void TestRead(int num_configs,
    157                 int num_buffers_in_one_config,
    158                 bool is_encrypted) {
    159     stream_.reset(new FakeDemuxerStream(
    160         num_configs, num_buffers_in_one_config, is_encrypted));
    161 
    162     const VideoDecoderConfig& config = stream_->video_decoder_config();
    163     EXPECT_TRUE(config.IsValidConfig());
    164     EXPECT_EQ(is_encrypted, config.is_encrypted());
    165 
    166     ReadAllBuffers(num_configs, num_buffers_in_one_config);
    167   }
    168 
    169   base::MessageLoop message_loop_;
    170   scoped_ptr<FakeDemuxerStream> stream_;
    171 
    172   DemuxerStream::Status status_;
    173   scoped_refptr<DecoderBuffer> buffer_;
    174   bool read_pending_;
    175   int num_buffers_received_;
    176 
    177  private:
    178   DISALLOW_COPY_AND_ASSIGN(FakeDemuxerStreamTest);
    179 };
    180 
    181 TEST_F(FakeDemuxerStreamTest, Read_OneConfig) {
    182   TestRead(1, 5, false);
    183 }
    184 
    185 TEST_F(FakeDemuxerStreamTest, Read_MultipleConfigs) {
    186   TestRead(3, 5, false);
    187 }
    188 
    189 TEST_F(FakeDemuxerStreamTest, Read_OneBufferPerConfig) {
    190   TestRead(3, 1, false);
    191 }
    192 
    193 TEST_F(FakeDemuxerStreamTest, Read_Encrypted) {
    194   TestRead(6, 3, true);
    195 }
    196 
    197 TEST_F(FakeDemuxerStreamTest, HoldRead_Normal) {
    198   EnterNormalReadState();
    199   stream_->HoldNextRead();
    200   ReadAndExpect(PENDING);
    201   SatisfyReadAndExpect(OK);
    202 }
    203 
    204 TEST_F(FakeDemuxerStreamTest, HoldRead_BeforeConfigChanged) {
    205   EnterNormalReadState();
    206   stream_->HoldNextConfigChangeRead();
    207   ReadUntilPending();
    208   SatisfyReadAndExpect(CONFIG_CHANGED);
    209 }
    210 
    211 TEST_F(FakeDemuxerStreamTest, HoldRead_BeforeEOS) {
    212   EnterBeforeEOSState();
    213   stream_->HoldNextRead();
    214   ReadAndExpect(PENDING);
    215   SatisfyReadAndExpect(EOS);
    216 }
    217 
    218 TEST_F(FakeDemuxerStreamTest, Reset_Normal) {
    219   EnterNormalReadState();
    220   Reset();
    221   ReadAndExpect(OK);
    222 }
    223 
    224 TEST_F(FakeDemuxerStreamTest, Reset_AfterHoldRead) {
    225   EnterNormalReadState();
    226   stream_->HoldNextRead();
    227   Reset();
    228   ReadAndExpect(OK);
    229 }
    230 
    231 TEST_F(FakeDemuxerStreamTest, Reset_DuringPendingRead) {
    232   EnterNormalReadState();
    233   stream_->HoldNextRead();
    234   ReadAndExpect(PENDING);
    235   Reset();
    236   ReadAndExpect(OK);
    237 }
    238 
    239 TEST_F(FakeDemuxerStreamTest, Reset_BeforeConfigChanged) {
    240   EnterNormalReadState();
    241   stream_->HoldNextConfigChangeRead();
    242   ReadUntilPending();
    243   Reset();
    244   ReadAndExpect(CONFIG_CHANGED);
    245 }
    246 
    247 TEST_F(FakeDemuxerStreamTest, Reset_BeforeEOS) {
    248   EnterBeforeEOSState();
    249   stream_->HoldNextRead();
    250   ReadAndExpect(PENDING);
    251   Reset();
    252   ReadAndExpect(EOS);
    253 }
    254 
    255 TEST_F(FakeDemuxerStreamTest, NoConfigChanges) {
    256   stream_.reset(
    257       new FakeDemuxerStream(1, kNumBuffersInOneConfig, false));
    258   EXPECT_FALSE(stream_->SupportsConfigChanges());
    259   for (int i = 0; i < kNumBuffersInOneConfig; ++i)
    260     ReadAndExpect(OK);
    261   ReadAndExpect(EOS);
    262 }
    263 
    264 TEST_F(FakeDemuxerStreamTest, SeekToStart_Normal) {
    265   EnterNormalReadState();
    266   stream_->SeekToStart();
    267   num_buffers_received_ = 0;
    268   ReadAllBuffers(kNumConfigs, kNumBuffersInOneConfig);
    269 }
    270 
    271 TEST_F(FakeDemuxerStreamTest, SeekToStart_BeforeEOS) {
    272   EnterBeforeEOSState();
    273   stream_->SeekToStart();
    274   num_buffers_received_ = 0;
    275   ReadAllBuffers(1, kNumBuffersInOneConfig);
    276 }
    277 
    278 TEST_F(FakeDemuxerStreamTest, SeekToStart_AfterEOS) {
    279   TestRead(3, 5, false);
    280   stream_->SeekToStart();
    281   num_buffers_received_ = 0;
    282   ReadAllBuffers(3, 5);
    283 }
    284 
    285 }  // namespace media
    286