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