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 <vector>
      6 
      7 #include "base/bind.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "base/stl_util.h"
     10 #include "base/test/simple_test_tick_clock.h"
     11 #include "base/threading/simple_thread.h"
     12 #include "base/time/clock.h"
     13 #include "media/base/clock.h"
     14 #include "media/base/fake_text_track_stream.h"
     15 #include "media/base/gmock_callback_support.h"
     16 #include "media/base/media_log.h"
     17 #include "media/base/mock_filters.h"
     18 #include "media/base/pipeline.h"
     19 #include "media/base/test_helpers.h"
     20 #include "media/base/text_renderer.h"
     21 #include "media/base/text_track_config.h"
     22 #include "testing/gtest/include/gtest/gtest.h"
     23 #include "ui/gfx/size.h"
     24 
     25 using ::testing::_;
     26 using ::testing::DeleteArg;
     27 using ::testing::DoAll;
     28 // TODO(scherkus): Remove InSequence after refactoring Pipeline.
     29 using ::testing::InSequence;
     30 using ::testing::Invoke;
     31 using ::testing::InvokeWithoutArgs;
     32 using ::testing::Mock;
     33 using ::testing::NotNull;
     34 using ::testing::Return;
     35 using ::testing::SaveArg;
     36 using ::testing::StrictMock;
     37 using ::testing::WithArg;
     38 
     39 namespace media {
     40 
     41 // Demuxer properties.
     42 const int kTotalBytes = 1024;
     43 
     44 ACTION_P(SetDemuxerProperties, duration) {
     45   arg0->SetTotalBytes(kTotalBytes);
     46   arg0->SetDuration(duration);
     47 }
     48 
     49 ACTION_P2(Stop, pipeline, stop_cb) {
     50   pipeline->Stop(stop_cb);
     51 }
     52 
     53 ACTION_P2(SetError, pipeline, status) {
     54   pipeline->SetErrorForTesting(status);
     55 }
     56 
     57 // Used for setting expectations on pipeline callbacks.  Using a StrictMock
     58 // also lets us test for missing callbacks.
     59 class CallbackHelper {
     60  public:
     61   CallbackHelper() {}
     62   virtual ~CallbackHelper() {}
     63 
     64   MOCK_METHOD1(OnStart, void(PipelineStatus));
     65   MOCK_METHOD1(OnSeek, void(PipelineStatus));
     66   MOCK_METHOD0(OnStop, void());
     67   MOCK_METHOD0(OnEnded, void());
     68   MOCK_METHOD1(OnError, void(PipelineStatus));
     69   MOCK_METHOD1(OnBufferingState, void(Pipeline::BufferingState));
     70   MOCK_METHOD0(OnDurationChange, void());
     71 
     72  private:
     73   DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
     74 };
     75 
     76 // TODO(scherkus): even though some filters are initialized on separate
     77 // threads these test aren't flaky... why?  It's because filters' Initialize()
     78 // is executed on |message_loop_| and the mock filters instantly call
     79 // InitializationComplete(), which keeps the pipeline humming along.  If
     80 // either filters don't call InitializationComplete() immediately or filter
     81 // initialization is moved to a separate thread this test will become flaky.
     82 class PipelineTest : public ::testing::Test {
     83  public:
     84   PipelineTest()
     85       : pipeline_(new Pipeline(message_loop_.message_loop_proxy(),
     86                                new MediaLog())),
     87         filter_collection_(new FilterCollection()),
     88         demuxer_(new MockDemuxer()) {
     89     filter_collection_->SetDemuxer(demuxer_.get());
     90 
     91     video_renderer_ = new MockVideoRenderer();
     92     scoped_ptr<VideoRenderer> video_renderer(video_renderer_);
     93     filter_collection_->SetVideoRenderer(video_renderer.Pass());
     94 
     95     audio_renderer_ = new MockAudioRenderer();
     96     scoped_ptr<AudioRenderer> audio_renderer(audio_renderer_);
     97     filter_collection_->SetAudioRenderer(audio_renderer.Pass());
     98 
     99     text_renderer_ = new TextRenderer(
    100                          message_loop_.message_loop_proxy(),
    101                          base::Bind(&PipelineTest::OnAddTextTrack,
    102                                     base::Unretained(this)));
    103     scoped_ptr<TextRenderer> text_renderer(text_renderer_);
    104     filter_collection_->SetTextRenderer(text_renderer.Pass());
    105 
    106     // InitializeDemuxer() adds overriding expectations for expected non-NULL
    107     // streams.
    108     DemuxerStream* null_pointer = NULL;
    109     EXPECT_CALL(*demuxer_, GetStream(_))
    110         .WillRepeatedly(Return(null_pointer));
    111 
    112     EXPECT_CALL(*demuxer_, GetStartTime())
    113         .WillRepeatedly(Return(base::TimeDelta()));
    114   }
    115 
    116   virtual ~PipelineTest() {
    117     if (!pipeline_ || !pipeline_->IsRunning())
    118       return;
    119 
    120     ExpectStop();
    121 
    122     // The mock demuxer doesn't stop the fake text track stream,
    123     // so just stop it manually.
    124     if (text_stream_) {
    125       text_stream_->Stop();
    126       message_loop_.RunUntilIdle();
    127     }
    128 
    129     // Expect a stop callback if we were started.
    130     EXPECT_CALL(callbacks_, OnStop());
    131     pipeline_->Stop(base::Bind(&CallbackHelper::OnStop,
    132                                base::Unretained(&callbacks_)));
    133     message_loop_.RunUntilIdle();
    134   }
    135 
    136  protected:
    137   // Sets up expectations to allow the demuxer to initialize.
    138   typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector;
    139   void InitializeDemuxer(MockDemuxerStreamVector* streams,
    140                          const base::TimeDelta& duration) {
    141     EXPECT_CALL(callbacks_, OnDurationChange());
    142     EXPECT_CALL(*demuxer_, Initialize(_, _, _))
    143         .WillOnce(DoAll(SetDemuxerProperties(duration),
    144                         RunCallback<1>(PIPELINE_OK)));
    145 
    146     // Configure the demuxer to return the streams.
    147     for (size_t i = 0; i < streams->size(); ++i) {
    148       DemuxerStream* stream = (*streams)[i];
    149       EXPECT_CALL(*demuxer_, GetStream(stream->type()))
    150           .WillRepeatedly(Return(stream));
    151     }
    152   }
    153 
    154   void InitializeDemuxer(MockDemuxerStreamVector* streams) {
    155     // Initialize with a default non-zero duration.
    156     InitializeDemuxer(streams, base::TimeDelta::FromSeconds(10));
    157   }
    158 
    159   scoped_ptr<StrictMock<MockDemuxerStream> > CreateStream(
    160       DemuxerStream::Type type) {
    161     scoped_ptr<StrictMock<MockDemuxerStream> > stream(
    162         new StrictMock<MockDemuxerStream>(type));
    163     return stream.Pass();
    164   }
    165 
    166   // Sets up expectations to allow the video renderer to initialize.
    167   void InitializeVideoRenderer(DemuxerStream* stream) {
    168     EXPECT_CALL(*video_renderer_, Initialize(stream, _, _, _, _, _, _, _, _))
    169         .WillOnce(RunCallback<1>(PIPELINE_OK));
    170     EXPECT_CALL(*video_renderer_, SetPlaybackRate(0.0f));
    171 
    172     // Startup sequence.
    173     EXPECT_CALL(*video_renderer_, Preroll(demuxer_->GetStartTime(), _))
    174         .WillOnce(RunCallback<1>(PIPELINE_OK));
    175     EXPECT_CALL(*video_renderer_, Play(_))
    176         .WillOnce(RunClosure<0>());
    177   }
    178 
    179   // Sets up expectations to allow the audio renderer to initialize.
    180   void InitializeAudioRenderer(DemuxerStream* stream,
    181                                bool disable_after_init_cb) {
    182     if (disable_after_init_cb) {
    183       EXPECT_CALL(*audio_renderer_, Initialize(stream, _, _, _, _, _, _, _))
    184           .WillOnce(DoAll(RunCallback<1>(PIPELINE_OK),
    185                           WithArg<6>(RunClosure<0>())));  // |disabled_cb|.
    186     } else {
    187       EXPECT_CALL(*audio_renderer_, Initialize(stream, _, _, _, _, _, _, _))
    188           .WillOnce(DoAll(SaveArg<4>(&audio_time_cb_),
    189                           RunCallback<1>(PIPELINE_OK)));
    190     }
    191   }
    192 
    193   void AddTextStream() {
    194     EXPECT_CALL(*this, OnAddTextTrack(_,_))
    195         .WillOnce(Invoke(this, &PipelineTest::DoOnAddTextTrack));
    196     static_cast<DemuxerHost*>(pipeline_.get())->AddTextStream(text_stream(),
    197                               TextTrackConfig(kTextSubtitles, "", "", ""));
    198   }
    199 
    200   // Sets up expectations on the callback and initializes the pipeline.  Called
    201   // after tests have set expectations any filters they wish to use.
    202   void InitializePipeline(PipelineStatus start_status) {
    203     EXPECT_CALL(callbacks_, OnStart(start_status));
    204 
    205     if (start_status == PIPELINE_OK) {
    206       EXPECT_CALL(callbacks_, OnBufferingState(Pipeline::kHaveMetadata));
    207 
    208       if (audio_stream_) {
    209         EXPECT_CALL(*audio_renderer_, SetPlaybackRate(0.0f));
    210         EXPECT_CALL(*audio_renderer_, SetVolume(1.0f));
    211 
    212         // Startup sequence.
    213         EXPECT_CALL(*audio_renderer_, Preroll(base::TimeDelta(), _))
    214             .WillOnce(RunCallback<1>(PIPELINE_OK));
    215         EXPECT_CALL(*audio_renderer_, Play(_))
    216             .WillOnce(RunClosure<0>());
    217       }
    218       EXPECT_CALL(callbacks_, OnBufferingState(Pipeline::kPrerollCompleted));
    219     }
    220 
    221     pipeline_->Start(
    222         filter_collection_.Pass(),
    223         base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
    224         base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
    225         base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)),
    226         base::Bind(&CallbackHelper::OnBufferingState,
    227                    base::Unretained(&callbacks_)),
    228         base::Bind(&CallbackHelper::OnDurationChange,
    229                    base::Unretained(&callbacks_)));
    230     message_loop_.RunUntilIdle();
    231   }
    232 
    233   void CreateAudioStream() {
    234     audio_stream_ = CreateStream(DemuxerStream::AUDIO);
    235   }
    236 
    237   void CreateVideoStream() {
    238     video_stream_ = CreateStream(DemuxerStream::VIDEO);
    239     video_stream_->set_video_decoder_config(video_decoder_config_);
    240   }
    241 
    242   void CreateTextStream() {
    243     scoped_ptr<FakeTextTrackStream> text_stream(new FakeTextTrackStream);
    244     text_stream_ = text_stream.Pass();
    245   }
    246 
    247   MockDemuxerStream* audio_stream() {
    248     return audio_stream_.get();
    249   }
    250 
    251   MockDemuxerStream* video_stream() {
    252     return video_stream_.get();
    253   }
    254 
    255   FakeTextTrackStream* text_stream() {
    256     return text_stream_.get();
    257   }
    258 
    259   void ExpectSeek(const base::TimeDelta& seek_time) {
    260     // Every filter should receive a call to Seek().
    261     EXPECT_CALL(*demuxer_, Seek(seek_time, _))
    262         .WillOnce(RunCallback<1>(PIPELINE_OK));
    263 
    264     if (audio_stream_) {
    265       EXPECT_CALL(*audio_renderer_, Pause(_))
    266           .WillOnce(RunClosure<0>());
    267       EXPECT_CALL(*audio_renderer_, Flush(_))
    268           .WillOnce(RunClosure<0>());
    269       EXPECT_CALL(*audio_renderer_, Preroll(seek_time, _))
    270           .WillOnce(RunCallback<1>(PIPELINE_OK));
    271       EXPECT_CALL(*audio_renderer_, SetPlaybackRate(_));
    272       EXPECT_CALL(*audio_renderer_, SetVolume(_));
    273       EXPECT_CALL(*audio_renderer_, Play(_))
    274           .WillOnce(RunClosure<0>());
    275     }
    276 
    277     if (video_stream_) {
    278       EXPECT_CALL(*video_renderer_, Pause(_))
    279           .WillOnce(RunClosure<0>());
    280       EXPECT_CALL(*video_renderer_, Flush(_))
    281           .WillOnce(RunClosure<0>());
    282       EXPECT_CALL(*video_renderer_, Preroll(seek_time, _))
    283           .WillOnce(RunCallback<1>(PIPELINE_OK));
    284       EXPECT_CALL(*video_renderer_, SetPlaybackRate(_));
    285       EXPECT_CALL(*video_renderer_, Play(_))
    286           .WillOnce(RunClosure<0>());
    287     }
    288 
    289     EXPECT_CALL(callbacks_, OnBufferingState(Pipeline::kPrerollCompleted));
    290 
    291     // We expect a successful seek callback.
    292     EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK));
    293   }
    294 
    295   void DoSeek(const base::TimeDelta& seek_time) {
    296     pipeline_->Seek(seek_time,
    297                     base::Bind(&CallbackHelper::OnSeek,
    298                                base::Unretained(&callbacks_)));
    299 
    300     // We expect the time to be updated only after the seek has completed.
    301     EXPECT_NE(seek_time, pipeline_->GetMediaTime());
    302     message_loop_.RunUntilIdle();
    303     EXPECT_EQ(seek_time, pipeline_->GetMediaTime());
    304   }
    305 
    306   void ExpectStop() {
    307     if (demuxer_)
    308       EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
    309 
    310     if (audio_stream_)
    311       EXPECT_CALL(*audio_renderer_, Stop(_)).WillOnce(RunClosure<0>());
    312 
    313     if (video_stream_)
    314       EXPECT_CALL(*video_renderer_, Stop(_)).WillOnce(RunClosure<0>());
    315   }
    316 
    317   MOCK_METHOD2(OnAddTextTrack, void(const TextTrackConfig&,
    318                                     const AddTextTrackDoneCB&));
    319 
    320   void DoOnAddTextTrack(const TextTrackConfig& config,
    321                         const AddTextTrackDoneCB& done_cb) {
    322     scoped_ptr<TextTrack> text_track(new MockTextTrack);
    323     done_cb.Run(text_track.Pass());
    324   }
    325 
    326   // Fixture members.
    327   StrictMock<CallbackHelper> callbacks_;
    328   base::SimpleTestTickClock test_tick_clock_;
    329   base::MessageLoop message_loop_;
    330   scoped_ptr<Pipeline> pipeline_;
    331 
    332   scoped_ptr<FilterCollection> filter_collection_;
    333   scoped_ptr<MockDemuxer> demuxer_;
    334   MockVideoRenderer* video_renderer_;
    335   MockAudioRenderer* audio_renderer_;
    336   StrictMock<CallbackHelper> text_renderer_callbacks_;
    337   TextRenderer* text_renderer_;
    338   scoped_ptr<StrictMock<MockDemuxerStream> > audio_stream_;
    339   scoped_ptr<StrictMock<MockDemuxerStream> > video_stream_;
    340   scoped_ptr<FakeTextTrackStream> text_stream_;
    341   AudioRenderer::TimeCB audio_time_cb_;
    342   VideoDecoderConfig video_decoder_config_;
    343 
    344  private:
    345   DISALLOW_COPY_AND_ASSIGN(PipelineTest);
    346 };
    347 
    348 // Test that playback controls methods no-op when the pipeline hasn't been
    349 // started.
    350 TEST_F(PipelineTest, NotStarted) {
    351   const base::TimeDelta kZero;
    352 
    353   EXPECT_FALSE(pipeline_->IsRunning());
    354   EXPECT_FALSE(pipeline_->HasAudio());
    355   EXPECT_FALSE(pipeline_->HasVideo());
    356 
    357   // Setting should still work.
    358   EXPECT_EQ(0.0f, pipeline_->GetPlaybackRate());
    359   pipeline_->SetPlaybackRate(-1.0f);
    360   EXPECT_EQ(0.0f, pipeline_->GetPlaybackRate());
    361   pipeline_->SetPlaybackRate(1.0f);
    362   EXPECT_EQ(1.0f, pipeline_->GetPlaybackRate());
    363 
    364   // Setting should still work.
    365   EXPECT_EQ(1.0f, pipeline_->GetVolume());
    366   pipeline_->SetVolume(-1.0f);
    367   EXPECT_EQ(1.0f, pipeline_->GetVolume());
    368   pipeline_->SetVolume(0.0f);
    369   EXPECT_EQ(0.0f, pipeline_->GetVolume());
    370 
    371   EXPECT_TRUE(kZero == pipeline_->GetMediaTime());
    372   EXPECT_EQ(0u, pipeline_->GetBufferedTimeRanges().size());
    373   EXPECT_TRUE(kZero == pipeline_->GetMediaDuration());
    374 
    375   EXPECT_EQ(0, pipeline_->GetTotalBytes());
    376 
    377   // Should always get set to zero.
    378   gfx::Size size(1, 1);
    379   pipeline_->GetNaturalVideoSize(&size);
    380   EXPECT_EQ(0, size.width());
    381   EXPECT_EQ(0, size.height());
    382 }
    383 
    384 TEST_F(PipelineTest, NeverInitializes) {
    385   // Don't execute the callback passed into Initialize().
    386   EXPECT_CALL(*demuxer_, Initialize(_, _, _));
    387 
    388   // This test hangs during initialization by never calling
    389   // InitializationComplete().  StrictMock<> will ensure that the callback is
    390   // never executed.
    391   pipeline_->Start(
    392         filter_collection_.Pass(),
    393         base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
    394         base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
    395         base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)),
    396         base::Bind(&CallbackHelper::OnBufferingState,
    397                    base::Unretained(&callbacks_)),
    398         base::Bind(&CallbackHelper::OnDurationChange,
    399                    base::Unretained(&callbacks_)));
    400   message_loop_.RunUntilIdle();
    401 
    402 
    403   // Because our callback will get executed when the test tears down, we'll
    404   // verify that nothing has been called, then set our expectation for the call
    405   // made during tear down.
    406   Mock::VerifyAndClear(&callbacks_);
    407   EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK));
    408 }
    409 
    410 TEST_F(PipelineTest, URLNotFound) {
    411   EXPECT_CALL(*demuxer_, Initialize(_, _, _))
    412       .WillOnce(RunCallback<1>(PIPELINE_ERROR_URL_NOT_FOUND));
    413   EXPECT_CALL(*demuxer_, Stop(_))
    414       .WillOnce(RunClosure<0>());
    415 
    416   InitializePipeline(PIPELINE_ERROR_URL_NOT_FOUND);
    417 }
    418 
    419 TEST_F(PipelineTest, NoStreams) {
    420   EXPECT_CALL(*demuxer_, Initialize(_, _, _))
    421       .WillOnce(RunCallback<1>(PIPELINE_OK));
    422   EXPECT_CALL(*demuxer_, Stop(_))
    423       .WillOnce(RunClosure<0>());
    424 
    425   InitializePipeline(PIPELINE_ERROR_COULD_NOT_RENDER);
    426 }
    427 
    428 TEST_F(PipelineTest, AudioStream) {
    429   CreateAudioStream();
    430   MockDemuxerStreamVector streams;
    431   streams.push_back(audio_stream());
    432 
    433   InitializeDemuxer(&streams);
    434   InitializeAudioRenderer(audio_stream(), false);
    435 
    436   InitializePipeline(PIPELINE_OK);
    437   EXPECT_TRUE(pipeline_->HasAudio());
    438   EXPECT_FALSE(pipeline_->HasVideo());
    439 }
    440 
    441 TEST_F(PipelineTest, VideoStream) {
    442   CreateVideoStream();
    443   MockDemuxerStreamVector streams;
    444   streams.push_back(video_stream());
    445 
    446   InitializeDemuxer(&streams);
    447   InitializeVideoRenderer(video_stream());
    448 
    449   InitializePipeline(PIPELINE_OK);
    450   EXPECT_FALSE(pipeline_->HasAudio());
    451   EXPECT_TRUE(pipeline_->HasVideo());
    452 }
    453 
    454 TEST_F(PipelineTest, AudioVideoStream) {
    455   CreateAudioStream();
    456   CreateVideoStream();
    457   MockDemuxerStreamVector streams;
    458   streams.push_back(audio_stream());
    459   streams.push_back(video_stream());
    460 
    461   InitializeDemuxer(&streams);
    462   InitializeAudioRenderer(audio_stream(), false);
    463   InitializeVideoRenderer(video_stream());
    464 
    465   InitializePipeline(PIPELINE_OK);
    466   EXPECT_TRUE(pipeline_->HasAudio());
    467   EXPECT_TRUE(pipeline_->HasVideo());
    468 }
    469 
    470 TEST_F(PipelineTest, VideoTextStream) {
    471   CreateVideoStream();
    472   CreateTextStream();
    473   MockDemuxerStreamVector streams;
    474   streams.push_back(video_stream());
    475 
    476   InitializeDemuxer(&streams);
    477   InitializeVideoRenderer(video_stream());
    478 
    479   InitializePipeline(PIPELINE_OK);
    480   EXPECT_FALSE(pipeline_->HasAudio());
    481   EXPECT_TRUE(pipeline_->HasVideo());
    482 
    483   AddTextStream();
    484   message_loop_.RunUntilIdle();
    485 }
    486 
    487 TEST_F(PipelineTest, VideoAudioTextStream) {
    488   CreateVideoStream();
    489   CreateAudioStream();
    490   CreateTextStream();
    491   MockDemuxerStreamVector streams;
    492   streams.push_back(video_stream());
    493   streams.push_back(audio_stream());
    494 
    495   InitializeDemuxer(&streams);
    496   InitializeVideoRenderer(video_stream());
    497   InitializeAudioRenderer(audio_stream(), false);
    498 
    499   InitializePipeline(PIPELINE_OK);
    500   EXPECT_TRUE(pipeline_->HasAudio());
    501   EXPECT_TRUE(pipeline_->HasVideo());
    502 
    503   AddTextStream();
    504   message_loop_.RunUntilIdle();
    505 }
    506 
    507 TEST_F(PipelineTest, Seek) {
    508   CreateAudioStream();
    509   CreateVideoStream();
    510   CreateTextStream();
    511   MockDemuxerStreamVector streams;
    512   streams.push_back(audio_stream());
    513   streams.push_back(video_stream());
    514 
    515   InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(3000));
    516   InitializeAudioRenderer(audio_stream(), false);
    517   InitializeVideoRenderer(video_stream());
    518 
    519   // Initialize then seek!
    520   InitializePipeline(PIPELINE_OK);
    521 
    522   AddTextStream();
    523   message_loop_.RunUntilIdle();
    524 
    525   // Every filter should receive a call to Seek().
    526   base::TimeDelta expected = base::TimeDelta::FromSeconds(2000);
    527   ExpectSeek(expected);
    528   DoSeek(expected);
    529 }
    530 
    531 TEST_F(PipelineTest, SetVolume) {
    532   CreateAudioStream();
    533   MockDemuxerStreamVector streams;
    534   streams.push_back(audio_stream());
    535 
    536   InitializeDemuxer(&streams);
    537   InitializeAudioRenderer(audio_stream(), false);
    538 
    539   // The audio renderer should receive a call to SetVolume().
    540   float expected = 0.5f;
    541   EXPECT_CALL(*audio_renderer_, SetVolume(expected));
    542 
    543   // Initialize then set volume!
    544   InitializePipeline(PIPELINE_OK);
    545   pipeline_->SetVolume(expected);
    546 }
    547 
    548 TEST_F(PipelineTest, Properties) {
    549   CreateVideoStream();
    550   MockDemuxerStreamVector streams;
    551   streams.push_back(video_stream());
    552 
    553   const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100);
    554   InitializeDemuxer(&streams, kDuration);
    555   InitializeVideoRenderer(video_stream());
    556 
    557   InitializePipeline(PIPELINE_OK);
    558   EXPECT_EQ(kDuration.ToInternalValue(),
    559             pipeline_->GetMediaDuration().ToInternalValue());
    560   EXPECT_EQ(kTotalBytes, pipeline_->GetTotalBytes());
    561   EXPECT_FALSE(pipeline_->DidLoadingProgress());
    562 }
    563 
    564 TEST_F(PipelineTest, GetBufferedTimeRanges) {
    565   CreateVideoStream();
    566   MockDemuxerStreamVector streams;
    567   streams.push_back(video_stream());
    568 
    569   const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100);
    570   InitializeDemuxer(&streams, kDuration);
    571   InitializeVideoRenderer(video_stream());
    572 
    573   InitializePipeline(PIPELINE_OK);
    574 
    575   EXPECT_EQ(0u, pipeline_->GetBufferedTimeRanges().size());
    576 
    577   EXPECT_FALSE(pipeline_->DidLoadingProgress());
    578   pipeline_->AddBufferedByteRange(0, kTotalBytes / 8);
    579   EXPECT_TRUE(pipeline_->DidLoadingProgress());
    580   EXPECT_FALSE(pipeline_->DidLoadingProgress());
    581   EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
    582   EXPECT_EQ(base::TimeDelta(), pipeline_->GetBufferedTimeRanges().start(0));
    583   EXPECT_EQ(kDuration / 8, pipeline_->GetBufferedTimeRanges().end(0));
    584   pipeline_->AddBufferedTimeRange(base::TimeDelta(), kDuration / 8);
    585   EXPECT_EQ(base::TimeDelta(), pipeline_->GetBufferedTimeRanges().start(0));
    586   EXPECT_EQ(kDuration / 8, pipeline_->GetBufferedTimeRanges().end(0));
    587 
    588   base::TimeDelta kSeekTime = kDuration / 2;
    589   ExpectSeek(kSeekTime);
    590   DoSeek(kSeekTime);
    591 
    592   EXPECT_TRUE(pipeline_->DidLoadingProgress());
    593   EXPECT_FALSE(pipeline_->DidLoadingProgress());
    594   pipeline_->AddBufferedByteRange(kTotalBytes / 2,
    595                                   kTotalBytes / 2 + kTotalBytes / 8);
    596   EXPECT_TRUE(pipeline_->DidLoadingProgress());
    597   EXPECT_FALSE(pipeline_->DidLoadingProgress());
    598   EXPECT_EQ(2u, pipeline_->GetBufferedTimeRanges().size());
    599   EXPECT_EQ(base::TimeDelta(), pipeline_->GetBufferedTimeRanges().start(0));
    600   EXPECT_EQ(kDuration / 8, pipeline_->GetBufferedTimeRanges().end(0));
    601   EXPECT_EQ(kDuration / 2, pipeline_->GetBufferedTimeRanges().start(1));
    602   EXPECT_EQ(kDuration / 2 + kDuration / 8,
    603             pipeline_->GetBufferedTimeRanges().end(1));
    604 
    605   pipeline_->AddBufferedTimeRange(kDuration / 4, 3 * kDuration / 8);
    606   EXPECT_EQ(base::TimeDelta(), pipeline_->GetBufferedTimeRanges().start(0));
    607   EXPECT_EQ(kDuration / 8, pipeline_->GetBufferedTimeRanges().end(0));
    608   EXPECT_EQ(kDuration / 4, pipeline_->GetBufferedTimeRanges().start(1));
    609   EXPECT_EQ(3* kDuration / 8, pipeline_->GetBufferedTimeRanges().end(1));
    610   EXPECT_EQ(kDuration / 2, pipeline_->GetBufferedTimeRanges().start(2));
    611   EXPECT_EQ(kDuration / 2 + kDuration / 8,
    612             pipeline_->GetBufferedTimeRanges().end(2));
    613 }
    614 
    615 TEST_F(PipelineTest, DisableAudioRenderer) {
    616   CreateAudioStream();
    617   CreateVideoStream();
    618   MockDemuxerStreamVector streams;
    619   streams.push_back(audio_stream());
    620   streams.push_back(video_stream());
    621 
    622   InitializeDemuxer(&streams);
    623   InitializeAudioRenderer(audio_stream(), false);
    624   InitializeVideoRenderer(video_stream());
    625 
    626   InitializePipeline(PIPELINE_OK);
    627   EXPECT_TRUE(pipeline_->HasAudio());
    628   EXPECT_TRUE(pipeline_->HasVideo());
    629 
    630   EXPECT_CALL(*demuxer_, OnAudioRendererDisabled());
    631   pipeline_->OnAudioDisabled();
    632 
    633   // Verify that ended event is fired when video ends.
    634   EXPECT_CALL(callbacks_, OnEnded());
    635   pipeline_->OnVideoRendererEnded();
    636 }
    637 
    638 TEST_F(PipelineTest, DisableAudioRendererDuringInit) {
    639   CreateAudioStream();
    640   CreateVideoStream();
    641   MockDemuxerStreamVector streams;
    642   streams.push_back(audio_stream());
    643   streams.push_back(video_stream());
    644 
    645   InitializeDemuxer(&streams);
    646   InitializeAudioRenderer(audio_stream(), true);
    647   InitializeVideoRenderer(video_stream());
    648 
    649   EXPECT_CALL(*demuxer_, OnAudioRendererDisabled());
    650 
    651   InitializePipeline(PIPELINE_OK);
    652   EXPECT_FALSE(pipeline_->HasAudio());
    653   EXPECT_TRUE(pipeline_->HasVideo());
    654 
    655   // Verify that ended event is fired when video ends.
    656   EXPECT_CALL(callbacks_, OnEnded());
    657   pipeline_->OnVideoRendererEnded();
    658 }
    659 
    660 TEST_F(PipelineTest, EndedCallback) {
    661   CreateAudioStream();
    662   CreateVideoStream();
    663   CreateTextStream();
    664   MockDemuxerStreamVector streams;
    665   streams.push_back(audio_stream());
    666   streams.push_back(video_stream());
    667 
    668   InitializeDemuxer(&streams);
    669   InitializeAudioRenderer(audio_stream(), false);
    670   InitializeVideoRenderer(video_stream());
    671   InitializePipeline(PIPELINE_OK);
    672 
    673   AddTextStream();
    674 
    675   // The ended callback shouldn't run until all renderers have ended.
    676   pipeline_->OnAudioRendererEnded();
    677   message_loop_.RunUntilIdle();
    678 
    679   pipeline_->OnVideoRendererEnded();
    680   message_loop_.RunUntilIdle();
    681 
    682   EXPECT_CALL(callbacks_, OnEnded());
    683   text_stream()->SendEosNotification();
    684   message_loop_.RunUntilIdle();
    685 }
    686 
    687 TEST_F(PipelineTest, AudioStreamShorterThanVideo) {
    688   base::TimeDelta duration = base::TimeDelta::FromSeconds(10);
    689 
    690   CreateAudioStream();
    691   CreateVideoStream();
    692   MockDemuxerStreamVector streams;
    693   streams.push_back(audio_stream());
    694   streams.push_back(video_stream());
    695 
    696   // Replace the clock so we can simulate wallclock time advancing w/o using
    697   // Sleep().
    698   pipeline_->SetClockForTesting(new Clock(&test_tick_clock_));
    699 
    700   InitializeDemuxer(&streams, duration);
    701   InitializeAudioRenderer(audio_stream(), false);
    702   InitializeVideoRenderer(video_stream());
    703   InitializePipeline(PIPELINE_OK);
    704 
    705   EXPECT_EQ(0, pipeline_->GetMediaTime().ToInternalValue());
    706 
    707   float playback_rate = 1.0f;
    708   EXPECT_CALL(*video_renderer_, SetPlaybackRate(playback_rate));
    709   EXPECT_CALL(*audio_renderer_, SetPlaybackRate(playback_rate));
    710   pipeline_->SetPlaybackRate(playback_rate);
    711   message_loop_.RunUntilIdle();
    712 
    713   InSequence s;
    714 
    715   // Verify that the clock doesn't advance since it hasn't been started by
    716   // a time update from the audio stream.
    717   int64 start_time = pipeline_->GetMediaTime().ToInternalValue();
    718   test_tick_clock_.Advance(base::TimeDelta::FromMilliseconds(100));
    719   EXPECT_EQ(pipeline_->GetMediaTime().ToInternalValue(), start_time);
    720 
    721   // Signal end of audio stream.
    722   pipeline_->OnAudioRendererEnded();
    723   message_loop_.RunUntilIdle();
    724 
    725   // Verify that the clock advances.
    726   start_time = pipeline_->GetMediaTime().ToInternalValue();
    727   test_tick_clock_.Advance(base::TimeDelta::FromMilliseconds(100));
    728   EXPECT_GT(pipeline_->GetMediaTime().ToInternalValue(), start_time);
    729 
    730   // Signal end of video stream and make sure OnEnded() callback occurs.
    731   EXPECT_CALL(callbacks_, OnEnded());
    732   pipeline_->OnVideoRendererEnded();
    733 }
    734 
    735 TEST_F(PipelineTest, ErrorDuringSeek) {
    736   CreateAudioStream();
    737   MockDemuxerStreamVector streams;
    738   streams.push_back(audio_stream());
    739 
    740   InitializeDemuxer(&streams);
    741   InitializeAudioRenderer(audio_stream(), false);
    742   InitializePipeline(PIPELINE_OK);
    743 
    744   float playback_rate = 1.0f;
    745   EXPECT_CALL(*audio_renderer_, SetPlaybackRate(playback_rate));
    746   pipeline_->SetPlaybackRate(playback_rate);
    747   message_loop_.RunUntilIdle();
    748 
    749   base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
    750 
    751   // Preroll() isn't called as the demuxer errors out first.
    752   EXPECT_CALL(*audio_renderer_, Pause(_))
    753       .WillOnce(RunClosure<0>());
    754   EXPECT_CALL(*audio_renderer_, Flush(_))
    755       .WillOnce(RunClosure<0>());
    756   EXPECT_CALL(*audio_renderer_, Stop(_))
    757       .WillOnce(RunClosure<0>());
    758 
    759   EXPECT_CALL(*demuxer_, Seek(seek_time, _))
    760       .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ));
    761   EXPECT_CALL(*demuxer_, Stop(_))
    762       .WillOnce(RunClosure<0>());
    763 
    764   pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek,
    765                                         base::Unretained(&callbacks_)));
    766   EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ));
    767   message_loop_.RunUntilIdle();
    768 }
    769 
    770 // Invoked function OnError. This asserts that the pipeline does not enqueue
    771 // non-teardown related tasks while tearing down.
    772 static void TestNoCallsAfterError(
    773     Pipeline* pipeline, base::MessageLoop* message_loop,
    774     PipelineStatus /* status */) {
    775   CHECK(pipeline);
    776   CHECK(message_loop);
    777 
    778   // When we get to this stage, the message loop should be empty.
    779   EXPECT_TRUE(message_loop->IsIdleForTesting());
    780 
    781   // Make calls on pipeline after error has occurred.
    782   pipeline->SetPlaybackRate(0.5f);
    783   pipeline->SetVolume(0.5f);
    784 
    785   // No additional tasks should be queued as a result of these calls.
    786   EXPECT_TRUE(message_loop->IsIdleForTesting());
    787 }
    788 
    789 TEST_F(PipelineTest, NoMessageDuringTearDownFromError) {
    790   CreateAudioStream();
    791   MockDemuxerStreamVector streams;
    792   streams.push_back(audio_stream());
    793 
    794   InitializeDemuxer(&streams);
    795   InitializeAudioRenderer(audio_stream(), false);
    796   InitializePipeline(PIPELINE_OK);
    797 
    798   // Trigger additional requests on the pipeline during tear down from error.
    799   base::Callback<void(PipelineStatus)> cb = base::Bind(
    800       &TestNoCallsAfterError, pipeline_.get(), &message_loop_);
    801   ON_CALL(callbacks_, OnError(_))
    802       .WillByDefault(Invoke(&cb, &base::Callback<void(PipelineStatus)>::Run));
    803 
    804   base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
    805 
    806   // Seek() isn't called as the demuxer errors out first.
    807   EXPECT_CALL(*audio_renderer_, Pause(_))
    808       .WillOnce(RunClosure<0>());
    809   EXPECT_CALL(*audio_renderer_, Flush(_))
    810       .WillOnce(RunClosure<0>());
    811   EXPECT_CALL(*audio_renderer_, Stop(_))
    812       .WillOnce(RunClosure<0>());
    813 
    814   EXPECT_CALL(*demuxer_, Seek(seek_time, _))
    815       .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ));
    816   EXPECT_CALL(*demuxer_, Stop(_))
    817       .WillOnce(RunClosure<0>());
    818 
    819   pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek,
    820                                         base::Unretained(&callbacks_)));
    821   EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ));
    822   message_loop_.RunUntilIdle();
    823 }
    824 
    825 TEST_F(PipelineTest, StartTimeIsZero) {
    826   CreateVideoStream();
    827   MockDemuxerStreamVector streams;
    828   streams.push_back(video_stream());
    829 
    830   const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100);
    831   InitializeDemuxer(&streams, kDuration);
    832   InitializeVideoRenderer(video_stream());
    833 
    834   InitializePipeline(PIPELINE_OK);
    835   EXPECT_FALSE(pipeline_->HasAudio());
    836   EXPECT_TRUE(pipeline_->HasVideo());
    837 
    838   EXPECT_EQ(base::TimeDelta(), pipeline_->GetMediaTime());
    839 }
    840 
    841 TEST_F(PipelineTest, StartTimeIsNonZero) {
    842   const base::TimeDelta kStartTime = base::TimeDelta::FromSeconds(4);
    843   const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100);
    844 
    845   EXPECT_CALL(*demuxer_, GetStartTime())
    846       .WillRepeatedly(Return(kStartTime));
    847 
    848   CreateVideoStream();
    849   MockDemuxerStreamVector streams;
    850   streams.push_back(video_stream());
    851 
    852   InitializeDemuxer(&streams, kDuration);
    853   InitializeVideoRenderer(video_stream());
    854 
    855   InitializePipeline(PIPELINE_OK);
    856   EXPECT_FALSE(pipeline_->HasAudio());
    857   EXPECT_TRUE(pipeline_->HasVideo());
    858 
    859   EXPECT_EQ(kStartTime, pipeline_->GetMediaTime());
    860 }
    861 
    862 static void RunTimeCB(const AudioRenderer::TimeCB& time_cb,
    863                        int time_in_ms,
    864                        int max_time_in_ms) {
    865   time_cb.Run(base::TimeDelta::FromMilliseconds(time_in_ms),
    866               base::TimeDelta::FromMilliseconds(max_time_in_ms));
    867 }
    868 
    869 TEST_F(PipelineTest, AudioTimeUpdateDuringSeek) {
    870   CreateAudioStream();
    871   MockDemuxerStreamVector streams;
    872   streams.push_back(audio_stream());
    873 
    874   InitializeDemuxer(&streams);
    875   InitializeAudioRenderer(audio_stream(), false);
    876   InitializePipeline(PIPELINE_OK);
    877 
    878   float playback_rate = 1.0f;
    879   EXPECT_CALL(*audio_renderer_, SetPlaybackRate(playback_rate));
    880   pipeline_->SetPlaybackRate(playback_rate);
    881   message_loop_.RunUntilIdle();
    882 
    883   // Provide an initial time update so that the pipeline transitions out of the
    884   // "waiting for time update" state.
    885   audio_time_cb_.Run(base::TimeDelta::FromMilliseconds(100),
    886                      base::TimeDelta::FromMilliseconds(500));
    887 
    888   base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
    889 
    890   // Arrange to trigger a time update while the demuxer is in the middle of
    891   // seeking. This update should be ignored by the pipeline and the clock should
    892   // not get updated.
    893   base::Closure closure = base::Bind(&RunTimeCB, audio_time_cb_, 300, 700);
    894   EXPECT_CALL(*demuxer_, Seek(seek_time, _))
    895       .WillOnce(DoAll(InvokeWithoutArgs(&closure, &base::Closure::Run),
    896                       RunCallback<1>(PIPELINE_OK)));
    897 
    898   EXPECT_CALL(*audio_renderer_, Pause(_))
    899       .WillOnce(RunClosure<0>());
    900   EXPECT_CALL(*audio_renderer_, Flush(_))
    901       .WillOnce(RunClosure<0>());
    902   EXPECT_CALL(*audio_renderer_, Preroll(seek_time, _))
    903       .WillOnce(RunCallback<1>(PIPELINE_OK));
    904   EXPECT_CALL(*audio_renderer_, SetPlaybackRate(_));
    905   EXPECT_CALL(*audio_renderer_, SetVolume(_));
    906   EXPECT_CALL(*audio_renderer_, Play(_))
    907       .WillOnce(RunClosure<0>());
    908 
    909   EXPECT_CALL(callbacks_, OnBufferingState(Pipeline::kPrerollCompleted));
    910   EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK));
    911   DoSeek(seek_time);
    912 
    913   EXPECT_EQ(pipeline_->GetMediaTime(), seek_time);
    914 
    915   // Now that the seek is complete, verify that time updates advance the current
    916   // time.
    917   base::TimeDelta new_time = seek_time + base::TimeDelta::FromMilliseconds(100);
    918   audio_time_cb_.Run(new_time, new_time);
    919 
    920   EXPECT_EQ(pipeline_->GetMediaTime(), new_time);
    921 }
    922 
    923 static void DeletePipeline(scoped_ptr<Pipeline> pipeline) {
    924   // |pipeline| will go out of scope.
    925 }
    926 
    927 TEST_F(PipelineTest, DeleteAfterStop) {
    928   CreateAudioStream();
    929   MockDemuxerStreamVector streams;
    930   streams.push_back(audio_stream());
    931   InitializeDemuxer(&streams);
    932   InitializeAudioRenderer(audio_stream(), false);
    933   InitializePipeline(PIPELINE_OK);
    934 
    935   ExpectStop();
    936 
    937   Pipeline* pipeline = pipeline_.get();
    938   pipeline->Stop(base::Bind(&DeletePipeline, base::Passed(&pipeline_)));
    939   message_loop_.RunUntilIdle();
    940 }
    941 
    942 class PipelineTeardownTest : public PipelineTest {
    943  public:
    944   enum TeardownState {
    945     kInitDemuxer,
    946     kInitAudioRenderer,
    947     kInitVideoRenderer,
    948     kPausing,
    949     kFlushing,
    950     kSeeking,
    951     kPrerolling,
    952     kStarting,
    953     kPlaying,
    954   };
    955 
    956   enum StopOrError {
    957     kStop,
    958     kError,
    959     kErrorAndStop,
    960   };
    961 
    962   PipelineTeardownTest() {}
    963   virtual ~PipelineTeardownTest() {}
    964 
    965   void RunTest(TeardownState state, StopOrError stop_or_error) {
    966     switch (state) {
    967       case kInitDemuxer:
    968       case kInitAudioRenderer:
    969       case kInitVideoRenderer:
    970         DoInitialize(state, stop_or_error);
    971         break;
    972 
    973       case kPausing:
    974       case kFlushing:
    975       case kSeeking:
    976       case kPrerolling:
    977       case kStarting:
    978         DoInitialize(state, stop_or_error);
    979         DoSeek(state, stop_or_error);
    980         break;
    981 
    982       case kPlaying:
    983         DoInitialize(state, stop_or_error);
    984         DoStopOrError(stop_or_error);
    985         break;
    986     }
    987   }
    988 
    989  private:
    990   // TODO(scherkus): We do radically different things whether teardown is
    991   // invoked via stop vs error. The teardown path should be the same,
    992   // see http://crbug.com/110228
    993   void DoInitialize(TeardownState state, StopOrError stop_or_error) {
    994     PipelineStatus expected_status =
    995         SetInitializeExpectations(state, stop_or_error);
    996 
    997     EXPECT_CALL(callbacks_, OnStart(expected_status));
    998     pipeline_->Start(
    999         filter_collection_.Pass(),
   1000         base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
   1001         base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
   1002         base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)),
   1003         base::Bind(&CallbackHelper::OnBufferingState,
   1004                    base::Unretained(&callbacks_)),
   1005         base::Bind(&CallbackHelper::OnDurationChange,
   1006                    base::Unretained(&callbacks_)));
   1007     message_loop_.RunUntilIdle();
   1008   }
   1009 
   1010   PipelineStatus SetInitializeExpectations(TeardownState state,
   1011                                            StopOrError stop_or_error) {
   1012     PipelineStatus status = PIPELINE_OK;
   1013     base::Closure stop_cb = base::Bind(
   1014         &CallbackHelper::OnStop, base::Unretained(&callbacks_));
   1015 
   1016     if (state == kInitDemuxer) {
   1017       if (stop_or_error == kStop) {
   1018         EXPECT_CALL(*demuxer_, Initialize(_, _, _))
   1019             .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
   1020                             RunCallback<1>(PIPELINE_OK)));
   1021         EXPECT_CALL(callbacks_, OnStop());
   1022       } else {
   1023         status = DEMUXER_ERROR_COULD_NOT_OPEN;
   1024         EXPECT_CALL(*demuxer_, Initialize(_, _, _))
   1025             .WillOnce(RunCallback<1>(status));
   1026       }
   1027 
   1028       EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
   1029       return status;
   1030     }
   1031 
   1032     CreateAudioStream();
   1033     CreateVideoStream();
   1034     MockDemuxerStreamVector streams;
   1035     streams.push_back(audio_stream());
   1036     streams.push_back(video_stream());
   1037     InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(3000));
   1038 
   1039     if (state == kInitAudioRenderer) {
   1040       if (stop_or_error == kStop) {
   1041         EXPECT_CALL(*audio_renderer_, Initialize(_, _, _, _, _, _, _, _))
   1042             .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
   1043                             RunCallback<1>(PIPELINE_OK)));
   1044         EXPECT_CALL(callbacks_, OnStop());
   1045       } else {
   1046         status = PIPELINE_ERROR_INITIALIZATION_FAILED;
   1047         EXPECT_CALL(*audio_renderer_, Initialize(_, _, _, _, _, _, _, _))
   1048             .WillOnce(RunCallback<1>(status));
   1049       }
   1050 
   1051       EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
   1052       EXPECT_CALL(*audio_renderer_, Stop(_)).WillOnce(RunClosure<0>());
   1053       return status;
   1054     }
   1055 
   1056     EXPECT_CALL(*audio_renderer_, Initialize(_, _, _, _, _, _, _, _))
   1057         .WillOnce(RunCallback<1>(PIPELINE_OK));
   1058 
   1059     if (state == kInitVideoRenderer) {
   1060       if (stop_or_error == kStop) {
   1061         EXPECT_CALL(*video_renderer_, Initialize(_, _, _, _, _, _, _, _, _))
   1062             .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
   1063                             RunCallback<1>(PIPELINE_OK)));
   1064         EXPECT_CALL(callbacks_, OnStop());
   1065       } else {
   1066         status = PIPELINE_ERROR_INITIALIZATION_FAILED;
   1067         EXPECT_CALL(*video_renderer_, Initialize(_, _, _, _, _, _, _, _, _))
   1068             .WillOnce(RunCallback<1>(status));
   1069       }
   1070 
   1071       EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
   1072       EXPECT_CALL(*audio_renderer_, Stop(_)).WillOnce(RunClosure<0>());
   1073       EXPECT_CALL(*video_renderer_, Stop(_)).WillOnce(RunClosure<0>());
   1074       return status;
   1075     }
   1076 
   1077     EXPECT_CALL(*video_renderer_, Initialize(_, _, _, _, _, _, _, _, _))
   1078         .WillOnce(RunCallback<1>(PIPELINE_OK));
   1079 
   1080     EXPECT_CALL(callbacks_, OnBufferingState(Pipeline::kHaveMetadata));
   1081 
   1082     // If we get here it's a successful initialization.
   1083     EXPECT_CALL(*audio_renderer_, Preroll(base::TimeDelta(), _))
   1084         .WillOnce(RunCallback<1>(PIPELINE_OK));
   1085     EXPECT_CALL(*video_renderer_, Preroll(base::TimeDelta(), _))
   1086         .WillOnce(RunCallback<1>(PIPELINE_OK));
   1087 
   1088     EXPECT_CALL(*audio_renderer_, SetPlaybackRate(0.0f));
   1089     EXPECT_CALL(*video_renderer_, SetPlaybackRate(0.0f));
   1090     EXPECT_CALL(*audio_renderer_, SetVolume(1.0f));
   1091 
   1092     EXPECT_CALL(*audio_renderer_, Play(_))
   1093         .WillOnce(RunClosure<0>());
   1094     EXPECT_CALL(*video_renderer_, Play(_))
   1095         .WillOnce(RunClosure<0>());
   1096 
   1097     if (status == PIPELINE_OK)
   1098       EXPECT_CALL(callbacks_, OnBufferingState(Pipeline::kPrerollCompleted));
   1099 
   1100     return status;
   1101   }
   1102 
   1103   void DoSeek(TeardownState state, StopOrError stop_or_error) {
   1104     InSequence s;
   1105     PipelineStatus status = SetSeekExpectations(state, stop_or_error);
   1106 
   1107     EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
   1108     EXPECT_CALL(*audio_renderer_, Stop(_)).WillOnce(RunClosure<0>());
   1109     EXPECT_CALL(*video_renderer_, Stop(_)).WillOnce(RunClosure<0>());
   1110     EXPECT_CALL(callbacks_, OnSeek(status));
   1111 
   1112     if (status == PIPELINE_OK) {
   1113       EXPECT_CALL(callbacks_, OnStop());
   1114     }
   1115 
   1116     pipeline_->Seek(base::TimeDelta::FromSeconds(10), base::Bind(
   1117         &CallbackHelper::OnSeek, base::Unretained(&callbacks_)));
   1118     message_loop_.RunUntilIdle();
   1119   }
   1120 
   1121   PipelineStatus SetSeekExpectations(TeardownState state,
   1122                                      StopOrError stop_or_error) {
   1123     PipelineStatus status = PIPELINE_OK;
   1124     base::Closure stop_cb = base::Bind(
   1125         &CallbackHelper::OnStop, base::Unretained(&callbacks_));
   1126 
   1127     if (state == kPausing) {
   1128       if (stop_or_error == kStop) {
   1129         EXPECT_CALL(*audio_renderer_, Pause(_))
   1130             .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), RunClosure<0>()));
   1131       } else {
   1132         status = PIPELINE_ERROR_READ;
   1133         EXPECT_CALL(*audio_renderer_, Pause(_)).WillOnce(
   1134             DoAll(SetError(pipeline_.get(), status), RunClosure<0>()));
   1135       }
   1136 
   1137       return status;
   1138     }
   1139 
   1140     EXPECT_CALL(*audio_renderer_, Pause(_)).WillOnce(RunClosure<0>());
   1141     EXPECT_CALL(*video_renderer_, Pause(_)).WillOnce(RunClosure<0>());
   1142 
   1143     if (state == kFlushing) {
   1144       if (stop_or_error == kStop) {
   1145         EXPECT_CALL(*audio_renderer_, Flush(_))
   1146             .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), RunClosure<0>()));
   1147       } else {
   1148         status = PIPELINE_ERROR_READ;
   1149         EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce(
   1150             DoAll(SetError(pipeline_.get(), status), RunClosure<0>()));
   1151       }
   1152 
   1153       return status;
   1154     }
   1155 
   1156     EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce(RunClosure<0>());
   1157     EXPECT_CALL(*video_renderer_, Flush(_)).WillOnce(RunClosure<0>());
   1158 
   1159     if (state == kSeeking) {
   1160       if (stop_or_error == kStop) {
   1161         EXPECT_CALL(*demuxer_, Seek(_, _))
   1162             .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
   1163                             RunCallback<1>(PIPELINE_OK)));
   1164       } else {
   1165         status = PIPELINE_ERROR_READ;
   1166         EXPECT_CALL(*demuxer_, Seek(_, _))
   1167             .WillOnce(RunCallback<1>(status));
   1168       }
   1169 
   1170       return status;
   1171     }
   1172 
   1173     EXPECT_CALL(*demuxer_, Seek(_, _))
   1174         .WillOnce(RunCallback<1>(PIPELINE_OK));
   1175 
   1176     if (state == kPrerolling) {
   1177       if (stop_or_error == kStop) {
   1178         EXPECT_CALL(*audio_renderer_, Preroll(_, _))
   1179             .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
   1180                             RunCallback<1>(PIPELINE_OK)));
   1181       } else {
   1182         status = PIPELINE_ERROR_READ;
   1183         EXPECT_CALL(*audio_renderer_, Preroll(_, _))
   1184             .WillOnce(RunCallback<1>(status));
   1185       }
   1186 
   1187       return status;
   1188     }
   1189 
   1190     EXPECT_CALL(*audio_renderer_, Preroll(_, _))
   1191         .WillOnce(RunCallback<1>(PIPELINE_OK));
   1192     EXPECT_CALL(*video_renderer_, Preroll(_, _))
   1193         .WillOnce(RunCallback<1>(PIPELINE_OK));
   1194 
   1195     // Playback rate and volume are updated prior to starting.
   1196     EXPECT_CALL(*audio_renderer_, SetPlaybackRate(0.0f));
   1197     EXPECT_CALL(*video_renderer_, SetPlaybackRate(0.0f));
   1198     EXPECT_CALL(*audio_renderer_, SetVolume(1.0f));
   1199 
   1200     if (state == kStarting) {
   1201       if (stop_or_error == kStop) {
   1202         EXPECT_CALL(*audio_renderer_, Play(_))
   1203             .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), RunClosure<0>()));
   1204       } else {
   1205         status = PIPELINE_ERROR_READ;
   1206         EXPECT_CALL(*audio_renderer_, Play(_)).WillOnce(
   1207             DoAll(SetError(pipeline_.get(), status), RunClosure<0>()));
   1208       }
   1209       return status;
   1210     }
   1211 
   1212     NOTREACHED() << "State not supported: " << state;
   1213     return status;
   1214   }
   1215 
   1216   void DoStopOrError(StopOrError stop_or_error) {
   1217     InSequence s;
   1218 
   1219     EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
   1220     EXPECT_CALL(*audio_renderer_, Stop(_)).WillOnce(RunClosure<0>());
   1221     EXPECT_CALL(*video_renderer_, Stop(_)).WillOnce(RunClosure<0>());
   1222 
   1223     switch (stop_or_error) {
   1224       case kStop:
   1225         EXPECT_CALL(callbacks_, OnStop());
   1226         pipeline_->Stop(base::Bind(
   1227             &CallbackHelper::OnStop, base::Unretained(&callbacks_)));
   1228         break;
   1229 
   1230       case kError:
   1231         EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ));
   1232         pipeline_->SetErrorForTesting(PIPELINE_ERROR_READ);
   1233         break;
   1234 
   1235       case kErrorAndStop:
   1236         EXPECT_CALL(callbacks_, OnStop());
   1237         pipeline_->SetErrorForTesting(PIPELINE_ERROR_READ);
   1238         pipeline_->Stop(base::Bind(
   1239             &CallbackHelper::OnStop, base::Unretained(&callbacks_)));
   1240         break;
   1241     }
   1242 
   1243     message_loop_.RunUntilIdle();
   1244   }
   1245 
   1246   DISALLOW_COPY_AND_ASSIGN(PipelineTeardownTest);
   1247 };
   1248 
   1249 #define INSTANTIATE_TEARDOWN_TEST(stop_or_error, state) \
   1250     TEST_F(PipelineTeardownTest, stop_or_error##_##state) { \
   1251       RunTest(k##state, k##stop_or_error); \
   1252     }
   1253 
   1254 INSTANTIATE_TEARDOWN_TEST(Stop, InitDemuxer);
   1255 INSTANTIATE_TEARDOWN_TEST(Stop, InitAudioRenderer);
   1256 INSTANTIATE_TEARDOWN_TEST(Stop, InitVideoRenderer);
   1257 INSTANTIATE_TEARDOWN_TEST(Stop, Pausing);
   1258 INSTANTIATE_TEARDOWN_TEST(Stop, Flushing);
   1259 INSTANTIATE_TEARDOWN_TEST(Stop, Seeking);
   1260 INSTANTIATE_TEARDOWN_TEST(Stop, Prerolling);
   1261 INSTANTIATE_TEARDOWN_TEST(Stop, Starting);
   1262 INSTANTIATE_TEARDOWN_TEST(Stop, Playing);
   1263 
   1264 INSTANTIATE_TEARDOWN_TEST(Error, InitDemuxer);
   1265 INSTANTIATE_TEARDOWN_TEST(Error, InitAudioRenderer);
   1266 INSTANTIATE_TEARDOWN_TEST(Error, InitVideoRenderer);
   1267 INSTANTIATE_TEARDOWN_TEST(Error, Pausing);
   1268 INSTANTIATE_TEARDOWN_TEST(Error, Flushing);
   1269 INSTANTIATE_TEARDOWN_TEST(Error, Seeking);
   1270 INSTANTIATE_TEARDOWN_TEST(Error, Prerolling);
   1271 INSTANTIATE_TEARDOWN_TEST(Error, Starting);
   1272 INSTANTIATE_TEARDOWN_TEST(Error, Playing);
   1273 
   1274 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing);
   1275 
   1276 }  // namespace media
   1277