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 <utility>
      6 
      7 #include "base/bind.h"
      8 #include "base/callback.h"
      9 #include "base/callback_helpers.h"
     10 #include "base/debug/stack_trace.h"
     11 #include "base/message_loop/message_loop.h"
     12 #include "base/stl_util.h"
     13 #include "base/strings/stringprintf.h"
     14 #include "base/synchronization/lock.h"
     15 #include "base/timer/timer.h"
     16 #include "media/base/data_buffer.h"
     17 #include "media/base/gmock_callback_support.h"
     18 #include "media/base/limits.h"
     19 #include "media/base/mock_filters.h"
     20 #include "media/base/test_helpers.h"
     21 #include "media/base/video_frame.h"
     22 #include "media/filters/video_renderer_base.h"
     23 #include "testing/gtest/include/gtest/gtest.h"
     24 
     25 using ::testing::_;
     26 using ::testing::AnyNumber;
     27 using ::testing::InSequence;
     28 using ::testing::Invoke;
     29 using ::testing::NiceMock;
     30 using ::testing::NotNull;
     31 using ::testing::Return;
     32 using ::testing::StrictMock;
     33 
     34 namespace media {
     35 
     36 static const int kFrameDurationInMs = 10;
     37 static const int kVideoDurationInMs = kFrameDurationInMs * 100;
     38 
     39 class VideoRendererBaseTest : public ::testing::Test {
     40  public:
     41   VideoRendererBaseTest()
     42       : decoder_(new MockVideoDecoder()),
     43         demuxer_stream_(DemuxerStream::VIDEO) {
     44     ScopedVector<VideoDecoder> decoders;
     45     decoders.push_back(decoder_);
     46 
     47     renderer_.reset(new VideoRendererBase(
     48         message_loop_.message_loop_proxy(),
     49         decoders.Pass(),
     50         media::SetDecryptorReadyCB(),
     51         base::Bind(&VideoRendererBaseTest::OnPaint, base::Unretained(this)),
     52         base::Bind(&VideoRendererBaseTest::OnSetOpaque, base::Unretained(this)),
     53         true));
     54 
     55     demuxer_stream_.set_video_decoder_config(TestVideoConfig::Normal());
     56 
     57     // We expect these to be called but we don't care how/when.
     58     EXPECT_CALL(demuxer_stream_, Read(_))
     59         .WillRepeatedly(RunCallback<0>(DemuxerStream::kOk,
     60                                        DecoderBuffer::CreateEOSBuffer()));
     61     EXPECT_CALL(*decoder_, Stop(_))
     62         .WillRepeatedly(Invoke(this, &VideoRendererBaseTest::StopRequested));
     63     EXPECT_CALL(statistics_cb_object_, OnStatistics(_))
     64         .Times(AnyNumber());
     65     EXPECT_CALL(*this, OnTimeUpdate(_))
     66         .Times(AnyNumber());
     67     EXPECT_CALL(*this, OnSetOpaque(_))
     68         .Times(AnyNumber());
     69   }
     70 
     71   virtual ~VideoRendererBaseTest() {}
     72 
     73   // Callbacks passed into VideoRendererBase().
     74   MOCK_CONST_METHOD1(OnSetOpaque, void(bool));
     75 
     76   // Callbacks passed into Initialize().
     77   MOCK_METHOD1(OnTimeUpdate, void(base::TimeDelta));
     78   MOCK_METHOD1(OnNaturalSizeChanged, void(const gfx::Size&));
     79 
     80   void Initialize() {
     81     InitializeWithDuration(kVideoDurationInMs);
     82   }
     83 
     84   void InitializeWithDuration(int duration_ms) {
     85     duration_ = base::TimeDelta::FromMilliseconds(duration_ms);
     86 
     87     // Monitor decodes from the decoder.
     88     EXPECT_CALL(*decoder_, Decode(_, _))
     89         .WillRepeatedly(Invoke(this, &VideoRendererBaseTest::FrameRequested));
     90 
     91     EXPECT_CALL(*decoder_, Reset(_))
     92         .WillRepeatedly(Invoke(this, &VideoRendererBaseTest::FlushRequested));
     93 
     94     InSequence s;
     95 
     96     EXPECT_CALL(*decoder_, Initialize(_, _))
     97         .WillOnce(RunCallback<1>(PIPELINE_OK));
     98 
     99     // Set playback rate before anything else happens.
    100     renderer_->SetPlaybackRate(1.0f);
    101 
    102     // Initialize, we shouldn't have any reads.
    103     InitializeRenderer(PIPELINE_OK);
    104 
    105     // We expect the video size to be set.
    106     EXPECT_CALL(*this,
    107                 OnNaturalSizeChanged(TestVideoConfig::NormalCodedSize()));
    108 
    109     // Start prerolling.
    110     QueuePrerollFrames(0);
    111     Preroll(0, PIPELINE_OK);
    112   }
    113 
    114   void InitializeRenderer(PipelineStatus expected) {
    115     SCOPED_TRACE(base::StringPrintf("InitializeRenderer(%d)", expected));
    116     WaitableMessageLoopEvent event;
    117     CallInitialize(event.GetPipelineStatusCB());
    118     event.RunAndWaitForStatus(expected);
    119   }
    120 
    121   void CallInitialize(const PipelineStatusCB& status_cb) {
    122     renderer_->Initialize(
    123         &demuxer_stream_,
    124         status_cb,
    125         base::Bind(&MockStatisticsCB::OnStatistics,
    126                    base::Unretained(&statistics_cb_object_)),
    127         base::Bind(&VideoRendererBaseTest::OnTimeUpdate,
    128                    base::Unretained(this)),
    129         base::Bind(&VideoRendererBaseTest::OnNaturalSizeChanged,
    130                    base::Unretained(this)),
    131         ended_event_.GetClosure(),
    132         error_event_.GetPipelineStatusCB(),
    133         base::Bind(&VideoRendererBaseTest::GetTime, base::Unretained(this)),
    134         base::Bind(&VideoRendererBaseTest::GetDuration,
    135                    base::Unretained(this)));
    136   }
    137 
    138   void Play() {
    139     SCOPED_TRACE("Play()");
    140     WaitableMessageLoopEvent event;
    141     renderer_->Play(event.GetClosure());
    142     event.RunAndWait();
    143   }
    144 
    145   void Preroll(int timestamp_ms, PipelineStatus expected) {
    146     SCOPED_TRACE(base::StringPrintf("Preroll(%d, %d)", timestamp_ms, expected));
    147     WaitableMessageLoopEvent event;
    148     renderer_->Preroll(
    149         base::TimeDelta::FromMilliseconds(timestamp_ms),
    150         event.GetPipelineStatusCB());
    151     event.RunAndWaitForStatus(expected);
    152   }
    153 
    154   void Pause() {
    155     SCOPED_TRACE("Pause()");
    156     WaitableMessageLoopEvent event;
    157     renderer_->Pause(event.GetClosure());
    158     event.RunAndWait();
    159   }
    160 
    161   void Flush() {
    162     SCOPED_TRACE("Flush()");
    163     WaitableMessageLoopEvent event;
    164     renderer_->Flush(event.GetClosure());
    165     event.RunAndWait();
    166   }
    167 
    168   void Stop() {
    169     SCOPED_TRACE("Stop()");
    170     WaitableMessageLoopEvent event;
    171     renderer_->Stop(event.GetClosure());
    172     event.RunAndWait();
    173   }
    174 
    175   void Shutdown() {
    176     Pause();
    177     Flush();
    178     Stop();
    179   }
    180 
    181   // Queues a VideoFrame with |next_frame_timestamp_|.
    182   void QueueNextFrame() {
    183     DCHECK_EQ(&message_loop_, base::MessageLoop::current());
    184     DCHECK_LT(next_frame_timestamp_.InMicroseconds(),
    185               duration_.InMicroseconds());
    186 
    187     gfx::Size natural_size = TestVideoConfig::NormalCodedSize();
    188     scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame(
    189         VideoFrame::RGB32, natural_size, gfx::Rect(natural_size), natural_size,
    190         next_frame_timestamp_);
    191     decode_results_.push_back(std::make_pair(
    192         VideoDecoder::kOk, frame));
    193     next_frame_timestamp_ +=
    194         base::TimeDelta::FromMilliseconds(kFrameDurationInMs);
    195   }
    196 
    197   void QueueEndOfStream() {
    198     DCHECK_EQ(&message_loop_, base::MessageLoop::current());
    199     decode_results_.push_back(std::make_pair(
    200         VideoDecoder::kOk, VideoFrame::CreateEmptyFrame()));
    201   }
    202 
    203   void QueueDecodeError() {
    204     DCHECK_EQ(&message_loop_, base::MessageLoop::current());
    205     scoped_refptr<VideoFrame> null_frame;
    206     decode_results_.push_back(std::make_pair(
    207         VideoDecoder::kDecodeError, null_frame));
    208   }
    209 
    210   void QueueAbortedRead() {
    211     DCHECK_EQ(&message_loop_, base::MessageLoop::current());
    212     scoped_refptr<VideoFrame> null_frame;
    213     decode_results_.push_back(std::make_pair(
    214         VideoDecoder::kOk, null_frame));
    215   }
    216 
    217   void QueuePrerollFrames(int timestamp_ms) {
    218     DCHECK_EQ(&message_loop_, base::MessageLoop::current());
    219     next_frame_timestamp_ = base::TimeDelta();
    220     base::TimeDelta timestamp = base::TimeDelta::FromMilliseconds(timestamp_ms);
    221     while (next_frame_timestamp_ < timestamp) {
    222       QueueNextFrame();
    223     }
    224 
    225     // Queue the frame at |timestamp| plus additional ones for prerolling.
    226     for (int i = 0; i < limits::kMaxVideoFrames; ++i) {
    227       QueueNextFrame();
    228     }
    229   }
    230 
    231   void ResetCurrentFrame() {
    232     base::AutoLock l(lock_);
    233     current_frame_ = NULL;
    234   }
    235 
    236   scoped_refptr<VideoFrame> GetCurrentFrame() {
    237     base::AutoLock l(lock_);
    238     return current_frame_;
    239   }
    240 
    241   int GetCurrentTimestampInMs() {
    242     scoped_refptr<VideoFrame> frame = GetCurrentFrame();
    243     if (!frame.get())
    244       return -1;
    245     return frame->GetTimestamp().InMilliseconds();
    246   }
    247 
    248   void WaitForError(PipelineStatus expected) {
    249     SCOPED_TRACE(base::StringPrintf("WaitForError(%d)", expected));
    250     error_event_.RunAndWaitForStatus(expected);
    251   }
    252 
    253   void WaitForEnded() {
    254     SCOPED_TRACE("WaitForEnded()");
    255     ended_event_.RunAndWait();
    256   }
    257 
    258   void WaitForPendingRead() {
    259     SCOPED_TRACE("WaitForPendingRead()");
    260     if (!read_cb_.is_null())
    261       return;
    262 
    263     DCHECK(wait_for_pending_read_cb_.is_null());
    264 
    265     WaitableMessageLoopEvent event;
    266     wait_for_pending_read_cb_ = event.GetClosure();
    267     event.RunAndWait();
    268 
    269     DCHECK(!read_cb_.is_null());
    270     DCHECK(wait_for_pending_read_cb_.is_null());
    271   }
    272 
    273   void SatisfyPendingRead() {
    274     CHECK(!read_cb_.is_null());
    275     CHECK(!decode_results_.empty());
    276 
    277     base::Closure closure = base::Bind(
    278         read_cb_, decode_results_.front().first,
    279         decode_results_.front().second);
    280 
    281     read_cb_.Reset();
    282     decode_results_.pop_front();
    283 
    284     message_loop_.PostTask(FROM_HERE, closure);
    285   }
    286 
    287   void AdvanceTimeInMs(int time_ms) {
    288     DCHECK_EQ(&message_loop_, base::MessageLoop::current());
    289     base::AutoLock l(lock_);
    290     time_ += base::TimeDelta::FromMilliseconds(time_ms);
    291     DCHECK_LE(time_.InMicroseconds(), duration_.InMicroseconds());
    292   }
    293 
    294  protected:
    295   // Fixture members.
    296   scoped_ptr<VideoRendererBase> renderer_;
    297   MockVideoDecoder* decoder_;  // Owned by |renderer_|.
    298   NiceMock<MockDemuxerStream> demuxer_stream_;
    299   MockStatisticsCB statistics_cb_object_;
    300 
    301  private:
    302   base::TimeDelta GetTime() {
    303     base::AutoLock l(lock_);
    304     return time_;
    305   }
    306 
    307   base::TimeDelta GetDuration() {
    308     return duration_;
    309   }
    310 
    311   void OnPaint(const scoped_refptr<VideoFrame>& frame) {
    312     base::AutoLock l(lock_);
    313     current_frame_ = frame;
    314   }
    315 
    316   void FrameRequested(const scoped_refptr<DecoderBuffer>& buffer,
    317                       const VideoDecoder::DecodeCB& read_cb) {
    318     DCHECK_EQ(&message_loop_, base::MessageLoop::current());
    319     CHECK(read_cb_.is_null());
    320     read_cb_ = read_cb;
    321 
    322     // Wake up WaitForPendingRead() if needed.
    323     if (!wait_for_pending_read_cb_.is_null())
    324       base::ResetAndReturn(&wait_for_pending_read_cb_).Run();
    325 
    326     if (decode_results_.empty())
    327       return;
    328 
    329     SatisfyPendingRead();
    330   }
    331 
    332   void FlushRequested(const base::Closure& callback) {
    333     DCHECK_EQ(&message_loop_, base::MessageLoop::current());
    334     decode_results_.clear();
    335     if (!read_cb_.is_null()) {
    336       QueueAbortedRead();
    337       SatisfyPendingRead();
    338     }
    339 
    340     message_loop_.PostTask(FROM_HERE, callback);
    341   }
    342 
    343   void StopRequested(const base::Closure& callback) {
    344     DCHECK_EQ(&message_loop_, base::MessageLoop::current());
    345     decode_results_.clear();
    346     if (!read_cb_.is_null()) {
    347       QueueAbortedRead();
    348       SatisfyPendingRead();
    349     }
    350 
    351     message_loop_.PostTask(FROM_HERE, callback);
    352   }
    353 
    354   base::MessageLoop message_loop_;
    355 
    356   // Used to protect |time_| and |current_frame_|.
    357   base::Lock lock_;
    358   base::TimeDelta time_;
    359   scoped_refptr<VideoFrame> current_frame_;
    360 
    361   // Used for satisfying reads.
    362   VideoDecoder::DecodeCB read_cb_;
    363   base::TimeDelta next_frame_timestamp_;
    364   base::TimeDelta duration_;
    365 
    366   WaitableMessageLoopEvent error_event_;
    367   WaitableMessageLoopEvent ended_event_;
    368 
    369   // Run during FrameRequested() to unblock WaitForPendingRead().
    370   base::Closure wait_for_pending_read_cb_;
    371 
    372   std::deque<std::pair<
    373       VideoDecoder::Status, scoped_refptr<VideoFrame> > > decode_results_;
    374 
    375   DISALLOW_COPY_AND_ASSIGN(VideoRendererBaseTest);
    376 };
    377 
    378 TEST_F(VideoRendererBaseTest, DoNothing) {
    379   // Test that creation and deletion doesn't depend on calls to Initialize()
    380   // and/or Stop().
    381 }
    382 
    383 TEST_F(VideoRendererBaseTest, StopWithoutInitialize) {
    384   Stop();
    385 }
    386 
    387 TEST_F(VideoRendererBaseTest, Initialize) {
    388   Initialize();
    389   EXPECT_EQ(0, GetCurrentTimestampInMs());
    390   Shutdown();
    391 }
    392 
    393 static void ExpectNotCalled(PipelineStatus) {
    394   base::debug::StackTrace stack;
    395   ADD_FAILURE() << "Expected callback not to be called\n" << stack.ToString();
    396 }
    397 
    398 TEST_F(VideoRendererBaseTest, StopWhileInitializing) {
    399   EXPECT_CALL(*decoder_, Initialize(_, _))
    400       .WillOnce(RunCallback<1>(PIPELINE_OK));
    401   CallInitialize(base::Bind(&ExpectNotCalled));
    402   Stop();
    403 
    404   // ~VideoRendererBase() will CHECK() if we left anything initialized.
    405 }
    406 
    407 TEST_F(VideoRendererBaseTest, StopWhileFlushing) {
    408   Initialize();
    409   Pause();
    410   renderer_->Flush(base::Bind(&ExpectNotCalled, PIPELINE_OK));
    411   Stop();
    412 
    413   // ~VideoRendererBase() will CHECK() if we left anything initialized.
    414 }
    415 
    416 TEST_F(VideoRendererBaseTest, Play) {
    417   Initialize();
    418   Play();
    419   Shutdown();
    420 }
    421 
    422 TEST_F(VideoRendererBaseTest, EndOfStream_DefaultFrameDuration) {
    423   Initialize();
    424   Play();
    425 
    426   // Verify that the ended callback fires when the default last frame duration
    427   // has elapsed.
    428   int end_timestamp = kFrameDurationInMs * limits::kMaxVideoFrames +
    429       VideoRendererBase::kMaxLastFrameDuration().InMilliseconds();
    430   EXPECT_LT(end_timestamp, kVideoDurationInMs);
    431 
    432   QueueEndOfStream();
    433   AdvanceTimeInMs(end_timestamp);
    434   WaitForEnded();
    435 
    436   Shutdown();
    437 }
    438 
    439 TEST_F(VideoRendererBaseTest, EndOfStream_ClipDuration) {
    440   int duration = kVideoDurationInMs + kFrameDurationInMs / 2;
    441   InitializeWithDuration(duration);
    442   Play();
    443 
    444   // Render all frames except for the last |limits::kMaxVideoFrames| frames
    445   // and deliver all the frames between the start and |duration|. The preroll
    446   // inside Initialize() makes this a little confusing, but |timestamp| is
    447   // the current render time and QueueNextFrame() delivers a frame with a
    448   // timestamp that is |timestamp| + limits::kMaxVideoFrames *
    449   // kFrameDurationInMs.
    450   int timestamp = kFrameDurationInMs;
    451   int end_timestamp = duration - limits::kMaxVideoFrames * kFrameDurationInMs;
    452   for (; timestamp < end_timestamp; timestamp += kFrameDurationInMs) {
    453     QueueNextFrame();
    454   }
    455 
    456   // Queue the end of stream frame and wait for the last frame to be rendered.
    457   QueueEndOfStream();
    458   AdvanceTimeInMs(duration);
    459   WaitForEnded();
    460 
    461   Shutdown();
    462 }
    463 
    464 TEST_F(VideoRendererBaseTest, DecodeError_Playing) {
    465   Initialize();
    466   Play();
    467 
    468   QueueDecodeError();
    469   AdvanceTimeInMs(kVideoDurationInMs);
    470   WaitForError(PIPELINE_ERROR_DECODE);
    471   Shutdown();
    472 }
    473 
    474 TEST_F(VideoRendererBaseTest, DecodeError_DuringPreroll) {
    475   Initialize();
    476   Pause();
    477   Flush();
    478 
    479   QueueDecodeError();
    480   Preroll(kFrameDurationInMs * 6, PIPELINE_ERROR_DECODE);
    481   Shutdown();
    482 }
    483 
    484 TEST_F(VideoRendererBaseTest, Preroll_Exact) {
    485   Initialize();
    486   Pause();
    487   Flush();
    488   QueuePrerollFrames(kFrameDurationInMs * 6);
    489 
    490   Preroll(kFrameDurationInMs * 6, PIPELINE_OK);
    491   EXPECT_EQ(kFrameDurationInMs * 6, GetCurrentTimestampInMs());
    492   Shutdown();
    493 }
    494 
    495 TEST_F(VideoRendererBaseTest, Preroll_RightBefore) {
    496   Initialize();
    497   Pause();
    498   Flush();
    499   QueuePrerollFrames(kFrameDurationInMs * 6);
    500 
    501   Preroll(kFrameDurationInMs * 6 - 1, PIPELINE_OK);
    502   EXPECT_EQ(kFrameDurationInMs * 5, GetCurrentTimestampInMs());
    503   Shutdown();
    504 }
    505 
    506 TEST_F(VideoRendererBaseTest, Preroll_RightAfter) {
    507   Initialize();
    508   Pause();
    509   Flush();
    510   QueuePrerollFrames(kFrameDurationInMs * 6);
    511 
    512   Preroll(kFrameDurationInMs * 6 + 1, PIPELINE_OK);
    513   EXPECT_EQ(kFrameDurationInMs * 6, GetCurrentTimestampInMs());
    514   Shutdown();
    515 }
    516 
    517 TEST_F(VideoRendererBaseTest, PlayAfterPreroll) {
    518   Initialize();
    519   Pause();
    520   Flush();
    521   QueuePrerollFrames(kFrameDurationInMs * 4);
    522 
    523   Preroll(kFrameDurationInMs * 4, PIPELINE_OK);
    524   EXPECT_EQ(kFrameDurationInMs * 4, GetCurrentTimestampInMs());
    525 
    526   Play();
    527   // Advance time past prerolled time to trigger a Read().
    528   AdvanceTimeInMs(5 * kFrameDurationInMs);
    529   WaitForPendingRead();
    530   Shutdown();
    531 }
    532 
    533 TEST_F(VideoRendererBaseTest, GetCurrentFrame_Initialized) {
    534   Initialize();
    535   EXPECT_TRUE(GetCurrentFrame().get());  // Due to prerolling.
    536   Shutdown();
    537 }
    538 
    539 TEST_F(VideoRendererBaseTest, GetCurrentFrame_Playing) {
    540   Initialize();
    541   Play();
    542   EXPECT_TRUE(GetCurrentFrame().get());
    543   Shutdown();
    544 }
    545 
    546 TEST_F(VideoRendererBaseTest, GetCurrentFrame_Paused) {
    547   Initialize();
    548   Play();
    549   Pause();
    550   EXPECT_TRUE(GetCurrentFrame().get());
    551   Shutdown();
    552 }
    553 
    554 TEST_F(VideoRendererBaseTest, GetCurrentFrame_Flushed) {
    555   Initialize();
    556   Play();
    557   Pause();
    558 
    559   // Frame shouldn't be updated.
    560   ResetCurrentFrame();
    561   Flush();
    562   EXPECT_FALSE(GetCurrentFrame().get());
    563 
    564   Shutdown();
    565 }
    566 
    567 TEST_F(VideoRendererBaseTest, GetCurrentFrame_EndOfStream) {
    568   Initialize();
    569   Play();
    570   Pause();
    571   Flush();
    572 
    573   // Preroll only end of stream frames.
    574   QueueEndOfStream();
    575 
    576   // Frame shouldn't be updated.
    577   ResetCurrentFrame();
    578   Preroll(0, PIPELINE_OK);
    579   EXPECT_FALSE(GetCurrentFrame().get());
    580 
    581   // Start playing, we should immediately get notified of end of stream.
    582   Play();
    583   WaitForEnded();
    584 
    585   Shutdown();
    586 }
    587 
    588 TEST_F(VideoRendererBaseTest, GetCurrentFrame_Shutdown) {
    589   Initialize();
    590 
    591   // Frame shouldn't be updated.
    592   ResetCurrentFrame();
    593   Shutdown();
    594   EXPECT_FALSE(GetCurrentFrame().get());
    595 }
    596 
    597 // Stop() is called immediately during an error.
    598 TEST_F(VideoRendererBaseTest, GetCurrentFrame_Error) {
    599   Initialize();
    600 
    601   // Frame shouldn't be updated.
    602   ResetCurrentFrame();
    603   Stop();
    604   EXPECT_FALSE(GetCurrentFrame().get());
    605 }
    606 
    607 // Verify that a late decoder response doesn't break invariants in the renderer.
    608 TEST_F(VideoRendererBaseTest, StopDuringOutstandingRead) {
    609   Initialize();
    610   Play();
    611 
    612   // Advance time a bit to trigger a Read().
    613   AdvanceTimeInMs(kFrameDurationInMs);
    614   WaitForPendingRead();
    615 
    616   WaitableMessageLoopEvent event;
    617   renderer_->Stop(event.GetClosure());
    618 
    619   event.RunAndWait();
    620 }
    621 
    622 TEST_F(VideoRendererBaseTest, AbortPendingRead_Playing) {
    623   Initialize();
    624   Play();
    625 
    626   // Advance time a bit to trigger a Read().
    627   AdvanceTimeInMs(kFrameDurationInMs);
    628   WaitForPendingRead();
    629 
    630   QueueAbortedRead();
    631   SatisfyPendingRead();
    632 
    633   Pause();
    634   Flush();
    635   QueuePrerollFrames(kFrameDurationInMs * 6);
    636   Preroll(kFrameDurationInMs * 6, PIPELINE_OK);
    637   EXPECT_EQ(kFrameDurationInMs * 6, GetCurrentTimestampInMs());
    638   Shutdown();
    639 }
    640 
    641 TEST_F(VideoRendererBaseTest, AbortPendingRead_Flush) {
    642   Initialize();
    643   Play();
    644 
    645   // Advance time a bit to trigger a Read().
    646   AdvanceTimeInMs(kFrameDurationInMs);
    647   WaitForPendingRead();
    648 
    649   Pause();
    650   Flush();
    651   Shutdown();
    652 }
    653 
    654 TEST_F(VideoRendererBaseTest, AbortPendingRead_Preroll) {
    655   Initialize();
    656   Pause();
    657   Flush();
    658 
    659   QueueAbortedRead();
    660   Preroll(kFrameDurationInMs * 6, PIPELINE_OK);
    661   Shutdown();
    662 }
    663 
    664 TEST_F(VideoRendererBaseTest, VideoDecoder_InitFailure) {
    665   InSequence s;
    666 
    667   EXPECT_CALL(*decoder_, Initialize(_, _))
    668       .WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED));
    669   InitializeRenderer(DECODER_ERROR_NOT_SUPPORTED);
    670 
    671   Stop();
    672 }
    673 
    674 }  // namespace media
    675