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