Home | History | Annotate | Download | only in filters
      1 // Copyright 2013 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/message_loop/message_loop.h"
      8 #include "media/base/decoder_buffer.h"
      9 #include "media/base/mock_filters.h"
     10 #include "media/base/test_helpers.h"
     11 #include "media/base/video_frame.h"
     12 #include "media/filters/fake_video_decoder.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 namespace media {
     16 
     17 static const int kDecodingDelay = 9;
     18 static const int kTotalBuffers = 12;
     19 static const int kDurationMs = 30;
     20 
     21 class FakeVideoDecoderTest : public testing::Test {
     22  public:
     23   FakeVideoDecoderTest()
     24       : decoder_(new FakeVideoDecoder(kDecodingDelay)),
     25         num_input_buffers_(0),
     26         num_decoded_frames_(0),
     27         decode_status_(VideoDecoder::kNotEnoughData),
     28         is_decode_pending_(false),
     29         is_reset_pending_(false),
     30         is_stop_pending_(false) {}
     31 
     32   virtual ~FakeVideoDecoderTest() {
     33     StopAndExpect(OK);
     34   }
     35 
     36   void InitializeWithConfig(const VideoDecoderConfig& config) {
     37     decoder_->Initialize(config, NewExpectedStatusCB(PIPELINE_OK));
     38     message_loop_.RunUntilIdle();
     39     current_config_ = config;
     40   }
     41 
     42   void Initialize() {
     43     InitializeWithConfig(TestVideoConfig::Normal());
     44   }
     45 
     46   void EnterPendingInitState() {
     47     decoder_->HoldNextInit();
     48     Initialize();
     49   }
     50 
     51   void SatisfyInit() {
     52     decoder_->SatisfyInit();
     53     message_loop_.RunUntilIdle();
     54   }
     55 
     56   // Callback for VideoDecoder::Read().
     57   void FrameReady(VideoDecoder::Status status,
     58                   const scoped_refptr<VideoFrame>& frame) {
     59     DCHECK(is_decode_pending_);
     60     ASSERT_TRUE(status == VideoDecoder::kOk ||
     61                 status == VideoDecoder::kNotEnoughData);
     62     is_decode_pending_ = false;
     63     decode_status_ = status;
     64     frame_decoded_ = frame;
     65 
     66     if (frame && !frame->IsEndOfStream())
     67       num_decoded_frames_++;
     68   }
     69 
     70   enum CallbackResult {
     71     PENDING,
     72     OK,
     73     NOT_ENOUGH_DATA,
     74     ABROTED,
     75     EOS
     76   };
     77 
     78   void ExpectReadResult(CallbackResult result) {
     79     switch (result) {
     80       case PENDING:
     81         EXPECT_TRUE(is_decode_pending_);
     82         ASSERT_FALSE(frame_decoded_);
     83         break;
     84       case OK:
     85         EXPECT_FALSE(is_decode_pending_);
     86         ASSERT_EQ(VideoDecoder::kOk, decode_status_);
     87         ASSERT_TRUE(frame_decoded_);
     88         EXPECT_FALSE(frame_decoded_->IsEndOfStream());
     89         break;
     90       case NOT_ENOUGH_DATA:
     91         EXPECT_FALSE(is_decode_pending_);
     92         ASSERT_EQ(VideoDecoder::kNotEnoughData, decode_status_);
     93         ASSERT_FALSE(frame_decoded_);
     94         break;
     95       case ABROTED:
     96         EXPECT_FALSE(is_decode_pending_);
     97         ASSERT_EQ(VideoDecoder::kOk, decode_status_);
     98         EXPECT_FALSE(frame_decoded_);
     99         break;
    100       case EOS:
    101         EXPECT_FALSE(is_decode_pending_);
    102         ASSERT_EQ(VideoDecoder::kOk, decode_status_);
    103         ASSERT_TRUE(frame_decoded_);
    104         EXPECT_TRUE(frame_decoded_->IsEndOfStream());
    105         break;
    106     }
    107   }
    108 
    109   void Decode() {
    110     scoped_refptr<DecoderBuffer> buffer;
    111 
    112     if (num_input_buffers_ < kTotalBuffers) {
    113       buffer = CreateFakeVideoBufferForTest(
    114           current_config_,
    115           base::TimeDelta::FromMilliseconds(kDurationMs * num_input_buffers_),
    116           base::TimeDelta::FromMilliseconds(kDurationMs));
    117       num_input_buffers_++;
    118     } else {
    119       buffer = DecoderBuffer::CreateEOSBuffer();
    120     }
    121 
    122     decode_status_ = VideoDecoder::kDecodeError;
    123     frame_decoded_ = NULL;
    124     is_decode_pending_ = true;
    125 
    126     decoder_->Decode(
    127         buffer,
    128         base::Bind(&FakeVideoDecoderTest::FrameReady, base::Unretained(this)));
    129     message_loop_.RunUntilIdle();
    130   }
    131 
    132   void ReadOneFrame() {
    133     do {
    134       Decode();
    135     } while (decode_status_ == VideoDecoder::kNotEnoughData &&
    136              !is_decode_pending_);
    137   }
    138 
    139   void ReadUntilEOS() {
    140     do {
    141       ReadOneFrame();
    142     } while (frame_decoded_ && !frame_decoded_->IsEndOfStream());
    143   }
    144 
    145   void EnterPendingReadState() {
    146     // Pass the initial NOT_ENOUGH_DATA stage.
    147     ReadOneFrame();
    148     decoder_->HoldNextRead();
    149     ReadOneFrame();
    150     ExpectReadResult(PENDING);
    151   }
    152 
    153   void SatisfyReadAndExpect(CallbackResult result) {
    154     decoder_->SatisfyRead();
    155     message_loop_.RunUntilIdle();
    156     ExpectReadResult(result);
    157   }
    158 
    159   void SatisfyRead() {
    160     SatisfyReadAndExpect(OK);
    161   }
    162 
    163   // Callback for VideoDecoder::Reset().
    164   void OnDecoderReset() {
    165     DCHECK(is_reset_pending_);
    166     is_reset_pending_ = false;
    167   }
    168 
    169   void ExpectResetResult(CallbackResult result) {
    170     switch (result) {
    171       case PENDING:
    172         EXPECT_TRUE(is_reset_pending_);
    173         break;
    174       case OK:
    175         EXPECT_FALSE(is_reset_pending_);
    176         break;
    177       default:
    178         NOTREACHED();
    179     }
    180   }
    181 
    182   void ResetAndExpect(CallbackResult result) {
    183     is_reset_pending_ = true;
    184     decoder_->Reset(base::Bind(&FakeVideoDecoderTest::OnDecoderReset,
    185                                base::Unretained(this)));
    186     message_loop_.RunUntilIdle();
    187     ExpectResetResult(result);
    188   }
    189 
    190   void EnterPendingResetState() {
    191     decoder_->HoldNextReset();
    192     ResetAndExpect(PENDING);
    193   }
    194 
    195   void SatisfyReset() {
    196     decoder_->SatisfyReset();
    197     message_loop_.RunUntilIdle();
    198     ExpectResetResult(OK);
    199   }
    200 
    201   // Callback for VideoDecoder::Stop().
    202   void OnDecoderStopped() {
    203     DCHECK(is_stop_pending_);
    204     is_stop_pending_ = false;
    205   }
    206 
    207   void ExpectStopResult(CallbackResult result) {
    208     switch (result) {
    209       case PENDING:
    210         EXPECT_TRUE(is_stop_pending_);
    211         break;
    212       case OK:
    213         EXPECT_FALSE(is_stop_pending_);
    214         break;
    215       default:
    216         NOTREACHED();
    217     }
    218   }
    219 
    220   void StopAndExpect(CallbackResult result) {
    221     is_stop_pending_ = true;
    222     decoder_->Stop(base::Bind(&FakeVideoDecoderTest::OnDecoderStopped,
    223                               base::Unretained(this)));
    224     message_loop_.RunUntilIdle();
    225     ExpectStopResult(result);
    226   }
    227 
    228   void EnterPendingStopState() {
    229     decoder_->HoldNextStop();
    230     StopAndExpect(PENDING);
    231   }
    232 
    233   void SatisfyStop() {
    234     decoder_->SatisfyStop();
    235     message_loop_.RunUntilIdle();
    236     ExpectStopResult(OK);
    237   }
    238 
    239   base::MessageLoop message_loop_;
    240   VideoDecoderConfig current_config_;
    241 
    242   scoped_ptr<FakeVideoDecoder> decoder_;
    243 
    244   int num_input_buffers_;
    245   int num_decoded_frames_;
    246 
    247   // Callback result/status.
    248   VideoDecoder::Status decode_status_;
    249   scoped_refptr<VideoFrame> frame_decoded_;
    250   bool is_decode_pending_;
    251   bool is_reset_pending_;
    252   bool is_stop_pending_;
    253 
    254  private:
    255   DISALLOW_COPY_AND_ASSIGN(FakeVideoDecoderTest);
    256 };
    257 
    258 TEST_F(FakeVideoDecoderTest, Initialize) {
    259   Initialize();
    260 }
    261 
    262 TEST_F(FakeVideoDecoderTest, Read_AllFrames) {
    263   Initialize();
    264   ReadUntilEOS();
    265   EXPECT_EQ(kTotalBuffers, num_decoded_frames_);
    266 }
    267 
    268 TEST_F(FakeVideoDecoderTest, Read_DecodingDelay) {
    269   Initialize();
    270 
    271   while (num_input_buffers_ < kTotalBuffers) {
    272     ReadOneFrame();
    273     EXPECT_EQ(num_input_buffers_, num_decoded_frames_ + kDecodingDelay);
    274   }
    275 }
    276 
    277 TEST_F(FakeVideoDecoderTest, Read_ZeroDelay) {
    278   decoder_.reset(new FakeVideoDecoder(0));
    279   Initialize();
    280 
    281   while (num_input_buffers_ < kTotalBuffers) {
    282     ReadOneFrame();
    283     EXPECT_EQ(num_input_buffers_, num_decoded_frames_);
    284   }
    285 }
    286 
    287 TEST_F(FakeVideoDecoderTest, Read_Pending_NotEnoughData) {
    288   Initialize();
    289   decoder_->HoldNextRead();
    290   ReadOneFrame();
    291   ExpectReadResult(PENDING);
    292   SatisfyReadAndExpect(NOT_ENOUGH_DATA);
    293 }
    294 
    295 TEST_F(FakeVideoDecoderTest, Read_Pending_OK) {
    296   Initialize();
    297   ReadOneFrame();
    298   EnterPendingReadState();
    299   SatisfyReadAndExpect(OK);
    300 }
    301 
    302 TEST_F(FakeVideoDecoderTest, Reinitialize) {
    303   Initialize();
    304   ReadOneFrame();
    305   InitializeWithConfig(TestVideoConfig::Large());
    306   ReadOneFrame();
    307 }
    308 
    309 // Reinitializing the decoder during the middle of the decoding process can
    310 // cause dropped frames.
    311 TEST_F(FakeVideoDecoderTest, Reinitialize_FrameDropped) {
    312   Initialize();
    313   ReadOneFrame();
    314   Initialize();
    315   ReadUntilEOS();
    316   EXPECT_LT(num_decoded_frames_, kTotalBuffers);
    317 }
    318 
    319 TEST_F(FakeVideoDecoderTest, Reset) {
    320   Initialize();
    321   ReadOneFrame();
    322   ResetAndExpect(OK);
    323 }
    324 
    325 TEST_F(FakeVideoDecoderTest, Reset_DuringPendingRead) {
    326   Initialize();
    327   EnterPendingReadState();
    328   ResetAndExpect(PENDING);
    329   SatisfyRead();
    330 }
    331 
    332 TEST_F(FakeVideoDecoderTest, Reset_Pending) {
    333   Initialize();
    334   EnterPendingResetState();
    335   SatisfyReset();
    336 }
    337 
    338 TEST_F(FakeVideoDecoderTest, Reset_PendingDuringPendingRead) {
    339   Initialize();
    340   EnterPendingReadState();
    341   EnterPendingResetState();
    342   SatisfyRead();
    343   SatisfyReset();
    344 }
    345 
    346 TEST_F(FakeVideoDecoderTest, Stop) {
    347   Initialize();
    348   ReadOneFrame();
    349   ExpectReadResult(OK);
    350   StopAndExpect(OK);
    351 }
    352 
    353 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingInitialization) {
    354   EnterPendingInitState();
    355   EnterPendingStopState();
    356   SatisfyInit();
    357   SatisfyStop();
    358 }
    359 
    360 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingRead) {
    361   Initialize();
    362   EnterPendingReadState();
    363   StopAndExpect(PENDING);
    364   SatisfyRead();
    365   ExpectStopResult(OK);
    366 }
    367 
    368 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingReset) {
    369   Initialize();
    370   EnterPendingResetState();
    371   StopAndExpect(PENDING);
    372   SatisfyReset();
    373   ExpectStopResult(OK);
    374 }
    375 
    376 TEST_F(FakeVideoDecoderTest, Stop_DuringPendingReadAndPendingReset) {
    377   Initialize();
    378   EnterPendingReadState();
    379   EnterPendingResetState();
    380   StopAndExpect(PENDING);
    381   SatisfyRead();
    382   SatisfyReset();
    383   ExpectStopResult(OK);
    384 }
    385 
    386 TEST_F(FakeVideoDecoderTest, Stop_Pending) {
    387   Initialize();
    388   decoder_->HoldNextStop();
    389   StopAndExpect(PENDING);
    390   decoder_->SatisfyStop();
    391   message_loop_.RunUntilIdle();
    392   ExpectStopResult(OK);
    393 }
    394 
    395 TEST_F(FakeVideoDecoderTest, Stop_PendingDuringPendingRead) {
    396   Initialize();
    397   EnterPendingReadState();
    398   EnterPendingStopState();
    399   SatisfyRead();
    400   SatisfyStop();
    401 }
    402 
    403 TEST_F(FakeVideoDecoderTest, Stop_PendingDuringPendingReset) {
    404   Initialize();
    405   EnterPendingResetState();
    406   EnterPendingStopState();
    407   SatisfyReset();
    408   SatisfyStop();
    409 }
    410 
    411 TEST_F(FakeVideoDecoderTest, Stop_PendingDuringPendingReadAndPendingReset) {
    412   Initialize();
    413   EnterPendingReadState();
    414   EnterPendingResetState();
    415   EnterPendingStopState();
    416   SatisfyRead();
    417   SatisfyReset();
    418   SatisfyStop();
    419 }
    420 
    421 }  // namespace media
    422