| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/base/pipeline_impl.h" | 5 #include "media/base/pipeline_impl.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 using ::testing::SaveArg; | 41 using ::testing::SaveArg; |
| 42 using ::testing::StrictMock; | 42 using ::testing::StrictMock; |
| 43 using ::testing::WithArg; | 43 using ::testing::WithArg; |
| 44 | 44 |
| 45 namespace media { | 45 namespace media { |
| 46 | 46 |
| 47 ACTION_P(SetDemuxerProperties, duration) { | 47 ACTION_P(SetDemuxerProperties, duration) { |
| 48 arg0->SetDuration(duration); | 48 arg0->SetDuration(duration); |
| 49 } | 49 } |
| 50 | 50 |
| 51 ACTION_P2(Stop, pipeline, stop_cb) { | 51 ACTION_P(Stop, pipeline) { |
| 52 pipeline->Stop(stop_cb); | 52 pipeline->Stop(); |
| 53 } | 53 } |
| 54 | 54 |
| 55 ACTION_P2(SetError, pipeline, status) { | 55 ACTION_P2(SetError, pipeline, status) { |
| 56 pipeline->SetErrorForTesting(status); | 56 pipeline->SetErrorForTesting(status); |
| 57 } | 57 } |
| 58 | 58 |
| 59 ACTION_P2(SetBufferingState, cb, buffering_state) { | 59 ACTION_P2(SetBufferingState, cb, buffering_state) { |
| 60 cb->Run(buffering_state); | 60 cb->Run(buffering_state); |
| 61 } | 61 } |
| 62 | 62 |
| 63 ACTION_TEMPLATE(PostCallback, | 63 ACTION_TEMPLATE(PostCallback, |
| 64 HAS_1_TEMPLATE_PARAMS(int, k), | 64 HAS_1_TEMPLATE_PARAMS(int, k), |
| 65 AND_1_VALUE_PARAMS(p0)) { | 65 AND_1_VALUE_PARAMS(p0)) { |
| 66 return base::MessageLoop::current()->PostTask( | 66 return base::MessageLoop::current()->PostTask( |
| 67 FROM_HERE, base::Bind(::std::tr1::get<k>(args), p0)); | 67 FROM_HERE, base::Bind(::std::tr1::get<k>(args), p0)); |
| 68 } | 68 } |
| 69 | 69 |
| 70 // TODO(scherkus): even though some filters are initialized on separate | 70 // TODO(scherkus): even though some filters are initialized on separate |
| 71 // threads these test aren't flaky... why? It's because filters' Initialize() | 71 // threads these test aren't flaky... why? It's because filters' Initialize() |
| 72 // is executed on |message_loop_| and the mock filters instantly call | 72 // is executed on |message_loop_| and the mock filters instantly call |
| 73 // InitializationComplete(), which keeps the pipeline humming along. If | 73 // InitializationComplete(), which keeps the pipeline humming along. If |
| 74 // either filters don't call InitializationComplete() immediately or filter | 74 // either filters don't call InitializationComplete() immediately or filter |
| 75 // initialization is moved to a separate thread this test will become flaky. | 75 // initialization is moved to a separate thread this test will become flaky. |
| 76 class PipelineImplTest : public ::testing::Test { | 76 class PipelineImplTest : public ::testing::Test { |
| 77 public: | 77 public: |
| 78 // Used for setting expectations on pipeline callbacks. Using a StrictMock | 78 // Used for setting expectations on pipeline callbacks. Using a StrictMock |
| 79 // also lets us test for missing callbacks. | 79 // also lets us test for missing callbacks. |
| 80 class CallbackHelper { | 80 class CallbackHelper : public Pipeline::Client { |
| 81 public: | 81 public: |
| 82 CallbackHelper() {} | 82 CallbackHelper() {} |
| 83 virtual ~CallbackHelper() {} | 83 virtual ~CallbackHelper() {} |
| 84 | 84 |
| 85 MOCK_METHOD1(OnStart, void(PipelineStatus)); | 85 MOCK_METHOD1(OnStart, void(PipelineStatus)); |
| 86 MOCK_METHOD1(OnSeek, void(PipelineStatus)); | 86 MOCK_METHOD1(OnSeek, void(PipelineStatus)); |
| 87 MOCK_METHOD1(OnSuspend, void(PipelineStatus)); | 87 MOCK_METHOD1(OnSuspend, void(PipelineStatus)); |
| 88 MOCK_METHOD1(OnResume, void(PipelineStatus)); | 88 MOCK_METHOD1(OnResume, void(PipelineStatus)); |
| 89 MOCK_METHOD0(OnStop, void()); | 89 |
| 90 // Pipeline::Client overrides. |
| 91 MOCK_METHOD1(OnError, void(PipelineStatus)); |
| 90 MOCK_METHOD0(OnEnded, void()); | 92 MOCK_METHOD0(OnEnded, void()); |
| 91 MOCK_METHOD1(OnError, void(PipelineStatus)); | |
| 92 MOCK_METHOD1(OnMetadata, void(PipelineMetadata)); | 93 MOCK_METHOD1(OnMetadata, void(PipelineMetadata)); |
| 93 MOCK_METHOD1(OnBufferingStateChange, void(BufferingState)); | 94 MOCK_METHOD1(OnBufferingStateChange, void(BufferingState)); |
| 94 MOCK_METHOD0(OnDurationChange, void()); | 95 MOCK_METHOD0(OnDurationChange, void()); |
| 96 MOCK_METHOD2(OnAddTextTrack, |
| 97 void(const TextTrackConfig&, const AddTextTrackDoneCB&)); |
| 98 MOCK_METHOD0(OnWaitingForDecryptionKey, void()); |
| 95 | 99 |
| 96 private: | 100 private: |
| 97 DISALLOW_COPY_AND_ASSIGN(CallbackHelper); | 101 DISALLOW_COPY_AND_ASSIGN(CallbackHelper); |
| 98 }; | 102 }; |
| 99 | 103 |
| 100 PipelineImplTest() | 104 PipelineImplTest() |
| 101 : pipeline_( | 105 : pipeline_( |
| 102 new PipelineImpl(message_loop_.task_runner(), new MediaLog())), | 106 new PipelineImpl(message_loop_.task_runner(), new MediaLog())), |
| 103 demuxer_(new StrictMock<MockDemuxer>()), | 107 demuxer_(new StrictMock<MockDemuxer>()), |
| 104 scoped_renderer_(new StrictMock<MockRenderer>()), | 108 scoped_renderer_(new StrictMock<MockRenderer>()), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 123 | 127 |
| 124 ExpectDemuxerStop(); | 128 ExpectDemuxerStop(); |
| 125 | 129 |
| 126 // The mock demuxer doesn't stop the fake text track stream, | 130 // The mock demuxer doesn't stop the fake text track stream, |
| 127 // so just stop it manually. | 131 // so just stop it manually. |
| 128 if (text_stream_) { | 132 if (text_stream_) { |
| 129 text_stream_->Stop(); | 133 text_stream_->Stop(); |
| 130 message_loop_.RunUntilIdle(); | 134 message_loop_.RunUntilIdle(); |
| 131 } | 135 } |
| 132 | 136 |
| 133 // Expect a stop callback if we were started. | |
| 134 ExpectPipelineStopAndDestroyPipeline(); | |
| 135 pipeline_->Stop( | |
| 136 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | |
| 137 message_loop_.RunUntilIdle(); | 137 message_loop_.RunUntilIdle(); |
| 138 pipeline_->Stop(); |
| 139 DestroyPipeline(); |
| 138 } | 140 } |
| 139 | 141 |
| 140 void OnDemuxerError() { | 142 void OnDemuxerError() { |
| 141 // Cast because OnDemuxerError is private in Pipeline. | 143 // Cast because OnDemuxerError is private in Pipeline. |
| 142 static_cast<DemuxerHost*>(pipeline_.get()) | 144 static_cast<DemuxerHost*>(pipeline_.get()) |
| 143 ->OnDemuxerError(PIPELINE_ERROR_ABORT); | 145 ->OnDemuxerError(PIPELINE_ERROR_ABORT); |
| 144 } | 146 } |
| 145 | 147 |
| 146 protected: | 148 protected: |
| 147 // Sets up expectations to allow the demuxer to initialize. | 149 // Sets up expectations to allow the demuxer to initialize. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 177 void SetRendererExpectations() { | 179 void SetRendererExpectations() { |
| 178 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) | 180 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) |
| 179 .WillOnce(DoAll(SaveArg<2>(&statistics_cb_), | 181 .WillOnce(DoAll(SaveArg<2>(&statistics_cb_), |
| 180 SaveArg<3>(&buffering_state_cb_), | 182 SaveArg<3>(&buffering_state_cb_), |
| 181 SaveArg<4>(&ended_cb_), PostCallback<1>(PIPELINE_OK))); | 183 SaveArg<4>(&ended_cb_), PostCallback<1>(PIPELINE_OK))); |
| 182 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(audio_stream())); | 184 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(audio_stream())); |
| 183 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(video_stream())); | 185 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(video_stream())); |
| 184 } | 186 } |
| 185 | 187 |
| 186 void AddTextStream() { | 188 void AddTextStream() { |
| 187 EXPECT_CALL(*this, OnAddTextTrack(_, _)) | 189 EXPECT_CALL(callbacks_, OnAddTextTrack(_, _)) |
| 188 .WillOnce(Invoke(this, &PipelineImplTest::DoOnAddTextTrack)); | 190 .WillOnce(Invoke(this, &PipelineImplTest::DoOnAddTextTrack)); |
| 189 static_cast<DemuxerHost*>(pipeline_.get()) | 191 static_cast<DemuxerHost*>(pipeline_.get()) |
| 190 ->AddTextStream(text_stream(), | 192 ->AddTextStream(text_stream(), |
| 191 TextTrackConfig(kTextSubtitles, "", "", "")); | 193 TextTrackConfig(kTextSubtitles, "", "", "")); |
| 192 message_loop_.RunUntilIdle(); | 194 message_loop_.RunUntilIdle(); |
| 193 } | 195 } |
| 194 | 196 |
| 195 void StartPipeline() { | 197 void StartPipeline() { |
| 196 EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0); | 198 EXPECT_CALL(callbacks_, OnWaitingForDecryptionKey()).Times(0); |
| 197 pipeline_->Start( | 199 pipeline_->Start( |
| 198 demuxer_.get(), std::move(scoped_renderer_), | 200 demuxer_.get(), std::move(scoped_renderer_), &callbacks_, |
| 199 base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)), | 201 base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_))); |
| 200 base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)), | |
| 201 base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)), | |
| 202 base::Bind(&CallbackHelper::OnMetadata, base::Unretained(&callbacks_)), | |
| 203 base::Bind(&CallbackHelper::OnBufferingStateChange, | |
| 204 base::Unretained(&callbacks_)), | |
| 205 base::Bind(&CallbackHelper::OnDurationChange, | |
| 206 base::Unretained(&callbacks_)), | |
| 207 base::Bind(&PipelineImplTest::OnAddTextTrack, base::Unretained(this)), | |
| 208 base::Bind(&PipelineImplTest::OnWaitingForDecryptionKey, | |
| 209 base::Unretained(this))); | |
| 210 } | 202 } |
| 211 | 203 |
| 212 // Sets up expectations on the callback and initializes the pipeline. Called | 204 // Sets up expectations on the callback and initializes the pipeline. Called |
| 213 // after tests have set expectations any filters they wish to use. | 205 // after tests have set expectations any filters they wish to use. |
| 214 void StartPipelineAndExpect(PipelineStatus start_status) { | 206 void StartPipelineAndExpect(PipelineStatus start_status) { |
| 215 EXPECT_CALL(callbacks_, OnStart(start_status)); | 207 EXPECT_CALL(callbacks_, OnStart(start_status)); |
| 216 | 208 |
| 217 if (start_status == PIPELINE_OK) { | 209 if (start_status == PIPELINE_OK) { |
| 218 EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_)); | 210 EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_)); |
| 219 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0)); | 211 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0)); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 // pointers must have been invalidated before the stop callback returns. | 312 // pointers must have been invalidated before the stop callback returns. |
| 321 DCHECK(!pipeline_->HasWeakPtrsForTesting()); | 313 DCHECK(!pipeline_->HasWeakPtrsForTesting()); |
| 322 pipeline_.reset(); | 314 pipeline_.reset(); |
| 323 } | 315 } |
| 324 | 316 |
| 325 void ExpectDemuxerStop() { | 317 void ExpectDemuxerStop() { |
| 326 if (demuxer_) | 318 if (demuxer_) |
| 327 EXPECT_CALL(*demuxer_, Stop()); | 319 EXPECT_CALL(*demuxer_, Stop()); |
| 328 } | 320 } |
| 329 | 321 |
| 330 void ExpectPipelineStopAndDestroyPipeline() { | |
| 331 // After the Pipeline is stopped, it could be destroyed any time. Always | |
| 332 // destroy the pipeline immediately after OnStop() to test this. | |
| 333 EXPECT_CALL(callbacks_, OnStop()) | |
| 334 .WillOnce(Invoke(this, &PipelineImplTest::DestroyPipeline)); | |
| 335 } | |
| 336 | |
| 337 MOCK_METHOD2(OnAddTextTrack, | |
| 338 void(const TextTrackConfig&, const AddTextTrackDoneCB&)); | |
| 339 MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); | |
| 340 | |
| 341 void DoOnAddTextTrack(const TextTrackConfig& config, | 322 void DoOnAddTextTrack(const TextTrackConfig& config, |
| 342 const AddTextTrackDoneCB& done_cb) { | 323 const AddTextTrackDoneCB& done_cb) { |
| 343 std::unique_ptr<TextTrack> text_track(new MockTextTrack); | 324 std::unique_ptr<TextTrack> text_track(new MockTextTrack); |
| 344 done_cb.Run(std::move(text_track)); | 325 done_cb.Run(std::move(text_track)); |
| 345 } | 326 } |
| 346 | 327 |
| 347 void RunBufferedTimeRangesTest(const base::TimeDelta duration) { | 328 void RunBufferedTimeRangesTest(const base::TimeDelta duration) { |
| 348 EXPECT_EQ(0u, pipeline_->GetBufferedTimeRanges().size()); | 329 EXPECT_EQ(0u, pipeline_->GetBufferedTimeRanges().size()); |
| 349 EXPECT_FALSE(pipeline_->DidLoadingProgress()); | 330 EXPECT_FALSE(pipeline_->DidLoadingProgress()); |
| 350 Ranges<base::TimeDelta> ranges; | 331 Ranges<base::TimeDelta> ranges; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 // This test hangs during initialization by never calling | 396 // This test hangs during initialization by never calling |
| 416 // InitializationComplete(). StrictMock<> will ensure that the callback is | 397 // InitializationComplete(). StrictMock<> will ensure that the callback is |
| 417 // never executed. | 398 // never executed. |
| 418 StartPipeline(); | 399 StartPipeline(); |
| 419 message_loop_.RunUntilIdle(); | 400 message_loop_.RunUntilIdle(); |
| 420 | 401 |
| 421 // Because our callback will get executed when the test tears down, we'll | 402 // Because our callback will get executed when the test tears down, we'll |
| 422 // verify that nothing has been called, then set our expectation for the call | 403 // verify that nothing has been called, then set our expectation for the call |
| 423 // made during tear down. | 404 // made during tear down. |
| 424 Mock::VerifyAndClear(&callbacks_); | 405 Mock::VerifyAndClear(&callbacks_); |
| 425 EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK)); | |
| 426 } | 406 } |
| 427 | 407 |
| 428 TEST_F(PipelineImplTest, StopWithoutStart) { | 408 TEST_F(PipelineImplTest, StopWithoutStart) { |
| 429 ExpectPipelineStopAndDestroyPipeline(); | 409 pipeline_->Stop(); |
| 430 pipeline_->Stop( | |
| 431 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | |
| 432 message_loop_.RunUntilIdle(); | 410 message_loop_.RunUntilIdle(); |
| 433 } | 411 } |
| 434 | 412 |
| 435 TEST_F(PipelineImplTest, StartThenStopImmediately) { | 413 TEST_F(PipelineImplTest, StartThenStopImmediately) { |
| 436 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 414 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
| 437 .WillOnce(PostCallback<1>(PIPELINE_OK)); | 415 .WillOnce(PostCallback<1>(PIPELINE_OK)); |
| 438 EXPECT_CALL(*demuxer_, Stop()); | 416 EXPECT_CALL(*demuxer_, Stop()); |
| 417 EXPECT_CALL(callbacks_, OnMetadata(_)); |
| 439 | 418 |
| 440 EXPECT_CALL(callbacks_, OnStart(_)); | 419 EXPECT_CALL(callbacks_, OnStart(_)); |
| 441 StartPipeline(); | 420 StartPipeline(); |
| 421 message_loop_.RunUntilIdle(); |
| 442 | 422 |
| 443 // Expect a stop callback if we were started. | 423 pipeline_->Stop(); |
| 444 ExpectPipelineStopAndDestroyPipeline(); | |
| 445 pipeline_->Stop( | |
| 446 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | |
| 447 message_loop_.RunUntilIdle(); | |
| 448 } | 424 } |
| 449 | 425 |
| 450 TEST_F(PipelineImplTest, DemuxerErrorDuringStop) { | 426 TEST_F(PipelineImplTest, DemuxerErrorDuringStop) { |
| 451 CreateAudioStream(); | 427 CreateAudioStream(); |
| 452 MockDemuxerStreamVector streams; | 428 MockDemuxerStreamVector streams; |
| 453 streams.push_back(audio_stream()); | 429 streams.push_back(audio_stream()); |
| 454 | 430 |
| 455 SetDemuxerExpectations(&streams); | 431 SetDemuxerExpectations(&streams); |
| 456 SetRendererExpectations(); | 432 SetRendererExpectations(); |
| 457 | 433 |
| 458 StartPipelineAndExpect(PIPELINE_OK); | 434 StartPipelineAndExpect(PIPELINE_OK); |
| 435 message_loop_.RunUntilIdle(); |
| 459 | 436 |
| 460 EXPECT_CALL(*demuxer_, Stop()) | 437 EXPECT_CALL(*demuxer_, Stop()) |
| 461 .WillOnce(InvokeWithoutArgs(this, &PipelineImplTest::OnDemuxerError)); | 438 .WillOnce(InvokeWithoutArgs(this, &PipelineImplTest::OnDemuxerError)); |
| 462 ExpectPipelineStopAndDestroyPipeline(); | 439 pipeline_->Stop(); |
| 463 | |
| 464 pipeline_->Stop( | |
| 465 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | |
| 466 message_loop_.RunUntilIdle(); | |
| 467 } | 440 } |
| 468 | 441 |
| 469 TEST_F(PipelineImplTest, NoStreams) { | 442 TEST_F(PipelineImplTest, NoStreams) { |
| 470 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 443 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
| 471 .WillOnce(PostCallback<1>(PIPELINE_OK)); | 444 .WillOnce(PostCallback<1>(PIPELINE_OK)); |
| 472 EXPECT_CALL(*demuxer_, Stop()); | 445 EXPECT_CALL(*demuxer_, Stop()); |
| 473 EXPECT_CALL(callbacks_, OnMetadata(_)); | 446 EXPECT_CALL(callbacks_, OnMetadata(_)); |
| 474 | 447 |
| 475 StartPipelineAndExpect(PIPELINE_ERROR_COULD_NOT_RENDER); | 448 StartPipelineAndExpect(PIPELINE_ERROR_COULD_NOT_RENDER); |
| 476 } | 449 } |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 SetDemuxerExpectations(&streams); | 609 SetDemuxerExpectations(&streams); |
| 637 SetRendererExpectations(); | 610 SetRendererExpectations(); |
| 638 | 611 |
| 639 // The audio renderer should receive a call to SetVolume(). | 612 // The audio renderer should receive a call to SetVolume(). |
| 640 float expected = 0.5f; | 613 float expected = 0.5f; |
| 641 EXPECT_CALL(*renderer_, SetVolume(expected)); | 614 EXPECT_CALL(*renderer_, SetVolume(expected)); |
| 642 | 615 |
| 643 // Initialize then set volume! | 616 // Initialize then set volume! |
| 644 StartPipelineAndExpect(PIPELINE_OK); | 617 StartPipelineAndExpect(PIPELINE_OK); |
| 645 pipeline_->SetVolume(expected); | 618 pipeline_->SetVolume(expected); |
| 619 message_loop_.RunUntilIdle(); |
| 646 } | 620 } |
| 647 | 621 |
| 648 TEST_F(PipelineImplTest, Properties) { | 622 TEST_F(PipelineImplTest, Properties) { |
| 649 CreateVideoStream(); | 623 CreateVideoStream(); |
| 650 MockDemuxerStreamVector streams; | 624 MockDemuxerStreamVector streams; |
| 651 streams.push_back(video_stream()); | 625 streams.push_back(video_stream()); |
| 652 | 626 |
| 653 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); | 627 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); |
| 654 SetDemuxerExpectations(&streams, kDuration); | 628 SetDemuxerExpectations(&streams, kDuration); |
| 655 SetRendererExpectations(); | 629 SetRendererExpectations(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 676 ExpectSeek(kSeekTime, false); | 650 ExpectSeek(kSeekTime, false); |
| 677 DoSeek(kSeekTime); | 651 DoSeek(kSeekTime); |
| 678 | 652 |
| 679 EXPECT_FALSE(pipeline_->DidLoadingProgress()); | 653 EXPECT_FALSE(pipeline_->DidLoadingProgress()); |
| 680 } | 654 } |
| 681 | 655 |
| 682 TEST_F(PipelineImplTest, BufferedTimeRangesCanChangeAfterStop) { | 656 TEST_F(PipelineImplTest, BufferedTimeRangesCanChangeAfterStop) { |
| 683 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 657 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
| 684 .WillOnce(PostCallback<1>(PIPELINE_OK)); | 658 .WillOnce(PostCallback<1>(PIPELINE_OK)); |
| 685 EXPECT_CALL(*demuxer_, Stop()); | 659 EXPECT_CALL(*demuxer_, Stop()); |
| 686 | 660 EXPECT_CALL(callbacks_, OnMetadata(_)); |
| 687 EXPECT_CALL(callbacks_, OnStart(_)); | 661 EXPECT_CALL(callbacks_, OnStart(_)); |
| 688 StartPipeline(); | 662 StartPipeline(); |
| 689 | |
| 690 EXPECT_CALL(callbacks_, OnStop()); | |
| 691 pipeline_->Stop( | |
| 692 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | |
| 693 message_loop_.RunUntilIdle(); | 663 message_loop_.RunUntilIdle(); |
| 694 | 664 |
| 665 pipeline_->Stop(); |
| 695 RunBufferedTimeRangesTest(base::TimeDelta::FromSeconds(5)); | 666 RunBufferedTimeRangesTest(base::TimeDelta::FromSeconds(5)); |
| 696 DestroyPipeline(); | 667 DestroyPipeline(); |
| 697 } | 668 } |
| 698 | 669 |
| 699 TEST_F(PipelineImplTest, EndedCallback) { | 670 TEST_F(PipelineImplTest, EndedCallback) { |
| 700 CreateAudioStream(); | 671 CreateAudioStream(); |
| 701 CreateVideoStream(); | 672 CreateVideoStream(); |
| 702 CreateTextStream(); | 673 CreateTextStream(); |
| 703 MockDemuxerStreamVector streams; | 674 MockDemuxerStreamVector streams; |
| 704 streams.push_back(audio_stream()); | 675 streams.push_back(audio_stream()); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 | 777 |
| 807 TEST_F(PipelineImplTest, DestroyAfterStop) { | 778 TEST_F(PipelineImplTest, DestroyAfterStop) { |
| 808 CreateAudioStream(); | 779 CreateAudioStream(); |
| 809 MockDemuxerStreamVector streams; | 780 MockDemuxerStreamVector streams; |
| 810 streams.push_back(audio_stream()); | 781 streams.push_back(audio_stream()); |
| 811 SetDemuxerExpectations(&streams); | 782 SetDemuxerExpectations(&streams); |
| 812 SetRendererExpectations(); | 783 SetRendererExpectations(); |
| 813 StartPipelineAndExpect(PIPELINE_OK); | 784 StartPipelineAndExpect(PIPELINE_OK); |
| 814 | 785 |
| 815 ExpectDemuxerStop(); | 786 ExpectDemuxerStop(); |
| 816 | 787 pipeline_->Stop(); |
| 817 ExpectPipelineStopAndDestroyPipeline(); | |
| 818 pipeline_->Stop( | |
| 819 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | |
| 820 message_loop_.RunUntilIdle(); | 788 message_loop_.RunUntilIdle(); |
| 821 } | 789 } |
| 822 | 790 |
| 823 TEST_F(PipelineImplTest, Underflow) { | 791 TEST_F(PipelineImplTest, Underflow) { |
| 824 CreateAudioStream(); | 792 CreateAudioStream(); |
| 825 CreateVideoStream(); | 793 CreateVideoStream(); |
| 826 MockDemuxerStreamVector streams; | 794 MockDemuxerStreamVector streams; |
| 827 streams.push_back(audio_stream()); | 795 streams.push_back(audio_stream()); |
| 828 streams.push_back(video_stream()); | 796 streams.push_back(video_stream()); |
| 829 | 797 |
| 830 SetDemuxerExpectations(&streams); | 798 SetDemuxerExpectations(&streams); |
| 831 SetRendererExpectations(); | 799 SetRendererExpectations(); |
| 832 StartPipelineAndExpect(PIPELINE_OK); | 800 StartPipelineAndExpect(PIPELINE_OK); |
| 833 | 801 |
| 834 // Simulate underflow. | 802 // Simulate underflow. |
| 835 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 803 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| 836 buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); | 804 buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); |
| 805 message_loop_.RunUntilIdle(); |
| 837 | 806 |
| 838 // Seek while underflowed. | 807 // Seek while underflowed. |
| 839 base::TimeDelta expected = base::TimeDelta::FromSeconds(5); | 808 base::TimeDelta expected = base::TimeDelta::FromSeconds(5); |
| 840 ExpectSeek(expected, true); | 809 ExpectSeek(expected, true); |
| 841 DoSeek(expected); | 810 DoSeek(expected); |
| 842 } | 811 } |
| 843 | 812 |
| 844 TEST_F(PipelineImplTest, PositiveStartTime) { | 813 TEST_F(PipelineImplTest, PositiveStartTime) { |
| 845 start_time_ = base::TimeDelta::FromSeconds(1); | 814 start_time_ = base::TimeDelta::FromSeconds(1); |
| 846 EXPECT_CALL(*demuxer_, GetStartTime()).WillRepeatedly(Return(start_time_)); | 815 EXPECT_CALL(*demuxer_, GetStartTime()).WillRepeatedly(Return(start_time_)); |
| 847 CreateAudioStream(); | 816 CreateAudioStream(); |
| 848 MockDemuxerStreamVector streams; | 817 MockDemuxerStreamVector streams; |
| 849 streams.push_back(audio_stream()); | 818 streams.push_back(audio_stream()); |
| 850 SetDemuxerExpectations(&streams); | 819 SetDemuxerExpectations(&streams); |
| 851 SetRendererExpectations(); | 820 SetRendererExpectations(); |
| 852 StartPipelineAndExpect(PIPELINE_OK); | 821 StartPipelineAndExpect(PIPELINE_OK); |
| 853 ExpectDemuxerStop(); | 822 ExpectDemuxerStop(); |
| 854 ExpectPipelineStopAndDestroyPipeline(); | 823 pipeline_->Stop(); |
| 855 pipeline_->Stop( | |
| 856 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | |
| 857 message_loop_.RunUntilIdle(); | 824 message_loop_.RunUntilIdle(); |
| 858 } | 825 } |
| 859 | 826 |
| 860 class PipelineTeardownTest : public PipelineImplTest { | 827 class PipelineTeardownTest : public PipelineImplTest { |
| 861 public: | 828 public: |
| 862 enum TeardownState { | 829 enum TeardownState { |
| 863 kInitDemuxer, | 830 kInitDemuxer, |
| 864 kInitRenderer, | 831 kInitRenderer, |
| 865 kFlushing, | 832 kFlushing, |
| 866 kSeeking, | 833 kSeeking, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 904 DoSuspend(state, stop_or_error); | 871 DoSuspend(state, stop_or_error); |
| 905 break; | 872 break; |
| 906 } | 873 } |
| 907 } | 874 } |
| 908 | 875 |
| 909 private: | 876 private: |
| 910 // TODO(scherkus): We do radically different things whether teardown is | 877 // TODO(scherkus): We do radically different things whether teardown is |
| 911 // invoked via stop vs error. The teardown path should be the same, | 878 // invoked via stop vs error. The teardown path should be the same, |
| 912 // see http://crbug.com/110228 | 879 // see http://crbug.com/110228 |
| 913 void DoInitialize(TeardownState state, StopOrError stop_or_error) { | 880 void DoInitialize(TeardownState state, StopOrError stop_or_error) { |
| 914 PipelineStatus expected_status = | 881 SetInitializeExpectations(state, stop_or_error); |
| 915 SetInitializeExpectations(state, stop_or_error); | |
| 916 | |
| 917 EXPECT_CALL(callbacks_, OnStart(expected_status)); | |
| 918 StartPipeline(); | 882 StartPipeline(); |
| 919 message_loop_.RunUntilIdle(); | 883 message_loop_.RunUntilIdle(); |
| 920 } | 884 } |
| 921 | 885 |
| 922 PipelineStatus SetInitializeExpectations(TeardownState state, | 886 void SetInitializeExpectations(TeardownState state, |
| 923 StopOrError stop_or_error) { | 887 StopOrError stop_or_error) { |
| 924 PipelineStatus status = PIPELINE_OK; | |
| 925 base::Closure stop_cb = | |
| 926 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_)); | |
| 927 | |
| 928 if (state == kInitDemuxer) { | 888 if (state == kInitDemuxer) { |
| 929 if (stop_or_error == kStop) { | 889 if (stop_or_error == kStop) { |
| 930 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 890 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
| 931 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), | 891 .WillOnce( |
| 932 PostCallback<1>(PIPELINE_OK))); | 892 DoAll(Stop(pipeline_.get()), PostCallback<1>(PIPELINE_OK))); |
| 933 ExpectPipelineStopAndDestroyPipeline(); | 893 // Note: OnStart callback is not called after pipeline is stopped. |
| 934 } else { | 894 } else { |
| 935 status = DEMUXER_ERROR_COULD_NOT_OPEN; | |
| 936 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) | 895 EXPECT_CALL(*demuxer_, Initialize(_, _, _)) |
| 937 .WillOnce(PostCallback<1>(status)); | 896 .WillOnce(PostCallback<1>(DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 897 EXPECT_CALL(callbacks_, OnStart(DEMUXER_ERROR_COULD_NOT_OPEN)); |
| 938 } | 898 } |
| 939 | 899 |
| 940 EXPECT_CALL(*demuxer_, Stop()); | 900 EXPECT_CALL(*demuxer_, Stop()); |
| 941 return status; | 901 return; |
| 942 } | 902 } |
| 943 | 903 |
| 944 CreateAudioStream(); | 904 CreateAudioStream(); |
| 945 CreateVideoStream(); | 905 CreateVideoStream(); |
| 946 MockDemuxerStreamVector streams; | 906 MockDemuxerStreamVector streams; |
| 947 streams.push_back(audio_stream()); | 907 streams.push_back(audio_stream()); |
| 948 streams.push_back(video_stream()); | 908 streams.push_back(video_stream()); |
| 949 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); | 909 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); |
| 950 | 910 |
| 951 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(true)); | 911 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(true)); |
| 952 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(true)); | 912 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(true)); |
| 953 | 913 |
| 954 if (state == kInitRenderer) { | 914 if (state == kInitRenderer) { |
| 955 if (stop_or_error == kStop) { | 915 if (stop_or_error == kStop) { |
| 956 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) | 916 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) |
| 957 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), | 917 .WillOnce( |
| 958 PostCallback<1>(PIPELINE_OK))); | 918 DoAll(Stop(pipeline_.get()), PostCallback<1>(PIPELINE_OK))); |
| 959 ExpectPipelineStopAndDestroyPipeline(); | 919 // Note: OnStart or OnMetadata callback are not called |
| 920 // after pipeline is stopped. |
| 960 } else { | 921 } else { |
| 961 status = PIPELINE_ERROR_INITIALIZATION_FAILED; | |
| 962 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) | 922 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) |
| 963 .WillOnce(PostCallback<1>(status)); | 923 .WillOnce(PostCallback<1>(PIPELINE_ERROR_INITIALIZATION_FAILED)); |
| 924 EXPECT_CALL(callbacks_, OnMetadata(_)); |
| 925 EXPECT_CALL(callbacks_, OnStart(PIPELINE_ERROR_INITIALIZATION_FAILED)); |
| 964 } | 926 } |
| 965 | 927 |
| 966 EXPECT_CALL(*demuxer_, Stop()); | 928 EXPECT_CALL(*demuxer_, Stop()); |
| 967 EXPECT_CALL(callbacks_, OnMetadata(_)); | 929 return; |
| 968 return status; | |
| 969 } | 930 } |
| 970 | 931 |
| 971 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) | 932 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) |
| 972 .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_), | 933 .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_), |
| 973 PostCallback<1>(PIPELINE_OK))); | 934 PostCallback<1>(PIPELINE_OK))); |
| 974 | 935 |
| 936 // If we get here it's a successful initialization. |
| 937 EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK)); |
| 975 EXPECT_CALL(callbacks_, OnMetadata(_)); | 938 EXPECT_CALL(callbacks_, OnMetadata(_)); |
| 976 | 939 |
| 977 // If we get here it's a successful initialization. | |
| 978 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0)); | 940 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0)); |
| 979 EXPECT_CALL(*renderer_, SetVolume(1.0f)); | 941 EXPECT_CALL(*renderer_, SetVolume(1.0f)); |
| 980 EXPECT_CALL(*renderer_, StartPlayingFrom(base::TimeDelta())) | 942 EXPECT_CALL(*renderer_, StartPlayingFrom(base::TimeDelta())) |
| 981 .WillOnce( | 943 .WillOnce( |
| 982 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_ENOUGH)); | 944 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_ENOUGH)); |
| 983 | 945 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
| 984 if (status == PIPELINE_OK) | |
| 985 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); | |
| 986 | |
| 987 return status; | |
| 988 } | 946 } |
| 989 | 947 |
| 990 void DoSeek(TeardownState state, StopOrError stop_or_error) { | 948 void DoSeek(TeardownState state, StopOrError stop_or_error) { |
| 991 InSequence s; | 949 SetSeekExpectations(state, stop_or_error); |
| 992 PipelineStatus status = SetSeekExpectations(state, stop_or_error); | |
| 993 | 950 |
| 994 EXPECT_CALL(*demuxer_, Stop()); | 951 EXPECT_CALL(*demuxer_, Stop()); |
| 995 EXPECT_CALL(callbacks_, OnSeek(status)); | |
| 996 | |
| 997 if (status == PIPELINE_OK) { | |
| 998 ExpectPipelineStopAndDestroyPipeline(); | |
| 999 } | |
| 1000 | 952 |
| 1001 pipeline_->Seek( | 953 pipeline_->Seek( |
| 1002 base::TimeDelta::FromSeconds(10), | 954 base::TimeDelta::FromSeconds(10), |
| 1003 base::Bind(&CallbackHelper::OnSeek, base::Unretained(&callbacks_))); | 955 base::Bind(&CallbackHelper::OnSeek, base::Unretained(&callbacks_))); |
| 1004 message_loop_.RunUntilIdle(); | 956 message_loop_.RunUntilIdle(); |
| 1005 } | 957 } |
| 1006 | 958 |
| 1007 PipelineStatus SetSeekExpectations(TeardownState state, | 959 void SetSeekExpectations(TeardownState state, StopOrError stop_or_error) { |
| 1008 StopOrError stop_or_error) { | |
| 1009 PipelineStatus status = PIPELINE_OK; | |
| 1010 base::Closure stop_cb = | |
| 1011 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_)); | |
| 1012 | |
| 1013 if (state == kFlushing) { | 960 if (state == kFlushing) { |
| 1014 if (stop_or_error == kStop) { | 961 if (stop_or_error == kStop) { |
| 1015 EXPECT_CALL(*renderer_, Flush(_)) | 962 EXPECT_CALL(*renderer_, Flush(_)) |
| 1016 .WillOnce(DoAll( | 963 .WillOnce(DoAll( |
| 1017 Stop(pipeline_.get(), stop_cb), | |
| 1018 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), | 964 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), |
| 965 Stop(pipeline_.get()), RunClosure<0>())); |
| 966 // Note: OnBufferingStateChange or OnSeek callbacks are not called |
| 967 // after pipeline is stopped. |
| 968 } else { |
| 969 EXPECT_CALL(*renderer_, Flush(_)) |
| 970 .WillOnce(DoAll( |
| 971 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), |
| 972 SetError(pipeline_.get(), PIPELINE_ERROR_READ), |
| 1019 RunClosure<0>())); | 973 RunClosure<0>())); |
| 1020 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 974 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| 1021 } else { | 975 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); |
| 1022 status = PIPELINE_ERROR_READ; | |
| 1023 EXPECT_CALL(*renderer_, Flush(_)) | |
| 1024 .WillOnce(DoAll( | |
| 1025 SetError(pipeline_.get(), status), | |
| 1026 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), | |
| 1027 RunClosure<0>())); | |
| 1028 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | |
| 1029 } | 976 } |
| 1030 | 977 return; |
| 1031 return status; | |
| 1032 } | 978 } |
| 1033 | 979 |
| 1034 EXPECT_CALL(*renderer_, Flush(_)) | 980 EXPECT_CALL(*renderer_, Flush(_)) |
| 1035 .WillOnce(DoAll( | 981 .WillOnce(DoAll( |
| 1036 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), | 982 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), |
| 1037 RunClosure<0>())); | 983 RunClosure<0>())); |
| 1038 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 984 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| 1039 | 985 |
| 1040 if (state == kSeeking) { | 986 if (state == kSeeking) { |
| 1041 if (stop_or_error == kStop) { | 987 if (stop_or_error == kStop) { |
| 1042 EXPECT_CALL(*demuxer_, Seek(_, _)) | 988 EXPECT_CALL(*demuxer_, Seek(_, _)) |
| 1043 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), | 989 .WillOnce( |
| 1044 RunCallback<1>(PIPELINE_OK))); | 990 DoAll(Stop(pipeline_.get()), RunCallback<1>(PIPELINE_OK))); |
| 991 // Note: OnSeek callback is not called after pipeline is stopped. |
| 1045 } else { | 992 } else { |
| 1046 status = PIPELINE_ERROR_READ; | 993 EXPECT_CALL(*demuxer_, Seek(_, _)) |
| 1047 EXPECT_CALL(*demuxer_, Seek(_, _)).WillOnce(RunCallback<1>(status)); | 994 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); |
| 995 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); |
| 1048 } | 996 } |
| 1049 | 997 return; |
| 1050 return status; | |
| 1051 } | 998 } |
| 1052 | 999 |
| 1053 NOTREACHED() << "State not supported: " << state; | 1000 NOTREACHED() << "State not supported: " << state; |
| 1054 return status; | |
| 1055 } | 1001 } |
| 1056 | 1002 |
| 1057 void DoSuspend(TeardownState state, StopOrError stop_or_error) { | 1003 void DoSuspend(TeardownState state, StopOrError stop_or_error) { |
| 1058 PipelineStatus status = SetSuspendExpectations(state, stop_or_error); | 1004 SetSuspendExpectations(state, stop_or_error); |
| 1059 | 1005 |
| 1060 if (state == kResuming) { | 1006 if (state == kResuming) { |
| 1061 EXPECT_CALL(*demuxer_, Stop()); | 1007 EXPECT_CALL(*demuxer_, Stop()); |
| 1062 if (status == PIPELINE_OK) | |
| 1063 ExpectPipelineStopAndDestroyPipeline(); | |
| 1064 } | 1008 } |
| 1065 | 1009 |
| 1066 PipelineImplTest::DoSuspend(); | 1010 PipelineImplTest::DoSuspend(); |
| 1067 | 1011 |
| 1068 if (state == kResuming) { | 1012 if (state == kResuming) { |
| 1069 PipelineImplTest::DoResume(base::TimeDelta()); | 1013 PipelineImplTest::DoResume(base::TimeDelta()); |
| 1070 return; | 1014 return; |
| 1071 } | 1015 } |
| 1072 | 1016 |
| 1073 // kSuspended, kSuspending never throw errors, since Resume() is always able | 1017 // kSuspended, kSuspending never throw errors, since Resume() is always able |
| 1074 // to restore the pipeline to a pristine state. | 1018 // to restore the pipeline to a pristine state. |
| 1075 DoStopOrError(stop_or_error, false); | 1019 DoStopOrError(stop_or_error, false); |
| 1076 } | 1020 } |
| 1077 | 1021 |
| 1078 PipelineStatus SetSuspendExpectations(TeardownState state, | 1022 void SetSuspendExpectations(TeardownState state, StopOrError stop_or_error) { |
| 1079 StopOrError stop_or_error) { | |
| 1080 PipelineStatus status = PIPELINE_OK; | |
| 1081 base::Closure stop_cb = | |
| 1082 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_)); | |
| 1083 | |
| 1084 EXPECT_CALL(*renderer_, SetPlaybackRate(0)); | 1023 EXPECT_CALL(*renderer_, SetPlaybackRate(0)); |
| 1085 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 1024 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| 1086 EXPECT_CALL(callbacks_, OnSuspend(PIPELINE_OK)); | 1025 EXPECT_CALL(callbacks_, OnSuspend(PIPELINE_OK)); |
| 1087 EXPECT_CALL(*renderer_, Flush(_)) | 1026 EXPECT_CALL(*renderer_, Flush(_)) |
| 1088 .WillOnce(DoAll( | 1027 .WillOnce(DoAll( |
| 1089 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), | 1028 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), |
| 1090 RunClosure<0>())); | 1029 RunClosure<0>())); |
| 1091 if (state == kResuming) { | 1030 if (state == kResuming) { |
| 1092 if (stop_or_error == kStop) { | 1031 if (stop_or_error == kStop) { |
| 1093 EXPECT_CALL(*demuxer_, Seek(_, _)) | 1032 EXPECT_CALL(*demuxer_, Seek(_, _)) |
| 1094 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), | 1033 .WillOnce( |
| 1095 RunCallback<1>(PIPELINE_OK))); | 1034 DoAll(Stop(pipeline_.get()), RunCallback<1>(PIPELINE_OK))); |
| 1096 EXPECT_CALL(callbacks_, OnResume(PIPELINE_OK)); | 1035 // Note: OnResume callback is not called after pipeline is stopped. |
| 1097 } else { | 1036 } else { |
| 1098 status = PIPELINE_ERROR_READ; | 1037 EXPECT_CALL(*demuxer_, Seek(_, _)) |
| 1099 EXPECT_CALL(*demuxer_, Seek(_, _)).WillOnce(RunCallback<1>(status)); | 1038 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); |
| 1100 EXPECT_CALL(callbacks_, OnResume(status)); | 1039 EXPECT_CALL(callbacks_, OnResume(PIPELINE_ERROR_READ)); |
| 1101 } | 1040 } |
| 1102 } else if (state != kSuspended && state != kSuspending) { | 1041 } else if (state != kSuspended && state != kSuspending) { |
| 1103 NOTREACHED() << "State not supported: " << state; | 1042 NOTREACHED() << "State not supported: " << state; |
| 1104 } | 1043 } |
| 1105 | |
| 1106 return status; | |
| 1107 } | 1044 } |
| 1108 | 1045 |
| 1109 void DoStopOrError(StopOrError stop_or_error, bool expect_errors) { | 1046 void DoStopOrError(StopOrError stop_or_error, bool expect_errors) { |
| 1110 InSequence s; | 1047 InSequence s; |
| 1111 | 1048 |
| 1112 switch (stop_or_error) { | 1049 switch (stop_or_error) { |
| 1113 case kStop: | 1050 case kStop: |
| 1114 EXPECT_CALL(*demuxer_, Stop()); | 1051 EXPECT_CALL(*demuxer_, Stop()); |
| 1115 ExpectPipelineStopAndDestroyPipeline(); | 1052 pipeline_->Stop(); |
| 1116 pipeline_->Stop( | |
| 1117 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | |
| 1118 break; | 1053 break; |
| 1119 | 1054 |
| 1120 case kError: | 1055 case kError: |
| 1121 if (expect_errors) { | 1056 if (expect_errors) { |
| 1122 EXPECT_CALL(*demuxer_, Stop()); | 1057 EXPECT_CALL(*demuxer_, Stop()); |
| 1123 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ)); | 1058 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ)); |
| 1124 } | 1059 } |
| 1125 pipeline_->SetErrorForTesting(PIPELINE_ERROR_READ); | 1060 pipeline_->SetErrorForTesting(PIPELINE_ERROR_READ); |
| 1126 break; | 1061 break; |
| 1127 | 1062 |
| 1128 case kErrorAndStop: | 1063 case kErrorAndStop: |
| 1129 EXPECT_CALL(*demuxer_, Stop()); | 1064 EXPECT_CALL(*demuxer_, Stop()); |
| 1130 if (expect_errors) | 1065 if (expect_errors) |
| 1131 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ)); | 1066 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ)); |
| 1132 ExpectPipelineStopAndDestroyPipeline(); | |
| 1133 pipeline_->SetErrorForTesting(PIPELINE_ERROR_READ); | 1067 pipeline_->SetErrorForTesting(PIPELINE_ERROR_READ); |
| 1134 message_loop_.RunUntilIdle(); | 1068 message_loop_.RunUntilIdle(); |
| 1135 pipeline_->Stop( | 1069 pipeline_->Stop(); |
| 1136 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); | |
| 1137 break; | 1070 break; |
| 1138 } | 1071 } |
| 1139 | 1072 |
| 1140 message_loop_.RunUntilIdle(); | 1073 message_loop_.RunUntilIdle(); |
| 1141 } | 1074 } |
| 1142 | 1075 |
| 1143 DISALLOW_COPY_AND_ASSIGN(PipelineTeardownTest); | 1076 DISALLOW_COPY_AND_ASSIGN(PipelineTeardownTest); |
| 1144 }; | 1077 }; |
| 1145 | 1078 |
| 1146 #define INSTANTIATE_TEARDOWN_TEST(stop_or_error, state) \ | 1079 #define INSTANTIATE_TEARDOWN_TEST(stop_or_error, state) \ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1163 INSTANTIATE_TEARDOWN_TEST(Error, Seeking); | 1096 INSTANTIATE_TEARDOWN_TEST(Error, Seeking); |
| 1164 INSTANTIATE_TEARDOWN_TEST(Error, Playing); | 1097 INSTANTIATE_TEARDOWN_TEST(Error, Playing); |
| 1165 INSTANTIATE_TEARDOWN_TEST(Error, Suspending); | 1098 INSTANTIATE_TEARDOWN_TEST(Error, Suspending); |
| 1166 INSTANTIATE_TEARDOWN_TEST(Error, Suspended); | 1099 INSTANTIATE_TEARDOWN_TEST(Error, Suspended); |
| 1167 INSTANTIATE_TEARDOWN_TEST(Error, Resuming); | 1100 INSTANTIATE_TEARDOWN_TEST(Error, Resuming); |
| 1168 | 1101 |
| 1169 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing); | 1102 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing); |
| 1170 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Suspended); | 1103 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Suspended); |
| 1171 | 1104 |
| 1172 } // namespace media | 1105 } // namespace media |
| OLD | NEW |