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