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 "media/base/pipeline_impl.h"
6 
7 #include <stddef.h>
8 #include <memory>
9 #include <utility>
10 #include <vector>
11 
12 #include "base/bind.h"
13 #include "base/location.h"
14 #include "base/macros.h"
15 #include "base/run_loop.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/stl_util.h"
18 #include "base/test/gmock_callback_support.h"
19 #include "base/test/simple_test_tick_clock.h"
20 #include "base/test/task_environment.h"
21 #include "base/threading/simple_thread.h"
22 #include "base/threading/thread_task_runner_handle.h"
23 #include "base/time/clock.h"
24 #include "media/base/fake_text_track_stream.h"
25 #include "media/base/media_util.h"
26 #include "media/base/mock_filters.h"
27 #include "media/base/test_helpers.h"
28 #include "media/base/text_renderer.h"
29 #include "media/base/text_track_config.h"
30 #include "media/base/time_delta_interpolator.h"
31 #include "testing/gtest/include/gtest/gtest.h"
32 #include "ui/gfx/geometry/size.h"
33 
34 using ::base::test::RunClosure;
35 using ::base::test::RunOnceCallback;
36 using ::base::test::RunOnceClosure;
37 using ::testing::_;
38 using ::testing::AnyNumber;
39 using ::testing::DeleteArg;
40 using ::testing::DoAll;
41 using ::testing::Invoke;
42 using ::testing::InvokeWithoutArgs;
43 using ::testing::Mock;
44 using ::testing::NiceMock;
45 using ::testing::NotNull;
46 using ::testing::Return;
47 using ::testing::SaveArg;
48 using ::testing::StrictMock;
49 using ::testing::WithArg;
50 
51 namespace media {
52 
ACTION_P(SetDemuxerProperties,duration)53 ACTION_P(SetDemuxerProperties, duration) {
54   arg0->SetDuration(duration);
55 }
56 
ACTION_P(Stop,pipeline)57 ACTION_P(Stop, pipeline) {
58   pipeline->Stop();
59 }
60 
ACTION_P(PostStop,pipeline)61 ACTION_P(PostStop, pipeline) {
62   base::ThreadTaskRunnerHandle::Get()->PostTask(
63       FROM_HERE, base::BindOnce(&Pipeline::Stop, base::Unretained(pipeline)));
64 }
65 
ACTION_P2(SetError,renderer_client,status)66 ACTION_P2(SetError, renderer_client, status) {
67   (*renderer_client)->OnError(status);
68 }
69 
ACTION_P3(SetBufferingState,renderer_client,buffering_state,reason)70 ACTION_P3(SetBufferingState, renderer_client, buffering_state, reason) {
71   (*renderer_client)->OnBufferingStateChange(buffering_state, reason);
72 }
73 
ACTION_TEMPLATE(PostCallback,HAS_1_TEMPLATE_PARAMS (int,k),AND_1_VALUE_PARAMS (p0))74 ACTION_TEMPLATE(PostCallback,
75                 HAS_1_TEMPLATE_PARAMS(int, k),
76                 AND_1_VALUE_PARAMS(p0)) {
77   base::ThreadTaskRunnerHandle::Get()->PostTask(
78       FROM_HERE, base::BindOnce(std::move(std::get<k>(args)), p0));
79 }
80 
81 // TODO(scherkus): even though some filters are initialized on separate
82 // threads these test aren't flaky... why?  It's because filters' Initialize()
83 // is executed on |message_loop_| and the mock filters instantly call
84 // InitializationComplete(), which keeps the pipeline humming along.  If
85 // either filters don't call InitializationComplete() immediately or filter
86 // initialization is moved to a separate thread this test will become flaky.
87 class PipelineImplTest : public ::testing::Test {
88  public:
89   // Used for setting expectations on pipeline callbacks.  Using a StrictMock
90   // also lets us test for missing callbacks.
91   class CallbackHelper : public MockPipelineClient {
92    public:
93     CallbackHelper() = default;
94     virtual ~CallbackHelper() = default;
95 
96     MOCK_METHOD1(OnStart, void(PipelineStatus));
97     MOCK_METHOD1(OnSeek, void(PipelineStatus));
98     MOCK_METHOD1(OnSuspend, void(PipelineStatus));
99     MOCK_METHOD1(OnResume, void(PipelineStatus));
100     MOCK_METHOD1(OnCdmAttached, void(bool));
101 
102    private:
103     DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
104   };
105 
PipelineImplTest()106   PipelineImplTest()
107       : demuxer_(new StrictMock<MockDemuxer>()),
108         demuxer_host_(nullptr),
109         scoped_renderer_(new StrictMock<MockRenderer>()),
110         renderer_(scoped_renderer_.get()),
111         renderer_client_(nullptr) {
112     pipeline_ = std::make_unique<PipelineImpl>(
113         task_environment_.GetMainThreadTaskRunner(),
114         task_environment_.GetMainThreadTaskRunner(),
115         base::BindRepeating(&PipelineImplTest::CreateRenderer,
116                             base::Unretained(this)),
117         &media_log_);
118 
119     // SetDemuxerExpectations() adds overriding expectations for expected
120     // non-NULL streams.
121     std::vector<DemuxerStream*> empty;
122     EXPECT_CALL(*demuxer_, GetAllStreams()).WillRepeatedly(Return(empty));
123 
124     EXPECT_CALL(*demuxer_, GetTimelineOffset())
125         .WillRepeatedly(Return(base::Time()));
126 
127     EXPECT_CALL(*renderer_, GetMediaTime())
128         .WillRepeatedly(Return(base::TimeDelta()));
129 
130     EXPECT_CALL(*demuxer_, GetStartTime()).WillRepeatedly(Return(start_time_));
131 
132     EXPECT_CALL(*renderer_, SetPreservesPitch(true)).Times(AnyNumber());
133   }
134 
~PipelineImplTest()135   ~PipelineImplTest() override {
136     if (pipeline_->IsRunning()) {
137       ExpectDemuxerStop();
138 
139       pipeline_->Stop();
140     }
141 
142     pipeline_.reset();
143     base::RunLoop().RunUntilIdle();
144   }
145 
OnDemuxerError()146   void OnDemuxerError() { demuxer_host_->OnDemuxerError(PIPELINE_ERROR_ABORT); }
147 
148  protected:
149   // Sets up expectations to allow the demuxer to initialize.
SetDemuxerExpectations(base::TimeDelta duration)150   void SetDemuxerExpectations(base::TimeDelta duration) {
151     EXPECT_CALL(callbacks_, OnDurationChange());
152     EXPECT_CALL(*demuxer_, OnInitialize(_, _))
153         .WillOnce(DoAll(SaveArg<0>(&demuxer_host_),
154                         SetDemuxerProperties(duration),
155                         PostCallback<1>(PIPELINE_OK)));
156     EXPECT_CALL(*demuxer_, GetAllStreams()).WillRepeatedly(Return(streams_));
157   }
158 
SetDemuxerExpectations()159   void SetDemuxerExpectations() {
160     // Initialize with a default non-zero duration.
161     SetDemuxerExpectations(base::TimeDelta::FromSeconds(10));
162   }
163 
CreateStream(DemuxerStream::Type type)164   std::unique_ptr<StrictMock<MockDemuxerStream>> CreateStream(
165       DemuxerStream::Type type) {
166     std::unique_ptr<StrictMock<MockDemuxerStream>> stream(
167         new StrictMock<MockDemuxerStream>(type));
168     return stream;
169   }
170 
171   // Sets up expectations to allow the renderer to initialize.
ExpectRendererInitialization()172   void ExpectRendererInitialization() {
173     EXPECT_CALL(*renderer_, OnInitialize(_, _, _))
174         .WillOnce(
175             DoAll(SaveArg<1>(&renderer_client_), PostCallback<2>(PIPELINE_OK)));
176   }
177 
StartPipeline(Pipeline::StartType start_type=Pipeline::StartType::kNormal)178   void StartPipeline(
179       Pipeline::StartType start_type = Pipeline::StartType::kNormal) {
180     EXPECT_CALL(callbacks_, OnWaiting(_)).Times(0);
181     pipeline_->Start(start_type, demuxer_.get(), &callbacks_,
182                      base::BindOnce(&CallbackHelper::OnStart,
183                                     base::Unretained(&callbacks_)));
184   }
185 
SetRendererPostStartExpectations()186   void SetRendererPostStartExpectations() {
187     EXPECT_CALL(*renderer_, SetPlaybackRate(0.0));
188     EXPECT_CALL(*renderer_, SetVolume(1.0f));
189     EXPECT_CALL(*renderer_, StartPlayingFrom(start_time_))
190         .WillOnce(SetBufferingState(&renderer_client_, BUFFERING_HAVE_ENOUGH,
191                                     BUFFERING_CHANGE_REASON_UNKNOWN));
192     EXPECT_CALL(callbacks_,
193                 OnBufferingStateChange(BUFFERING_HAVE_ENOUGH,
194                                        BUFFERING_CHANGE_REASON_UNKNOWN));
195   }
196 
197   // Suspension status of the pipeline post Start().
198   enum class PostStartStatus {
199     kNormal,
200     kSuspended,
201   };
202 
203   // Sets up expectations on the callback and initializes the pipeline. Called
204   // after tests have set expectations any filters they wish to use.
StartPipelineAndExpect(PipelineStatus start_status,Pipeline::StartType start_type=Pipeline::StartType::kNormal,PostStartStatus post_start_status=PostStartStatus::kNormal)205   void StartPipelineAndExpect(
206       PipelineStatus start_status,
207       Pipeline::StartType start_type = Pipeline::StartType::kNormal,
208       PostStartStatus post_start_status = PostStartStatus::kNormal) {
209     EXPECT_CALL(callbacks_, OnStart(start_status));
210 
211     if (start_status == PIPELINE_OK) {
212       EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_));
213 
214       if (start_type == Pipeline::StartType::kNormal)
215         ExpectRendererInitialization();
216 
217       if (post_start_status == PostStartStatus::kNormal)
218         SetRendererPostStartExpectations();
219     }
220 
221     StartPipeline(start_type);
222     base::RunLoop().RunUntilIdle();
223 
224     if (start_status == PIPELINE_OK)
225       EXPECT_TRUE(pipeline_->IsRunning());
226 
227     if (post_start_status != PostStartStatus::kNormal)
228       EXPECT_TRUE(pipeline_->IsSuspended());
229   }
230 
CreateAudioStream()231   void CreateAudioStream() {
232     audio_stream_ = CreateStream(DemuxerStream::AUDIO);
233     streams_.push_back(audio_stream_.get());
234   }
235 
CreateVideoStream(bool is_encrypted=false)236   void CreateVideoStream(bool is_encrypted = false) {
237     video_stream_ = CreateStream(DemuxerStream::VIDEO);
238     video_stream_->set_video_decoder_config(
239         is_encrypted ? TestVideoConfig::NormalEncrypted()
240                      : TestVideoConfig::Normal());
241     streams_.push_back(video_stream_.get());
242   }
243 
CreateAudioAndVideoStream()244   void CreateAudioAndVideoStream() {
245     CreateAudioStream();
246     CreateVideoStream();
247   }
248 
CreateEncryptedVideoStream()249   void CreateEncryptedVideoStream() { CreateVideoStream(true); }
250 
SetCdmAndExpect(bool expected_result)251   void SetCdmAndExpect(bool expected_result) {
252     EXPECT_CALL(*renderer_, OnSetCdm(_, _)).WillOnce(RunOnceCallback<1>(true));
253     EXPECT_CALL(callbacks_, OnCdmAttached(expected_result));
254     pipeline_->SetCdm(&cdm_context_,
255                       base::BindOnce(&CallbackHelper::OnCdmAttached,
256                                      base::Unretained(&callbacks_)));
257     base::RunLoop().RunUntilIdle();
258   }
259 
ExpectSeek(const base::TimeDelta & seek_time,bool underflowed)260   void ExpectSeek(const base::TimeDelta& seek_time, bool underflowed) {
261     EXPECT_CALL(*demuxer_, AbortPendingReads());
262     EXPECT_CALL(*demuxer_, OnSeek(seek_time, _))
263         .WillOnce(RunOnceCallback<1>(PIPELINE_OK));
264 
265     EXPECT_CALL(*renderer_, OnFlush(_)).WillOnce(RunOnceClosure<0>());
266     EXPECT_CALL(*renderer_, SetPlaybackRate(_));
267     EXPECT_CALL(*renderer_, StartPlayingFrom(seek_time))
268         .WillOnce(SetBufferingState(&renderer_client_, BUFFERING_HAVE_ENOUGH,
269                                     BUFFERING_CHANGE_REASON_UNKNOWN));
270 
271     // We expect a successful seek callback followed by a buffering update.
272     EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK));
273     EXPECT_CALL(callbacks_,
274                 OnBufferingStateChange(BUFFERING_HAVE_ENOUGH,
275                                        BUFFERING_CHANGE_REASON_UNKNOWN));
276   }
277 
DoSeek(const base::TimeDelta & seek_time)278   void DoSeek(const base::TimeDelta& seek_time) {
279     pipeline_->Seek(seek_time, base::BindOnce(&CallbackHelper::OnSeek,
280                                               base::Unretained(&callbacks_)));
281     base::RunLoop().RunUntilIdle();
282   }
283 
ExpectSuspend()284   void ExpectSuspend() {
285     EXPECT_CALL(*demuxer_, AbortPendingReads());
286     EXPECT_CALL(*renderer_, SetPlaybackRate(0));
287     EXPECT_CALL(callbacks_, OnSuspend(PIPELINE_OK));
288   }
289 
DoSuspend()290   void DoSuspend() {
291     pipeline_->Suspend(base::BindOnce(&CallbackHelper::OnSuspend,
292                                       base::Unretained(&callbacks_)));
293     base::RunLoop().RunUntilIdle();
294     ResetRenderer();
295   }
296 
CreateRenderer(base::Optional<RendererFactoryType>)297   std::unique_ptr<Renderer> CreateRenderer(
298       base::Optional<RendererFactoryType> /* factory_type */) {
299     return std::move(scoped_renderer_);
300   }
301 
ResetRenderer()302   void ResetRenderer() {
303     // |renderer_| has been deleted, replace it.
304     scoped_renderer_.reset(new StrictMock<MockRenderer>());
305     renderer_ = scoped_renderer_.get();
306     EXPECT_CALL(*renderer_, SetPreservesPitch(_)).Times(AnyNumber());
307   }
308 
ExpectResume(const base::TimeDelta & seek_time)309   void ExpectResume(const base::TimeDelta& seek_time) {
310     ExpectRendererInitialization();
311     EXPECT_CALL(*demuxer_, OnSeek(seek_time, _))
312         .WillOnce(RunOnceCallback<1>(PIPELINE_OK));
313     EXPECT_CALL(*renderer_, SetPlaybackRate(_));
314     EXPECT_CALL(*renderer_, SetVolume(_));
315     EXPECT_CALL(*renderer_, StartPlayingFrom(seek_time))
316         .WillOnce(SetBufferingState(&renderer_client_, BUFFERING_HAVE_ENOUGH,
317                                     BUFFERING_CHANGE_REASON_UNKNOWN));
318     EXPECT_CALL(callbacks_,
319                 OnBufferingStateChange(BUFFERING_HAVE_ENOUGH,
320                                        BUFFERING_CHANGE_REASON_UNKNOWN));
321     EXPECT_CALL(callbacks_, OnResume(PIPELINE_OK));
322   }
323 
DoResume(const base::TimeDelta & seek_time)324   void DoResume(const base::TimeDelta& seek_time) {
325     pipeline_->Resume(seek_time, base::BindOnce(&CallbackHelper::OnResume,
326                                                 base::Unretained(&callbacks_)));
327     base::RunLoop().RunUntilIdle();
328   }
329 
ExpectDemuxerStop()330   void ExpectDemuxerStop() {
331     if (demuxer_)
332       EXPECT_CALL(*demuxer_, Stop());
333   }
334 
RunBufferedTimeRangesTest(const base::TimeDelta duration)335   void RunBufferedTimeRangesTest(const base::TimeDelta duration) {
336     EXPECT_EQ(0u, pipeline_->GetBufferedTimeRanges().size());
337     EXPECT_FALSE(pipeline_->DidLoadingProgress());
338 
339     Ranges<base::TimeDelta> ranges;
340     ranges.Add(base::TimeDelta(), duration);
341     demuxer_host_->OnBufferedTimeRangesChanged(ranges);
342     base::RunLoop().RunUntilIdle();
343 
344     EXPECT_TRUE(pipeline_->DidLoadingProgress());
345     EXPECT_FALSE(pipeline_->DidLoadingProgress());
346     EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
347     EXPECT_EQ(base::TimeDelta(), pipeline_->GetBufferedTimeRanges().start(0));
348     EXPECT_EQ(duration, pipeline_->GetBufferedTimeRanges().end(0));
349   }
350 
351   // Fixture members.
352   StrictMock<CallbackHelper> callbacks_;
353   base::SimpleTestTickClock test_tick_clock_;
354   base::test::SingleThreadTaskEnvironment task_environment_;
355   NullMediaLog media_log_;
356   std::unique_ptr<PipelineImpl> pipeline_;
357   NiceMock<MockCdmContext> cdm_context_;
358 
359   std::unique_ptr<StrictMock<MockDemuxer>> demuxer_;
360   DemuxerHost* demuxer_host_;
361   std::unique_ptr<StrictMock<MockRenderer>> scoped_renderer_;
362   StrictMock<MockRenderer>* renderer_;
363   std::unique_ptr<StrictMock<MockDemuxerStream>> audio_stream_;
364   std::unique_ptr<StrictMock<MockDemuxerStream>> video_stream_;
365   std::vector<DemuxerStream*> streams_;
366   RendererClient* renderer_client_;
367   VideoDecoderConfig video_decoder_config_;
368   PipelineMetadata metadata_;
369   base::TimeDelta start_time_;
370 
371  private:
372   DISALLOW_COPY_AND_ASSIGN(PipelineImplTest);
373 };
374 
375 // Test that playback controls methods can be set even before the pipeline is
376 // started.
TEST_F(PipelineImplTest,ControlMethods)377 TEST_F(PipelineImplTest, ControlMethods) {
378   const base::TimeDelta kZero;
379 
380   EXPECT_FALSE(pipeline_->IsRunning());
381 
382   // Initial value.
383   EXPECT_EQ(0.0f, pipeline_->GetPlaybackRate());
384   // Invalid values cannot be set.
385   pipeline_->SetPlaybackRate(-1.0);
386   EXPECT_EQ(0.0f, pipeline_->GetPlaybackRate());
387   // Valid settings should work.
388   pipeline_->SetPlaybackRate(1.0);
389   EXPECT_EQ(1.0f, pipeline_->GetPlaybackRate());
390 
391   // Initial value.
392   EXPECT_EQ(1.0f, pipeline_->GetVolume());
393   // Invalid values cannot be set.
394   pipeline_->SetVolume(-1.0f);
395   EXPECT_EQ(1.0f, pipeline_->GetVolume());
396   // Valid settings should work.
397   pipeline_->SetVolume(0.0f);
398   EXPECT_EQ(0.0f, pipeline_->GetVolume());
399 
400   EXPECT_TRUE(kZero == pipeline_->GetMediaTime());
401   EXPECT_EQ(0u, pipeline_->GetBufferedTimeRanges().size());
402   EXPECT_TRUE(kZero == pipeline_->GetMediaDuration());
403 }
404 
TEST_F(PipelineImplTest,NeverInitializes)405 TEST_F(PipelineImplTest, NeverInitializes) {
406   // Don't execute the callback passed into Initialize().
407   EXPECT_CALL(*demuxer_, OnInitialize(_, _));
408 
409   // This test hangs during initialization by never calling
410   // InitializationComplete().  StrictMock<> will ensure that the callback is
411   // never executed.
412   StartPipeline();
413   base::RunLoop().RunUntilIdle();
414 
415   // Because our callback will get executed when the test tears down, we'll
416   // verify that nothing has been called, then set our expectation for the call
417   // made during tear down.
418   Mock::VerifyAndClear(&callbacks_);
419 }
420 
TEST_F(PipelineImplTest,StopWithoutStart)421 TEST_F(PipelineImplTest, StopWithoutStart) {
422   pipeline_->Stop();
423   base::RunLoop().RunUntilIdle();
424 }
425 
TEST_F(PipelineImplTest,StartThenStopImmediately)426 TEST_F(PipelineImplTest, StartThenStopImmediately) {
427   EXPECT_CALL(*demuxer_, OnInitialize(_, _))
428       .WillOnce(PostCallback<1>(PIPELINE_OK));
429   EXPECT_CALL(*demuxer_, Stop());
430   EXPECT_CALL(callbacks_, OnMetadata(_));
431 
432   EXPECT_CALL(callbacks_, OnStart(_));
433   StartPipeline();
434   base::RunLoop().RunUntilIdle();
435 
436   pipeline_->Stop();
437 }
438 
TEST_F(PipelineImplTest,StartSuspendedAndResumeAudioOnly)439 TEST_F(PipelineImplTest, StartSuspendedAndResumeAudioOnly) {
440   CreateAudioStream();
441   SetDemuxerExpectations(base::TimeDelta::FromSeconds(3000));
442 
443   StartPipelineAndExpect(PIPELINE_OK,
444                          Pipeline::StartType::kSuspendAfterMetadataForAudioOnly,
445                          PostStartStatus::kSuspended);
446   ASSERT_TRUE(pipeline_->IsSuspended());
447 
448   ResetRenderer();
449   base::TimeDelta expected = base::TimeDelta::FromSeconds(2000);
450   ExpectResume(expected);
451   DoResume(expected);
452 }
453 
TEST_F(PipelineImplTest,StartSuspendedAndResumeAudioVideo)454 TEST_F(PipelineImplTest, StartSuspendedAndResumeAudioVideo) {
455   CreateAudioAndVideoStream();
456   SetDemuxerExpectations(base::TimeDelta::FromSeconds(3000));
457 
458   StartPipelineAndExpect(PIPELINE_OK,
459                          Pipeline::StartType::kSuspendAfterMetadata,
460                          PostStartStatus::kSuspended);
461   ASSERT_TRUE(pipeline_->IsSuspended());
462 
463   ResetRenderer();
464   base::TimeDelta expected = base::TimeDelta::FromSeconds(2000);
465   ExpectResume(expected);
466   DoResume(expected);
467 }
468 
TEST_F(PipelineImplTest,StartSuspendedFailsOnVideoWithAudioOnlyExpectation)469 TEST_F(PipelineImplTest, StartSuspendedFailsOnVideoWithAudioOnlyExpectation) {
470   CreateAudioAndVideoStream();
471   SetDemuxerExpectations(base::TimeDelta::FromSeconds(3000));
472 
473   // StartType kSuspendAfterMetadataForAudioOnly only applies to AudioOnly.
474   // Since this playback has video, renderer will be initialized and the
475   // pipeline is not suspended.
476   ExpectRendererInitialization();
477   StartPipelineAndExpect(PIPELINE_OK,
478                          Pipeline::StartType::kSuspendAfterMetadataForAudioOnly,
479                          PostStartStatus::kNormal);
480   ASSERT_FALSE(pipeline_->IsSuspended());
481 }
482 
TEST_F(PipelineImplTest,DemuxerErrorDuringStop)483 TEST_F(PipelineImplTest, DemuxerErrorDuringStop) {
484   CreateAudioStream();
485   SetDemuxerExpectations();
486 
487   StartPipelineAndExpect(PIPELINE_OK);
488   base::RunLoop().RunUntilIdle();
489 
490   EXPECT_CALL(*demuxer_, Stop())
491       .WillOnce(InvokeWithoutArgs(this, &PipelineImplTest::OnDemuxerError));
492   pipeline_->Stop();
493   base::RunLoop().RunUntilIdle();
494 }
495 
TEST_F(PipelineImplTest,NoStreams)496 TEST_F(PipelineImplTest, NoStreams) {
497   EXPECT_CALL(*demuxer_, OnInitialize(_, _))
498       .WillOnce(PostCallback<1>(PIPELINE_OK));
499   EXPECT_CALL(callbacks_, OnMetadata(_));
500 
501   StartPipelineAndExpect(PIPELINE_ERROR_COULD_NOT_RENDER);
502 }
503 
TEST_F(PipelineImplTest,AudioStream)504 TEST_F(PipelineImplTest, AudioStream) {
505   CreateAudioStream();
506   SetDemuxerExpectations();
507 
508   StartPipelineAndExpect(PIPELINE_OK);
509   EXPECT_TRUE(metadata_.has_audio);
510   EXPECT_FALSE(metadata_.has_video);
511 }
512 
TEST_F(PipelineImplTest,VideoStream)513 TEST_F(PipelineImplTest, VideoStream) {
514   CreateVideoStream();
515   SetDemuxerExpectations();
516 
517   StartPipelineAndExpect(PIPELINE_OK);
518   EXPECT_FALSE(metadata_.has_audio);
519   EXPECT_TRUE(metadata_.has_video);
520 }
521 
TEST_F(PipelineImplTest,AudioVideoStream)522 TEST_F(PipelineImplTest, AudioVideoStream) {
523   CreateAudioAndVideoStream();
524   SetDemuxerExpectations();
525 
526   StartPipelineAndExpect(PIPELINE_OK);
527   EXPECT_TRUE(metadata_.has_audio);
528   EXPECT_TRUE(metadata_.has_video);
529 }
530 
TEST_F(PipelineImplTest,EncryptedStream_SetCdmBeforeStart)531 TEST_F(PipelineImplTest, EncryptedStream_SetCdmBeforeStart) {
532   CreateEncryptedVideoStream();
533   SetDemuxerExpectations();
534 
535   SetCdmAndExpect(true);
536   StartPipelineAndExpect(PIPELINE_OK);
537 }
538 
TEST_F(PipelineImplTest,EncryptedStream_SetCdmAfterStart)539 TEST_F(PipelineImplTest, EncryptedStream_SetCdmAfterStart) {
540   CreateEncryptedVideoStream();
541   SetDemuxerExpectations();
542 
543   // Demuxer initialization and metadata reporting don't wait for CDM.
544   EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_));
545 
546   base::RunLoop run_loop;
547   EXPECT_CALL(callbacks_, OnWaiting(_))
548       .WillOnce(RunClosure(run_loop.QuitClosure()));
549   pipeline_->Start(
550       Pipeline::StartType::kNormal, demuxer_.get(), &callbacks_,
551       base::BindOnce(&CallbackHelper::OnStart, base::Unretained(&callbacks_)));
552   run_loop.Run();
553 
554   ExpectRendererInitialization();
555   EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK));
556   SetRendererPostStartExpectations();
557   SetCdmAndExpect(true);
558 }
559 
TEST_F(PipelineImplTest,Seek)560 TEST_F(PipelineImplTest, Seek) {
561   CreateAudioAndVideoStream();
562   SetDemuxerExpectations(base::TimeDelta::FromSeconds(3000));
563 
564   // Initialize then seek!
565   StartPipelineAndExpect(PIPELINE_OK);
566 
567   // Every filter should receive a call to Seek().
568   base::TimeDelta expected = base::TimeDelta::FromSeconds(2000);
569   ExpectSeek(expected, false);
570   DoSeek(expected);
571 }
572 
TEST_F(PipelineImplTest,SeekAfterError)573 TEST_F(PipelineImplTest, SeekAfterError) {
574   CreateAudioStream();
575   SetDemuxerExpectations(base::TimeDelta::FromSeconds(3000));
576 
577   // Initialize then seek!
578   StartPipelineAndExpect(PIPELINE_OK);
579 
580   // Pipeline::Client is supposed to call Pipeline::Stop() after errors.
581   EXPECT_CALL(callbacks_, OnError(_)).WillOnce(Stop(pipeline_.get()));
582   EXPECT_CALL(*demuxer_, Stop());
583   OnDemuxerError();
584   base::RunLoop().RunUntilIdle();
585 
586   EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_INVALID_STATE));
587   pipeline_->Seek(
588       base::TimeDelta::FromMilliseconds(100),
589       base::BindOnce(&CallbackHelper::OnSeek, base::Unretained(&callbacks_)));
590   base::RunLoop().RunUntilIdle();
591 }
592 
TEST_F(PipelineImplTest,SuspendResume)593 TEST_F(PipelineImplTest, SuspendResume) {
594   CreateAudioAndVideoStream();
595   SetDemuxerExpectations(base::TimeDelta::FromSeconds(3000));
596 
597   StartPipelineAndExpect(PIPELINE_OK);
598 
599   // Inject some fake memory usage to verify its cleared after suspend.
600   PipelineStatistics stats;
601   stats.audio_memory_usage = 12345;
602   stats.video_memory_usage = 67890;
603   renderer_client_->OnStatisticsUpdate(stats);
604   base::RunLoop().RunUntilIdle();
605 
606   EXPECT_EQ(stats.audio_memory_usage,
607             pipeline_->GetStatistics().audio_memory_usage);
608   EXPECT_EQ(stats.video_memory_usage,
609             pipeline_->GetStatistics().video_memory_usage);
610 
611   // Make sure the preserves pitch flag is preserved between after resuming.
612   EXPECT_CALL(*renderer_, SetPreservesPitch(false)).Times(1);
613   pipeline_->SetPreservesPitch(false);
614 
615   ExpectSuspend();
616   DoSuspend();
617 
618   EXPECT_EQ(0, pipeline_->GetStatistics().audio_memory_usage);
619   EXPECT_EQ(0, pipeline_->GetStatistics().video_memory_usage);
620 
621   base::TimeDelta expected = base::TimeDelta::FromSeconds(2000);
622   ExpectResume(expected);
623   EXPECT_CALL(*renderer_, SetPreservesPitch(false)).Times(1);
624 
625   DoResume(expected);
626 }
627 
TEST_F(PipelineImplTest,SetVolume)628 TEST_F(PipelineImplTest, SetVolume) {
629   CreateAudioStream();
630   SetDemuxerExpectations();
631 
632   // The audio renderer should receive a call to SetVolume().
633   float expected = 0.5f;
634   EXPECT_CALL(*renderer_, SetVolume(expected));
635 
636   // Initialize then set volume!
637   StartPipelineAndExpect(PIPELINE_OK);
638   pipeline_->SetVolume(expected);
639   base::RunLoop().RunUntilIdle();
640 }
641 
TEST_F(PipelineImplTest,SetVolumeDuringStartup)642 TEST_F(PipelineImplTest, SetVolumeDuringStartup) {
643   CreateAudioStream();
644   SetDemuxerExpectations();
645 
646   // The audio renderer should receive two calls to SetVolume().
647   float expected = 0.5f;
648   EXPECT_CALL(*renderer_, SetVolume(expected)).Times(2);
649   EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK));
650   EXPECT_CALL(callbacks_, OnMetadata(_))
651       .WillOnce(RunOnceClosure(base::BindOnce(&PipelineImpl::SetVolume,
652                                               base::Unretained(pipeline_.get()),
653                                               expected)));
654   ExpectRendererInitialization();
655   EXPECT_CALL(*renderer_, SetPlaybackRate(0.0));
656   EXPECT_CALL(*renderer_, StartPlayingFrom(start_time_))
657       .WillOnce(SetBufferingState(&renderer_client_, BUFFERING_HAVE_ENOUGH,
658                                   BUFFERING_CHANGE_REASON_UNKNOWN));
659   EXPECT_CALL(callbacks_,
660               OnBufferingStateChange(BUFFERING_HAVE_ENOUGH,
661                                      BUFFERING_CHANGE_REASON_UNKNOWN));
662   StartPipeline();
663   base::RunLoop().RunUntilIdle();
664 }
665 
TEST_F(PipelineImplTest,SetPreservesPitch)666 TEST_F(PipelineImplTest, SetPreservesPitch) {
667   CreateAudioStream();
668   SetDemuxerExpectations();
669 
670   // The audio renderer preserve pitch by default.
671   EXPECT_CALL(*renderer_, SetPreservesPitch(true));
672   StartPipelineAndExpect(PIPELINE_OK);
673   base::RunLoop().RunUntilIdle();
674 
675   // Changes to the preservesPitch flag should be propagated.
676   EXPECT_CALL(*renderer_, SetPreservesPitch(false));
677   pipeline_->SetPreservesPitch(false);
678   base::RunLoop().RunUntilIdle();
679 }
680 
TEST_F(PipelineImplTest,Properties)681 TEST_F(PipelineImplTest, Properties) {
682   CreateVideoStream();
683   const auto kDuration = base::TimeDelta::FromSeconds(100);
684   SetDemuxerExpectations(kDuration);
685 
686   StartPipelineAndExpect(PIPELINE_OK);
687   EXPECT_EQ(kDuration.ToInternalValue(),
688             pipeline_->GetMediaDuration().ToInternalValue());
689   EXPECT_FALSE(pipeline_->DidLoadingProgress());
690 }
691 
TEST_F(PipelineImplTest,GetBufferedTimeRanges)692 TEST_F(PipelineImplTest, GetBufferedTimeRanges) {
693   CreateVideoStream();
694   const auto kDuration = base::TimeDelta::FromSeconds(100);
695   SetDemuxerExpectations(kDuration);
696 
697   StartPipelineAndExpect(PIPELINE_OK);
698   RunBufferedTimeRangesTest(kDuration / 8);
699 
700   base::TimeDelta kSeekTime = kDuration / 2;
701   ExpectSeek(kSeekTime, false);
702   DoSeek(kSeekTime);
703 
704   EXPECT_FALSE(pipeline_->DidLoadingProgress());
705 }
706 
TEST_F(PipelineImplTest,BufferedTimeRangesCanChangeAfterStop)707 TEST_F(PipelineImplTest, BufferedTimeRangesCanChangeAfterStop) {
708   EXPECT_CALL(*demuxer_, OnInitialize(_, _))
709       .WillOnce(
710           DoAll(SaveArg<0>(&demuxer_host_), PostCallback<1>(PIPELINE_OK)));
711   EXPECT_CALL(*demuxer_, Stop());
712   EXPECT_CALL(callbacks_, OnMetadata(_));
713   EXPECT_CALL(callbacks_, OnStart(_));
714   StartPipeline();
715   base::RunLoop().RunUntilIdle();
716 
717   pipeline_->Stop();
718   RunBufferedTimeRangesTest(base::TimeDelta::FromSeconds(5));
719 }
720 
TEST_F(PipelineImplTest,OnStatisticsUpdate)721 TEST_F(PipelineImplTest, OnStatisticsUpdate) {
722   CreateAudioAndVideoStream();
723   SetDemuxerExpectations();
724   StartPipelineAndExpect(PIPELINE_OK);
725 
726   PipelineStatistics stats;
727   stats.audio_decoder_info.decoder_name = "TestAudioDecoderName";
728   stats.audio_decoder_info.is_platform_decoder = false;
729   EXPECT_CALL(callbacks_, OnAudioDecoderChange(_));
730   renderer_client_->OnStatisticsUpdate(stats);
731   base::RunLoop().RunUntilIdle();
732 
733   // VideoDecoderInfo changed and we expect OnVideoDecoderChange() to be called.
734   stats.video_decoder_info.decoder_name = "TestVideoDecoderName";
735   stats.video_decoder_info.is_platform_decoder = true;
736   EXPECT_CALL(callbacks_, OnVideoDecoderChange(_));
737   renderer_client_->OnStatisticsUpdate(stats);
738   base::RunLoop().RunUntilIdle();
739 
740   // OnStatisticsUpdate() with the same |stats| should not cause new
741   // PipelineClient calls.
742   renderer_client_->OnStatisticsUpdate(stats);
743   base::RunLoop().RunUntilIdle();
744 
745   // AudioDecoderInfo changed and we expect OnAudioDecoderChange() to be called.
746   stats.audio_decoder_info.is_platform_decoder = true;
747   EXPECT_CALL(callbacks_, OnAudioDecoderChange(_));
748   renderer_client_->OnStatisticsUpdate(stats);
749   base::RunLoop().RunUntilIdle();
750 
751   // Both info changed.
752   stats.audio_decoder_info.decoder_name = "NewTestAudioDecoderName";
753   stats.video_decoder_info.has_decrypting_demuxer_stream = true;
754   EXPECT_CALL(callbacks_, OnAudioDecoderChange(_));
755   EXPECT_CALL(callbacks_, OnVideoDecoderChange(_));
756   renderer_client_->OnStatisticsUpdate(stats);
757   base::RunLoop().RunUntilIdle();
758 }
759 
TEST_F(PipelineImplTest,EndedCallback)760 TEST_F(PipelineImplTest, EndedCallback) {
761   CreateAudioAndVideoStream();
762   SetDemuxerExpectations();
763   StartPipelineAndExpect(PIPELINE_OK);
764 
765   // The ended callback shouldn't run until all renderers have ended.
766   EXPECT_CALL(callbacks_, OnEnded());
767   renderer_client_->OnEnded();
768   base::RunLoop().RunUntilIdle();
769 }
770 
TEST_F(PipelineImplTest,ErrorDuringSeek)771 TEST_F(PipelineImplTest, ErrorDuringSeek) {
772   CreateAudioStream();
773   SetDemuxerExpectations();
774   StartPipelineAndExpect(PIPELINE_OK);
775 
776   double playback_rate = 1.0;
777   EXPECT_CALL(*renderer_, SetPlaybackRate(playback_rate));
778   pipeline_->SetPlaybackRate(playback_rate);
779   base::RunLoop().RunUntilIdle();
780 
781   base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
782 
783   EXPECT_CALL(*renderer_, OnFlush(_)).WillOnce(RunOnceClosure<0>());
784 
785   EXPECT_CALL(*demuxer_, AbortPendingReads());
786   EXPECT_CALL(*demuxer_, OnSeek(seek_time, _))
787       .WillOnce(RunOnceCallback<1>(PIPELINE_ERROR_READ));
788   EXPECT_CALL(*demuxer_, Stop());
789 
790   pipeline_->Seek(seek_time, base::BindOnce(&CallbackHelper::OnSeek,
791                                             base::Unretained(&callbacks_)));
792   EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ))
793       .WillOnce(Stop(pipeline_.get()));
794   base::RunLoop().RunUntilIdle();
795 }
796 
TEST_F(PipelineImplTest,DestroyAfterStop)797 TEST_F(PipelineImplTest, DestroyAfterStop) {
798   CreateAudioStream();
799   SetDemuxerExpectations();
800   StartPipelineAndExpect(PIPELINE_OK);
801 
802   ExpectDemuxerStop();
803   pipeline_->Stop();
804   base::RunLoop().RunUntilIdle();
805 }
806 
TEST_F(PipelineImplTest,Underflow)807 TEST_F(PipelineImplTest, Underflow) {
808   CreateAudioAndVideoStream();
809   SetDemuxerExpectations();
810   StartPipelineAndExpect(PIPELINE_OK);
811 
812   // Simulate underflow.
813   EXPECT_CALL(callbacks_,
814               OnBufferingStateChange(BUFFERING_HAVE_NOTHING,
815                                      BUFFERING_CHANGE_REASON_UNKNOWN));
816   renderer_client_->OnBufferingStateChange(BUFFERING_HAVE_NOTHING,
817                                            BUFFERING_CHANGE_REASON_UNKNOWN);
818   base::RunLoop().RunUntilIdle();
819 
820   // Seek while underflowed.
821   base::TimeDelta expected = base::TimeDelta::FromSeconds(5);
822   ExpectSeek(expected, true);
823   DoSeek(expected);
824 }
825 
TEST_F(PipelineImplTest,PositiveStartTime)826 TEST_F(PipelineImplTest, PositiveStartTime) {
827   start_time_ = base::TimeDelta::FromSeconds(1);
828   EXPECT_CALL(*demuxer_, GetStartTime()).WillRepeatedly(Return(start_time_));
829   CreateAudioStream();
830   SetDemuxerExpectations();
831   StartPipelineAndExpect(PIPELINE_OK);
832   ExpectDemuxerStop();
833   pipeline_->Stop();
834   base::RunLoop().RunUntilIdle();
835 }
836 
TEST_F(PipelineImplTest,GetMediaTime)837 TEST_F(PipelineImplTest, GetMediaTime) {
838   CreateAudioStream();
839   SetDemuxerExpectations();
840   StartPipelineAndExpect(PIPELINE_OK);
841 
842   // Pipeline should report the same media time returned by the renderer.
843   base::TimeDelta kMediaTime = base::TimeDelta::FromSeconds(2);
844   EXPECT_CALL(*renderer_, GetMediaTime()).WillRepeatedly(Return(kMediaTime));
845   EXPECT_EQ(kMediaTime, pipeline_->GetMediaTime());
846 
847   // Media time should not go backwards even if the renderer returns an
848   // errorneous value. PipelineImpl should clamp it to last reported value.
849   EXPECT_CALL(*renderer_, GetMediaTime())
850       .WillRepeatedly(Return(base::TimeDelta::FromSeconds(1)));
851   EXPECT_EQ(kMediaTime, pipeline_->GetMediaTime());
852 }
853 
854 // Seeking posts a task from main thread to media thread to seek the renderer,
855 // resetting its internal clock. Calling GetMediaTime() should be safe even
856 // when the renderer has not performed the seek (simulated by its continuing
857 // to return the pre-seek time). Verifies fix for http://crbug.com/675556
TEST_F(PipelineImplTest,GetMediaTimeAfterSeek)858 TEST_F(PipelineImplTest, GetMediaTimeAfterSeek) {
859   CreateAudioStream();
860   SetDemuxerExpectations();
861   StartPipelineAndExpect(PIPELINE_OK);
862 
863   // Pipeline should report the same media time returned by the renderer.
864   base::TimeDelta kMediaTime = base::TimeDelta::FromSeconds(2);
865   EXPECT_CALL(*renderer_, GetMediaTime()).WillRepeatedly(Return(kMediaTime));
866   EXPECT_EQ(kMediaTime, pipeline_->GetMediaTime());
867 
868   // Seek backward 1 second. Do not run RunLoop to ensure renderer is not yet
869   // notified of the seek (via media thread).
870   base::TimeDelta kSeekTime = kMediaTime - base::TimeDelta::FromSeconds(1);
871   ExpectSeek(kSeekTime, false);
872   pipeline_->Seek(kSeekTime, base::BindOnce(&CallbackHelper::OnSeek,
873                                             base::Unretained(&callbacks_)));
874 
875   // Verify pipeline returns the seek time in spite of renderer returning the
876   // stale media time.
877   EXPECT_EQ(kSeekTime, pipeline_->GetMediaTime());
878   EXPECT_EQ(kMediaTime, renderer_->GetMediaTime());
879 
880   // Allow seek task to post to the renderer.
881   base::RunLoop().RunUntilIdle();
882 
883   // With seek completed, pipeline should again return the renderer's media time
884   // (as long as media time is moving forward).
885   EXPECT_EQ(kMediaTime, pipeline_->GetMediaTime());
886 }
887 
888 // This test makes sure that, after receiving an error, stopping and starting
889 // the pipeline clears all internal error state, and allows errors to be
890 // propagated again.
TEST_F(PipelineImplTest,RendererErrorsReset)891 TEST_F(PipelineImplTest, RendererErrorsReset) {
892   // Basic setup
893   CreateAudioStream();
894   SetDemuxerExpectations();
895   StartPipelineAndExpect(PIPELINE_OK);
896 
897   // Trigger two errors. The second error will be ignored.
898   EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ)).Times(1);
899   renderer_client_->OnError(PIPELINE_ERROR_READ);
900   renderer_client_->OnError(PIPELINE_ERROR_READ);
901 
902   base::RunLoop().RunUntilIdle();
903 
904   // Stopping the demuxer should clear internal state.
905   EXPECT_CALL(*demuxer_, Stop());
906   pipeline_->Stop();
907 
908   base::RunLoop().RunUntilIdle();
909 
910   ResetRenderer();
911   SetDemuxerExpectations();
912   StartPipelineAndExpect(PIPELINE_OK);
913 
914   // New errors should propagate and not be ignored.
915   EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ)).Times(1);
916   renderer_client_->OnError(PIPELINE_ERROR_READ);
917 
918   base::RunLoop().RunUntilIdle();
919 }
920 
921 class PipelineTeardownTest : public PipelineImplTest {
922  public:
923   enum TeardownState {
924     kInitDemuxer,
925     kInitRenderer,
926     kFlushing,
927     kSeeking,
928     kPlaying,
929     kSuspending,
930     kSuspended,
931     kResuming,
932   };
933 
934   enum StopOrError {
935     kStop,
936     kError,
937     kErrorAndStop,
938   };
939 
940   PipelineTeardownTest() = default;
941   ~PipelineTeardownTest() override = default;
942 
RunTest(TeardownState state,StopOrError stop_or_error)943   void RunTest(TeardownState state, StopOrError stop_or_error) {
944     switch (state) {
945       case kInitDemuxer:
946       case kInitRenderer:
947         DoInitialize(state, stop_or_error);
948         break;
949 
950       case kFlushing:
951       case kSeeking:
952         DoInitialize(state, stop_or_error);
953         DoSeek(state, stop_or_error);
954         break;
955 
956       case kPlaying:
957         DoInitialize(state, stop_or_error);
958         DoStopOrError(stop_or_error, true);
959         break;
960 
961       case kSuspending:
962       case kSuspended:
963       case kResuming:
964         DoInitialize(state, stop_or_error);
965         DoSuspend(state, stop_or_error);
966         break;
967     }
968   }
969 
970  private:
971   // TODO(scherkus): We do radically different things whether teardown is
972   // invoked via stop vs error. The teardown path should be the same,
973   // see http://crbug.com/110228
DoInitialize(TeardownState state,StopOrError stop_or_error)974   void DoInitialize(TeardownState state, StopOrError stop_or_error) {
975     SetInitializeExpectations(state, stop_or_error);
976     StartPipeline();
977     base::RunLoop().RunUntilIdle();
978   }
979 
SetInitializeExpectations(TeardownState state,StopOrError stop_or_error)980   void SetInitializeExpectations(TeardownState state,
981                                  StopOrError stop_or_error) {
982     if (state == kInitDemuxer) {
983       if (stop_or_error == kStop) {
984         EXPECT_CALL(*demuxer_, OnInitialize(_, _))
985             .WillOnce(
986                 DoAll(PostStop(pipeline_.get()), PostCallback<1>(PIPELINE_OK)));
987         // Note: OnStart callback is not called after pipeline is stopped.
988       } else {
989         EXPECT_CALL(*demuxer_, OnInitialize(_, _))
990             .WillOnce(PostCallback<1>(DEMUXER_ERROR_COULD_NOT_OPEN));
991         EXPECT_CALL(callbacks_, OnStart(DEMUXER_ERROR_COULD_NOT_OPEN))
992             .WillOnce(Stop(pipeline_.get()));
993       }
994 
995       EXPECT_CALL(*demuxer_, Stop());
996       return;
997     }
998 
999     CreateAudioStream();
1000     CreateVideoStream();
1001     SetDemuxerExpectations(base::TimeDelta::FromSeconds(3000));
1002     EXPECT_CALL(*renderer_, SetVolume(1.0f));
1003 
1004     if (state == kInitRenderer) {
1005       if (stop_or_error == kStop) {
1006         EXPECT_CALL(*renderer_, OnInitialize(_, _, _))
1007             .WillOnce(
1008                 DoAll(PostStop(pipeline_.get()), PostCallback<2>(PIPELINE_OK)));
1009         // Note: OnStart is not callback after pipeline is stopped.
1010       } else {
1011         EXPECT_CALL(*renderer_, OnInitialize(_, _, _))
1012             .WillOnce(PostCallback<2>(PIPELINE_ERROR_INITIALIZATION_FAILED));
1013         EXPECT_CALL(callbacks_, OnStart(PIPELINE_ERROR_INITIALIZATION_FAILED))
1014             .WillOnce(Stop(pipeline_.get()));
1015       }
1016 
1017       EXPECT_CALL(callbacks_, OnMetadata(_));
1018       EXPECT_CALL(*demuxer_, Stop());
1019       return;
1020     }
1021 
1022     EXPECT_CALL(*renderer_, OnInitialize(_, _, _))
1023         .WillOnce(
1024             DoAll(SaveArg<1>(&renderer_client_), PostCallback<2>(PIPELINE_OK)));
1025 
1026     // If we get here it's a successful initialization.
1027     EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK));
1028     EXPECT_CALL(callbacks_, OnMetadata(_));
1029 
1030     EXPECT_CALL(*renderer_, SetPlaybackRate(0.0));
1031     EXPECT_CALL(*renderer_, StartPlayingFrom(base::TimeDelta()))
1032         .WillOnce(SetBufferingState(&renderer_client_, BUFFERING_HAVE_ENOUGH,
1033                                     BUFFERING_CHANGE_REASON_UNKNOWN));
1034     EXPECT_CALL(callbacks_,
1035                 OnBufferingStateChange(BUFFERING_HAVE_ENOUGH,
1036                                        BUFFERING_CHANGE_REASON_UNKNOWN));
1037   }
1038 
DoSeek(TeardownState state,StopOrError stop_or_error)1039   void DoSeek(TeardownState state, StopOrError stop_or_error) {
1040     SetSeekExpectations(state, stop_or_error);
1041 
1042     EXPECT_CALL(*demuxer_, AbortPendingReads());
1043     EXPECT_CALL(*demuxer_, Stop());
1044 
1045     pipeline_->Seek(
1046         base::TimeDelta::FromSeconds(10),
1047         base::BindOnce(&CallbackHelper::OnSeek, base::Unretained(&callbacks_)));
1048     base::RunLoop().RunUntilIdle();
1049   }
1050 
SetSeekExpectations(TeardownState state,StopOrError stop_or_error)1051   void SetSeekExpectations(TeardownState state, StopOrError stop_or_error) {
1052     if (state == kFlushing) {
1053       EXPECT_CALL(*demuxer_, OnSeek(_, _));
1054       if (stop_or_error == kStop) {
1055         EXPECT_CALL(*renderer_, OnFlush(_))
1056             .WillOnce(DoAll(Stop(pipeline_.get()), RunOnceClosure<0>()));
1057         // Note: OnSeek callbacks are not called
1058         // after pipeline is stopped.
1059       } else {
1060         EXPECT_CALL(*renderer_, OnFlush(_))
1061             .WillOnce(DoAll(SetError(&renderer_client_, PIPELINE_ERROR_READ),
1062                             RunOnceClosure<0>()));
1063         EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ))
1064             .WillOnce(Stop(pipeline_.get()));
1065       }
1066       return;
1067     }
1068 
1069     EXPECT_CALL(*renderer_, OnFlush(_)).WillOnce(RunOnceClosure<0>());
1070 
1071     if (state == kSeeking) {
1072       if (stop_or_error == kStop) {
1073         EXPECT_CALL(*demuxer_, OnSeek(_, _))
1074             .WillOnce(DoAll(PostStop(pipeline_.get()),
1075                             RunOnceCallback<1>(PIPELINE_OK)));
1076         // Note: OnSeek callback is not called after pipeline is stopped.
1077       } else {
1078         EXPECT_CALL(*demuxer_, OnSeek(_, _))
1079             .WillOnce(RunOnceCallback<1>(PIPELINE_ERROR_READ));
1080         EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ))
1081             .WillOnce(Stop(pipeline_.get()));
1082       }
1083       return;
1084     }
1085 
1086     NOTREACHED() << "State not supported: " << state;
1087   }
1088 
DoSuspend(TeardownState state,StopOrError stop_or_error)1089   void DoSuspend(TeardownState state, StopOrError stop_or_error) {
1090     SetSuspendExpectations(state, stop_or_error);
1091 
1092     if (state == kResuming) {
1093       EXPECT_CALL(*demuxer_, Stop());
1094     }
1095 
1096     PipelineImplTest::DoSuspend();
1097 
1098     if (state == kResuming) {
1099       PipelineImplTest::DoResume(base::TimeDelta());
1100       return;
1101     }
1102 
1103     // kSuspended, kSuspending never throw errors, since Resume() is always able
1104     // to restore the pipeline to a pristine state.
1105     DoStopOrError(stop_or_error, false);
1106   }
1107 
SetSuspendExpectations(TeardownState state,StopOrError stop_or_error)1108   void SetSuspendExpectations(TeardownState state, StopOrError stop_or_error) {
1109     EXPECT_CALL(*renderer_, SetPlaybackRate(0));
1110     EXPECT_CALL(*demuxer_, AbortPendingReads());
1111     EXPECT_CALL(callbacks_, OnSuspend(PIPELINE_OK));
1112     if (state == kResuming) {
1113       if (stop_or_error == kStop) {
1114         EXPECT_CALL(*demuxer_, OnSeek(_, _))
1115             .WillOnce(DoAll(PostStop(pipeline_.get()),
1116                             RunOnceCallback<1>(PIPELINE_OK)));
1117         // Note: OnResume callback is not called after pipeline is stopped.
1118       } else {
1119         EXPECT_CALL(*demuxer_, OnSeek(_, _))
1120             .WillOnce(RunOnceCallback<1>(PIPELINE_ERROR_READ));
1121         EXPECT_CALL(callbacks_, OnResume(PIPELINE_ERROR_READ))
1122             .WillOnce(Stop(pipeline_.get()));
1123       }
1124     } else if (state != kSuspended && state != kSuspending) {
1125       NOTREACHED() << "State not supported: " << state;
1126     }
1127   }
1128 
DoStopOrError(StopOrError stop_or_error,bool expect_errors)1129   void DoStopOrError(StopOrError stop_or_error, bool expect_errors) {
1130     switch (stop_or_error) {
1131       case kStop:
1132         EXPECT_CALL(*demuxer_, Stop());
1133         pipeline_->Stop();
1134         break;
1135 
1136       case kError:
1137         if (expect_errors) {
1138           EXPECT_CALL(*demuxer_, Stop());
1139           EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ))
1140               .WillOnce(Stop(pipeline_.get()));
1141         }
1142         renderer_client_->OnError(PIPELINE_ERROR_READ);
1143         break;
1144 
1145       case kErrorAndStop:
1146         EXPECT_CALL(*demuxer_, Stop());
1147         if (expect_errors)
1148           EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ));
1149         renderer_client_->OnError(PIPELINE_ERROR_READ);
1150         base::RunLoop().RunUntilIdle();
1151         pipeline_->Stop();
1152         break;
1153     }
1154 
1155     base::RunLoop().RunUntilIdle();
1156   }
1157 
1158   DISALLOW_COPY_AND_ASSIGN(PipelineTeardownTest);
1159 };
1160 
1161 #define INSTANTIATE_TEARDOWN_TEST(stop_or_error, state)   \
1162   TEST_F(PipelineTeardownTest, stop_or_error##_##state) { \
1163     RunTest(k##state, k##stop_or_error);                  \
1164   }
1165 
1166 INSTANTIATE_TEARDOWN_TEST(Stop, InitDemuxer)
1167 INSTANTIATE_TEARDOWN_TEST(Stop, InitRenderer)
1168 INSTANTIATE_TEARDOWN_TEST(Stop, Flushing)
1169 INSTANTIATE_TEARDOWN_TEST(Stop, Seeking)
1170 INSTANTIATE_TEARDOWN_TEST(Stop, Playing)
1171 INSTANTIATE_TEARDOWN_TEST(Stop, Suspending)
1172 INSTANTIATE_TEARDOWN_TEST(Stop, Suspended)
1173 INSTANTIATE_TEARDOWN_TEST(Stop, Resuming)
1174 
1175 INSTANTIATE_TEARDOWN_TEST(Error, InitDemuxer)
1176 INSTANTIATE_TEARDOWN_TEST(Error, InitRenderer)
1177 INSTANTIATE_TEARDOWN_TEST(Error, Flushing)
1178 INSTANTIATE_TEARDOWN_TEST(Error, Seeking)
1179 INSTANTIATE_TEARDOWN_TEST(Error, Playing)
1180 INSTANTIATE_TEARDOWN_TEST(Error, Suspending)
1181 INSTANTIATE_TEARDOWN_TEST(Error, Suspended)
1182 INSTANTIATE_TEARDOWN_TEST(Error, Resuming)
1183 
1184 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing)
1185 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Suspended)
1186 
1187 }  // namespace media
1188