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/bind.h"
      6 #include "base/callback_helpers.h"
      7 #include "base/message_loop/message_loop.h"
      8 #include "media/base/gmock_callback_support.h"
      9 #include "media/base/mock_filters.h"
     10 #include "media/base/test_helpers.h"
     11 #include "media/filters/fake_demuxer_stream.h"
     12 #include "media/filters/fake_video_decoder.h"
     13 #include "media/filters/video_frame_stream.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 
     16 using ::testing::_;
     17 using ::testing::Assign;
     18 using ::testing::Invoke;
     19 using ::testing::NiceMock;
     20 using ::testing::Return;
     21 using ::testing::SaveArg;
     22 
     23 static const int kNumConfigs = 3;
     24 static const int kNumBuffersInOneConfig = 5;
     25 static const int kDecodingDelay = 7;
     26 
     27 namespace media {
     28 
     29 class VideoFrameStreamTest : public testing::TestWithParam<bool> {
     30  public:
     31   VideoFrameStreamTest()
     32       : demuxer_stream_(new FakeDemuxerStream(kNumConfigs,
     33                                               kNumBuffersInOneConfig,
     34                                               GetParam())),
     35         decryptor_(new NiceMock<MockDecryptor>()),
     36         decoder_(new FakeVideoDecoder(kDecodingDelay)),
     37         is_initialized_(false),
     38         num_decoded_frames_(0),
     39         pending_read_(false),
     40         pending_reset_(false),
     41         pending_stop_(false),
     42         total_bytes_decoded_(0) {
     43     ScopedVector<VideoDecoder> decoders;
     44     decoders.push_back(decoder_);
     45 
     46     video_frame_stream_.reset(new VideoFrameStream(
     47         message_loop_.message_loop_proxy(),
     48         decoders.Pass(),
     49         base::Bind(&VideoFrameStreamTest::SetDecryptorReadyCallback,
     50                    base::Unretained(this))));
     51 
     52     EXPECT_CALL(*this, SetDecryptorReadyCallback(_))
     53         .WillRepeatedly(RunCallback<0>(decryptor_.get()));
     54 
     55     // Decryptor can only decrypt (not decrypt-and-decode) so that
     56     // DecryptingDemuxerStream will be used.
     57     EXPECT_CALL(*decryptor_, InitializeVideoDecoder(_, _))
     58         .WillRepeatedly(RunCallback<1>(false));
     59     EXPECT_CALL(*decryptor_, Decrypt(_, _, _))
     60         .WillRepeatedly(Invoke(this, &VideoFrameStreamTest::Decrypt));
     61   }
     62 
     63   ~VideoFrameStreamTest() {
     64     DCHECK(!pending_read_);
     65     DCHECK(!pending_reset_);
     66     DCHECK(!pending_stop_);
     67 
     68     // Check that the pipeline statistics callback was fired correctly.
     69     if (decoder_)
     70       EXPECT_EQ(decoder_->total_bytes_decoded(), total_bytes_decoded_);
     71 
     72     if (is_initialized_)
     73       Stop();
     74     EXPECT_FALSE(is_initialized_);
     75   }
     76 
     77   MOCK_METHOD1(SetDecryptorReadyCallback, void(const media::DecryptorReadyCB&));
     78   MOCK_METHOD2(OnInitialized, void(bool, bool));
     79 
     80   void OnStatistics(const PipelineStatistics& statistics) {
     81     total_bytes_decoded_ += statistics.video_bytes_decoded;
     82   }
     83 
     84   // Fake Decrypt() function used by DecryptingDemuxerStream. It does nothing
     85   // but removes the DecryptConfig to make the buffer unencrypted.
     86   void Decrypt(Decryptor::StreamType stream_type,
     87                const scoped_refptr<DecoderBuffer>& encrypted,
     88                const Decryptor::DecryptCB& decrypt_cb) {
     89     DCHECK_EQ(stream_type, Decryptor::kVideo);
     90     scoped_refptr<DecoderBuffer> decrypted = DecoderBuffer::CopyFrom(
     91         encrypted->data(), encrypted->data_size());
     92     decrypted->set_timestamp(encrypted->timestamp());
     93     decrypted->set_duration(encrypted->duration());
     94     decrypt_cb.Run(Decryptor::kSuccess, decrypted);
     95   }
     96 
     97   // Callback for VideoFrameStream::Read().
     98   void FrameReady(VideoFrameStream::Status status,
     99                   const scoped_refptr<VideoFrame>& frame) {
    100     DCHECK(pending_read_);
    101     // TODO(xhwang): Add test cases where the fake decoder returns error or
    102     // the fake demuxer aborts demuxer read.
    103     ASSERT_TRUE(status == VideoFrameStream::OK ||
    104                 status == VideoFrameStream::ABORTED);
    105     frame_read_ = frame;
    106     if (frame.get() && !frame->IsEndOfStream())
    107       num_decoded_frames_++;
    108     pending_read_ = false;
    109   }
    110 
    111   void OnReset() {
    112     DCHECK(!pending_read_);
    113     DCHECK(pending_reset_);
    114     pending_reset_ = false;
    115   }
    116 
    117   void OnStopped() {
    118     DCHECK(!pending_read_);
    119     DCHECK(!pending_reset_);
    120     DCHECK(pending_stop_);
    121     pending_stop_ = false;
    122     is_initialized_ = false;
    123   }
    124 
    125   void ReadUntilPending() {
    126     do {
    127       frame_read_ = NULL;
    128       pending_read_ = true;
    129       video_frame_stream_->Read(base::Bind(
    130           &VideoFrameStreamTest::FrameReady, base::Unretained(this)));
    131       message_loop_.RunUntilIdle();
    132     } while (!pending_read_);
    133   }
    134 
    135   enum PendingState {
    136     NOT_PENDING,
    137     DEMUXER_READ_NORMAL,
    138     DEMUXER_READ_CONFIG_CHANGE,
    139     DECODER_INIT,
    140     DECODER_REINIT,
    141     DECODER_READ,
    142     DECODER_RESET,
    143     DECODER_STOP
    144   };
    145 
    146   void EnterPendingState(PendingState state) {
    147     DCHECK_NE(state, NOT_PENDING);
    148     switch (state) {
    149       case DEMUXER_READ_NORMAL:
    150         demuxer_stream_->HoldNextRead();
    151         ReadUntilPending();
    152         break;
    153 
    154       case DEMUXER_READ_CONFIG_CHANGE:
    155         demuxer_stream_->HoldNextConfigChangeRead();
    156         ReadUntilPending();
    157         break;
    158 
    159       case DECODER_INIT:
    160         decoder_->HoldNextInit();
    161         video_frame_stream_->Initialize(
    162             demuxer_stream_.get(),
    163             base::Bind(&VideoFrameStreamTest::OnStatistics,
    164                        base::Unretained(this)),
    165             base::Bind(&VideoFrameStreamTest::OnInitialized,
    166                        base::Unretained(this)));
    167         message_loop_.RunUntilIdle();
    168         break;
    169 
    170       case DECODER_REINIT:
    171         decoder_->HoldNextInit();
    172         ReadUntilPending();
    173         break;
    174 
    175       case DECODER_READ:
    176         decoder_->HoldNextRead();
    177         ReadUntilPending();
    178         break;
    179 
    180       case DECODER_RESET:
    181         decoder_->HoldNextReset();
    182         pending_reset_ = true;
    183         video_frame_stream_->Reset(base::Bind(&VideoFrameStreamTest::OnReset,
    184                                               base::Unretained(this)));
    185         message_loop_.RunUntilIdle();
    186         break;
    187 
    188       case DECODER_STOP:
    189         decoder_->HoldNextStop();
    190         pending_stop_ = true;
    191         video_frame_stream_->Stop(base::Bind(&VideoFrameStreamTest::OnStopped,
    192                                              base::Unretained(this)));
    193         message_loop_.RunUntilIdle();
    194         break;
    195 
    196       case NOT_PENDING:
    197         NOTREACHED();
    198         break;
    199     }
    200   }
    201 
    202   void SatisfyPendingCallback(PendingState state) {
    203     DCHECK_NE(state, NOT_PENDING);
    204     switch (state) {
    205       case DEMUXER_READ_NORMAL:
    206       case DEMUXER_READ_CONFIG_CHANGE:
    207         demuxer_stream_->SatisfyRead();
    208         break;
    209 
    210       case DECODER_INIT:
    211         EXPECT_CALL(*this, OnInitialized(true, false))
    212             .WillOnce(SaveArg<0>(&is_initialized_));
    213         decoder_->SatisfyInit();
    214         break;
    215 
    216       case DECODER_REINIT:
    217         decoder_->SatisfyInit();
    218         break;
    219 
    220       case DECODER_READ:
    221         DCHECK(pending_read_);
    222         decoder_->SatisfyRead();
    223         break;
    224 
    225       case DECODER_RESET:
    226         DCHECK(pending_reset_);
    227         decoder_->SatisfyReset();
    228         break;
    229 
    230       case DECODER_STOP:
    231         DCHECK(pending_stop_);
    232         decoder_->SatisfyStop();
    233         break;
    234 
    235       case NOT_PENDING:
    236         NOTREACHED();
    237         break;
    238     }
    239 
    240     message_loop_.RunUntilIdle();
    241     if (!is_initialized_)
    242       decoder_ = NULL;
    243   }
    244 
    245   void Initialize() {
    246     EnterPendingState(DECODER_INIT);
    247     SatisfyPendingCallback(DECODER_INIT);
    248   }
    249 
    250   void Read() {
    251     EnterPendingState(DECODER_READ);
    252     SatisfyPendingCallback(DECODER_READ);
    253   }
    254 
    255   void Reset() {
    256     EnterPendingState(DECODER_RESET);
    257     SatisfyPendingCallback(DECODER_RESET);
    258   }
    259 
    260   void Stop() {
    261     EnterPendingState(DECODER_STOP);
    262     SatisfyPendingCallback(DECODER_STOP);
    263   }
    264 
    265   base::MessageLoop message_loop_;
    266 
    267   scoped_ptr<VideoFrameStream> video_frame_stream_;
    268   scoped_ptr<FakeDemuxerStream> demuxer_stream_;
    269   // Use NiceMock since we don't care about most of calls on the decryptor,
    270   // e.g. RegisterNewKeyCB().
    271   scoped_ptr<NiceMock<MockDecryptor> > decryptor_;
    272   FakeVideoDecoder* decoder_;  // Owned by |video_frame_stream_|.
    273 
    274   bool is_initialized_;
    275   int num_decoded_frames_;
    276   bool pending_read_;
    277   bool pending_reset_;
    278   bool pending_stop_;
    279   int total_bytes_decoded_;
    280   scoped_refptr<VideoFrame> frame_read_;
    281 
    282  private:
    283   DISALLOW_COPY_AND_ASSIGN(VideoFrameStreamTest);
    284 };
    285 
    286 INSTANTIATE_TEST_CASE_P(Clear, VideoFrameStreamTest, testing::Values(false));
    287 INSTANTIATE_TEST_CASE_P(Encrypted, VideoFrameStreamTest, testing::Values(true));
    288 
    289 TEST_P(VideoFrameStreamTest, Initialization) {
    290   Initialize();
    291 }
    292 
    293 TEST_P(VideoFrameStreamTest, ReadOneFrame) {
    294   Initialize();
    295   Read();
    296 }
    297 
    298 TEST_P(VideoFrameStreamTest, ReadAllFrames) {
    299   Initialize();
    300   do {
    301     Read();
    302   } while (frame_read_.get() && !frame_read_->IsEndOfStream());
    303 
    304   const int total_num_frames = kNumConfigs * kNumBuffersInOneConfig;
    305   DCHECK_EQ(num_decoded_frames_, total_num_frames);
    306 }
    307 
    308 TEST_P(VideoFrameStreamTest, Read_AfterReset) {
    309   Initialize();
    310   Reset();
    311   Read();
    312   Reset();
    313   Read();
    314 }
    315 
    316 // No Reset() before initialization is successfully completed.
    317 
    318 TEST_P(VideoFrameStreamTest, Reset_AfterInitialization) {
    319   Initialize();
    320   Reset();
    321   Read();
    322 }
    323 
    324 TEST_P(VideoFrameStreamTest, Reset_DuringReinitialization) {
    325   Initialize();
    326   EnterPendingState(DECODER_REINIT);
    327   // VideoDecoder::Reset() is not called when we reset during reinitialization.
    328   pending_reset_ = true;
    329   video_frame_stream_->Reset(
    330       base::Bind(&VideoFrameStreamTest::OnReset, base::Unretained(this)));
    331   SatisfyPendingCallback(DECODER_REINIT);
    332   Read();
    333 }
    334 
    335 TEST_P(VideoFrameStreamTest, Reset_AfterReinitialization) {
    336   Initialize();
    337   EnterPendingState(DECODER_REINIT);
    338   SatisfyPendingCallback(DECODER_REINIT);
    339   Reset();
    340   Read();
    341 }
    342 
    343 TEST_P(VideoFrameStreamTest, Reset_DuringDemuxerRead_Normal) {
    344   Initialize();
    345   EnterPendingState(DEMUXER_READ_NORMAL);
    346   EnterPendingState(DECODER_RESET);
    347   SatisfyPendingCallback(DEMUXER_READ_NORMAL);
    348   SatisfyPendingCallback(DECODER_RESET);
    349   Read();
    350 }
    351 
    352 TEST_P(VideoFrameStreamTest, Reset_DuringDemuxerRead_ConfigChange) {
    353   Initialize();
    354   EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
    355   EnterPendingState(DECODER_RESET);
    356   SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
    357   SatisfyPendingCallback(DECODER_RESET);
    358   Read();
    359 }
    360 
    361 TEST_P(VideoFrameStreamTest, Reset_DuringNormalDecoderRead) {
    362   Initialize();
    363   EnterPendingState(DECODER_READ);
    364   EnterPendingState(DECODER_RESET);
    365   SatisfyPendingCallback(DECODER_READ);
    366   SatisfyPendingCallback(DECODER_RESET);
    367   Read();
    368 }
    369 
    370 TEST_P(VideoFrameStreamTest, Reset_AfterNormalRead) {
    371   Initialize();
    372   Read();
    373   Reset();
    374   Read();
    375 }
    376 
    377 TEST_P(VideoFrameStreamTest, Reset_AfterDemuxerRead_ConfigChange) {
    378   Initialize();
    379   EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
    380   SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
    381   Reset();
    382   Read();
    383 }
    384 
    385 TEST_P(VideoFrameStreamTest, Stop_BeforeInitialization) {
    386   pending_stop_ = true;
    387   video_frame_stream_->Stop(
    388       base::Bind(&VideoFrameStreamTest::OnStopped, base::Unretained(this)));
    389   message_loop_.RunUntilIdle();
    390 }
    391 
    392 TEST_P(VideoFrameStreamTest, Stop_DuringInitialization) {
    393   EnterPendingState(DECODER_INIT);
    394   EnterPendingState(DECODER_STOP);
    395   SatisfyPendingCallback(DECODER_INIT);
    396   SatisfyPendingCallback(DECODER_STOP);
    397 }
    398 
    399 TEST_P(VideoFrameStreamTest, Stop_AfterInitialization) {
    400   Initialize();
    401   Stop();
    402 }
    403 
    404 TEST_P(VideoFrameStreamTest, Stop_DuringReinitialization) {
    405   Initialize();
    406   EnterPendingState(DECODER_REINIT);
    407   EnterPendingState(DECODER_STOP);
    408   SatisfyPendingCallback(DECODER_REINIT);
    409   SatisfyPendingCallback(DECODER_STOP);
    410 }
    411 
    412 TEST_P(VideoFrameStreamTest, Stop_AfterReinitialization) {
    413   Initialize();
    414   EnterPendingState(DECODER_REINIT);
    415   SatisfyPendingCallback(DECODER_REINIT);
    416   Stop();
    417 }
    418 
    419 TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_Normal) {
    420   Initialize();
    421   EnterPendingState(DEMUXER_READ_NORMAL);
    422   EnterPendingState(DECODER_STOP);
    423   SatisfyPendingCallback(DEMUXER_READ_NORMAL);
    424   SatisfyPendingCallback(DECODER_STOP);
    425 }
    426 
    427 TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_ConfigChange) {
    428   Initialize();
    429   EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
    430   EnterPendingState(DECODER_STOP);
    431   SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
    432   SatisfyPendingCallback(DECODER_STOP);
    433 }
    434 
    435 TEST_P(VideoFrameStreamTest, Stop_DuringNormalDecoderRead) {
    436   Initialize();
    437   EnterPendingState(DECODER_READ);
    438   EnterPendingState(DECODER_STOP);
    439   SatisfyPendingCallback(DECODER_READ);
    440   SatisfyPendingCallback(DECODER_STOP);
    441 }
    442 
    443 TEST_P(VideoFrameStreamTest, Stop_AfterNormalRead) {
    444   Initialize();
    445   Read();
    446   Stop();
    447 }
    448 
    449 TEST_P(VideoFrameStreamTest, Stop_AfterConfigChangeRead) {
    450   Initialize();
    451   EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
    452   SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
    453   Stop();
    454 }
    455 
    456 TEST_P(VideoFrameStreamTest, Stop_DuringReset) {
    457   Initialize();
    458   EnterPendingState(DECODER_RESET);
    459   EnterPendingState(DECODER_STOP);
    460   SatisfyPendingCallback(DECODER_RESET);
    461   SatisfyPendingCallback(DECODER_STOP);
    462 }
    463 
    464 TEST_P(VideoFrameStreamTest, Stop_AfterReset) {
    465   Initialize();
    466   Reset();
    467   Stop();
    468 }
    469 
    470 TEST_P(VideoFrameStreamTest, Stop_DuringRead_DuringReset) {
    471   Initialize();
    472   EnterPendingState(DECODER_READ);
    473   EnterPendingState(DECODER_RESET);
    474   EnterPendingState(DECODER_STOP);
    475   SatisfyPendingCallback(DECODER_READ);
    476   SatisfyPendingCallback(DECODER_RESET);
    477   SatisfyPendingCallback(DECODER_STOP);
    478 }
    479 
    480 TEST_P(VideoFrameStreamTest, Stop_AfterRead_DuringReset) {
    481   Initialize();
    482   EnterPendingState(DECODER_READ);
    483   EnterPendingState(DECODER_RESET);
    484   SatisfyPendingCallback(DECODER_READ);
    485   EnterPendingState(DECODER_STOP);
    486   SatisfyPendingCallback(DECODER_RESET);
    487   SatisfyPendingCallback(DECODER_STOP);
    488 }
    489 
    490 TEST_P(VideoFrameStreamTest, Stop_AfterRead_AfterReset) {
    491   Initialize();
    492   Read();
    493   Reset();
    494   Stop();
    495 }
    496 
    497 }  // namespace media
    498