• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ACTION_P(SetDemuxerProperties,duration)44 ACTION_P(SetDemuxerProperties, duration) {
45   arg0->SetTotalBytes(kTotalBytes);
46   arg0->SetDuration(duration);
47 }
48 
ACTION_P2(Stop,pipeline,stop_cb)49 ACTION_P2(Stop, pipeline, stop_cb) {
50   pipeline->Stop(stop_cb);
51 }
52 
ACTION_P2(SetError,pipeline,status)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:
CallbackHelper()61   CallbackHelper() {}
~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:
PipelineTest()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 
~PipelineTest()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;
InitializeDemuxer(MockDemuxerStreamVector * streams,const base::TimeDelta & duration)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 
InitializeDemuxer(MockDemuxerStreamVector * streams)154   void InitializeDemuxer(MockDemuxerStreamVector* streams) {
155     // Initialize with a default non-zero duration.
156     InitializeDemuxer(streams, base::TimeDelta::FromSeconds(10));
157   }
158 
CreateStream(DemuxerStream::Type type)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.
InitializeVideoRenderer(DemuxerStream * stream)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.
InitializeAudioRenderer(DemuxerStream * stream,bool disable_after_init_cb)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 
AddTextStream()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.
InitializePipeline(PipelineStatus start_status)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 
CreateAudioStream()233   void CreateAudioStream() {
234     audio_stream_ = CreateStream(DemuxerStream::AUDIO);
235   }
236 
CreateVideoStream()237   void CreateVideoStream() {
238     video_stream_ = CreateStream(DemuxerStream::VIDEO);
239     video_stream_->set_video_decoder_config(video_decoder_config_);
240   }
241 
CreateTextStream()242   void CreateTextStream() {
243     scoped_ptr<FakeTextTrackStream> text_stream(new FakeTextTrackStream);
244     text_stream_ = text_stream.Pass();
245   }
246 
audio_stream()247   MockDemuxerStream* audio_stream() {
248     return audio_stream_.get();
249   }
250 
video_stream()251   MockDemuxerStream* video_stream() {
252     return video_stream_.get();
253   }
254 
text_stream()255   FakeTextTrackStream* text_stream() {
256     return text_stream_.get();
257   }
258 
ExpectSeek(const base::TimeDelta & seek_time)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 
DoSeek(const base::TimeDelta & seek_time)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 
ExpectStop()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 
DoOnAddTextTrack(const TextTrackConfig & config,const AddTextTrackDoneCB & done_cb)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.
TEST_F(PipelineTest,NotStarted)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 
TEST_F(PipelineTest,NeverInitializes)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 
TEST_F(PipelineTest,URLNotFound)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 
TEST_F(PipelineTest,NoStreams)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 
TEST_F(PipelineTest,AudioStream)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 
TEST_F(PipelineTest,VideoStream)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 
TEST_F(PipelineTest,AudioVideoStream)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 
TEST_F(PipelineTest,VideoTextStream)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 
TEST_F(PipelineTest,VideoAudioTextStream)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 
TEST_F(PipelineTest,Seek)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 
TEST_F(PipelineTest,SetVolume)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 
TEST_F(PipelineTest,Properties)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 
TEST_F(PipelineTest,GetBufferedTimeRanges)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 
TEST_F(PipelineTest,DisableAudioRenderer)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 
TEST_F(PipelineTest,DisableAudioRendererDuringInit)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 
TEST_F(PipelineTest,EndedCallback)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 
TEST_F(PipelineTest,AudioStreamShorterThanVideo)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 
TEST_F(PipelineTest,ErrorDuringSeek)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.
TestNoCallsAfterError(Pipeline * pipeline,base::MessageLoop * message_loop,PipelineStatus)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 
TEST_F(PipelineTest,NoMessageDuringTearDownFromError)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 
TEST_F(PipelineTest,StartTimeIsZero)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 
TEST_F(PipelineTest,StartTimeIsNonZero)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 
RunTimeCB(const AudioRenderer::TimeCB & time_cb,int time_in_ms,int max_time_in_ms)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 
TEST_F(PipelineTest,AudioTimeUpdateDuringSeek)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 
DeletePipeline(scoped_ptr<Pipeline> pipeline)923 static void DeletePipeline(scoped_ptr<Pipeline> pipeline) {
924   // |pipeline| will go out of scope.
925 }
926 
TEST_F(PipelineTest,DeleteAfterStop)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 
PipelineTeardownTest()962   PipelineTeardownTest() {}
~PipelineTeardownTest()963   virtual ~PipelineTeardownTest() {}
964 
RunTest(TeardownState state,StopOrError stop_or_error)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
DoInitialize(TeardownState state,StopOrError stop_or_error)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 
SetInitializeExpectations(TeardownState state,StopOrError stop_or_error)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 
DoSeek(TeardownState state,StopOrError stop_or_error)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 
SetSeekExpectations(TeardownState state,StopOrError stop_or_error)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 
DoStopOrError(StopOrError stop_or_error)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