| 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 } | 49 } |
| 50 | 50 |
| 51 ACTION_P(Stop, pipeline) { | 51 ACTION_P(Stop, pipeline) { |
| 52 pipeline->Stop(); | 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, renderer_client, buffering_state) { |
| 60 cb->Run(buffering_state); | 60 (*renderer_client)->OnBufferingStateChange(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 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 99 | 99 |
| 100 private: | 100 private: |
| 101 DISALLOW_COPY_AND_ASSIGN(CallbackHelper); | 101 DISALLOW_COPY_AND_ASSIGN(CallbackHelper); |
| 102 }; | 102 }; |
| 103 | 103 |
| 104 PipelineImplTest() | 104 PipelineImplTest() |
| 105 : pipeline_( | 105 : pipeline_( |
| 106 new PipelineImpl(message_loop_.task_runner(), new MediaLog())), | 106 new PipelineImpl(message_loop_.task_runner(), new MediaLog())), |
| 107 demuxer_(new StrictMock<MockDemuxer>()), | 107 demuxer_(new StrictMock<MockDemuxer>()), |
| 108 scoped_renderer_(new StrictMock<MockRenderer>()), | 108 scoped_renderer_(new StrictMock<MockRenderer>()), |
| 109 renderer_(scoped_renderer_.get()) { | 109 renderer_(scoped_renderer_.get()), |
| 110 renderer_client_(nullptr) { |
| 110 // SetDemuxerExpectations() adds overriding expectations for expected | 111 // SetDemuxerExpectations() adds overriding expectations for expected |
| 111 // non-NULL streams. | 112 // non-NULL streams. |
| 112 DemuxerStream* null_pointer = NULL; | 113 DemuxerStream* null_pointer = NULL; |
| 113 EXPECT_CALL(*demuxer_, GetStream(_)).WillRepeatedly(Return(null_pointer)); | 114 EXPECT_CALL(*demuxer_, GetStream(_)).WillRepeatedly(Return(null_pointer)); |
| 114 | 115 |
| 115 EXPECT_CALL(*demuxer_, GetTimelineOffset()) | 116 EXPECT_CALL(*demuxer_, GetTimelineOffset()) |
| 116 .WillRepeatedly(Return(base::Time())); | 117 .WillRepeatedly(Return(base::Time())); |
| 117 | 118 |
| 118 EXPECT_CALL(*renderer_, GetMediaTime()) | 119 EXPECT_CALL(*renderer_, GetMediaTime()) |
| 119 .WillRepeatedly(Return(base::TimeDelta())); | 120 .WillRepeatedly(Return(base::TimeDelta())); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 | 171 |
| 171 std::unique_ptr<StrictMock<MockDemuxerStream>> CreateStream( | 172 std::unique_ptr<StrictMock<MockDemuxerStream>> CreateStream( |
| 172 DemuxerStream::Type type) { | 173 DemuxerStream::Type type) { |
| 173 std::unique_ptr<StrictMock<MockDemuxerStream>> stream( | 174 std::unique_ptr<StrictMock<MockDemuxerStream>> stream( |
| 174 new StrictMock<MockDemuxerStream>(type)); | 175 new StrictMock<MockDemuxerStream>(type)); |
| 175 return stream; | 176 return stream; |
| 176 } | 177 } |
| 177 | 178 |
| 178 // Sets up expectations to allow the video renderer to initialize. | 179 // Sets up expectations to allow the video renderer to initialize. |
| 179 void SetRendererExpectations() { | 180 void SetRendererExpectations() { |
| 180 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) | 181 EXPECT_CALL(*renderer_, Initialize(_, _, _)) |
| 181 .WillOnce(DoAll(SaveArg<2>(&statistics_cb_), | 182 .WillOnce( |
| 182 SaveArg<3>(&buffering_state_cb_), | 183 DoAll(SaveArg<1>(&renderer_client_), PostCallback<2>(PIPELINE_OK))); |
| 183 SaveArg<4>(&ended_cb_), PostCallback<1>(PIPELINE_OK))); | |
| 184 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(audio_stream())); | 184 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(audio_stream())); |
| 185 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(video_stream())); | 185 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(video_stream())); |
| 186 } | 186 } |
| 187 | 187 |
| 188 void AddTextStream() { | 188 void AddTextStream() { |
| 189 EXPECT_CALL(callbacks_, OnAddTextTrack(_, _)) | 189 EXPECT_CALL(callbacks_, OnAddTextTrack(_, _)) |
| 190 .WillOnce(Invoke(this, &PipelineImplTest::DoOnAddTextTrack)); | 190 .WillOnce(Invoke(this, &PipelineImplTest::DoOnAddTextTrack)); |
| 191 static_cast<DemuxerHost*>(pipeline_.get()) | 191 static_cast<DemuxerHost*>(pipeline_.get()) |
| 192 ->AddTextStream(text_stream(), | 192 ->AddTextStream(text_stream(), |
| 193 TextTrackConfig(kTextSubtitles, "", "", "")); | 193 TextTrackConfig(kTextSubtitles, "", "", "")); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 205 // after tests have set expectations any filters they wish to use. | 205 // after tests have set expectations any filters they wish to use. |
| 206 void StartPipelineAndExpect(PipelineStatus start_status) { | 206 void StartPipelineAndExpect(PipelineStatus start_status) { |
| 207 EXPECT_CALL(callbacks_, OnStart(start_status)); | 207 EXPECT_CALL(callbacks_, OnStart(start_status)); |
| 208 | 208 |
| 209 if (start_status == PIPELINE_OK) { | 209 if (start_status == PIPELINE_OK) { |
| 210 EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_)); | 210 EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_)); |
| 211 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0)); | 211 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0)); |
| 212 EXPECT_CALL(*renderer_, SetVolume(1.0f)); | 212 EXPECT_CALL(*renderer_, SetVolume(1.0f)); |
| 213 EXPECT_CALL(*renderer_, StartPlayingFrom(start_time_)) | 213 EXPECT_CALL(*renderer_, StartPlayingFrom(start_time_)) |
| 214 .WillOnce( | 214 .WillOnce( |
| 215 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_ENOUGH)); | 215 SetBufferingState(&renderer_client_, BUFFERING_HAVE_ENOUGH)); |
| 216 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 216 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
| 217 } | 217 } |
| 218 | 218 |
| 219 StartPipeline(); | 219 StartPipeline(); |
| 220 message_loop_.RunUntilIdle(); | 220 message_loop_.RunUntilIdle(); |
| 221 } | 221 } |
| 222 | 222 |
| 223 void CreateAudioStream() { | 223 void CreateAudioStream() { |
| 224 audio_stream_ = CreateStream(DemuxerStream::AUDIO); | 224 audio_stream_ = CreateStream(DemuxerStream::AUDIO); |
| 225 } | 225 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 239 | 239 |
| 240 MockDemuxerStream* video_stream() { return video_stream_.get(); } | 240 MockDemuxerStream* video_stream() { return video_stream_.get(); } |
| 241 | 241 |
| 242 FakeTextTrackStream* text_stream() { return text_stream_.get(); } | 242 FakeTextTrackStream* text_stream() { return text_stream_.get(); } |
| 243 | 243 |
| 244 void ExpectSeek(const base::TimeDelta& seek_time, bool underflowed) { | 244 void ExpectSeek(const base::TimeDelta& seek_time, bool underflowed) { |
| 245 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) | 245 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) |
| 246 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 246 .WillOnce(RunCallback<1>(PIPELINE_OK)); |
| 247 | 247 |
| 248 EXPECT_CALL(*renderer_, Flush(_)) | 248 EXPECT_CALL(*renderer_, Flush(_)) |
| 249 .WillOnce(DoAll( | 249 .WillOnce( |
| 250 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), | 250 DoAll(SetBufferingState(&renderer_client_, BUFFERING_HAVE_NOTHING), |
| 251 RunClosure<0>())); | 251 RunClosure<0>())); |
| 252 EXPECT_CALL(*renderer_, SetPlaybackRate(_)); | 252 EXPECT_CALL(*renderer_, SetPlaybackRate(_)); |
| 253 EXPECT_CALL(*renderer_, SetVolume(_)); | 253 EXPECT_CALL(*renderer_, SetVolume(_)); |
| 254 EXPECT_CALL(*renderer_, StartPlayingFrom(seek_time)) | 254 EXPECT_CALL(*renderer_, StartPlayingFrom(seek_time)) |
| 255 .WillOnce( | 255 .WillOnce(SetBufferingState(&renderer_client_, BUFFERING_HAVE_ENOUGH)); |
| 256 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_ENOUGH)); | |
| 257 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 256 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| 258 | 257 |
| 259 // We expect a successful seek callback followed by a buffering update. | 258 // We expect a successful seek callback followed by a buffering update. |
| 260 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); | 259 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); |
| 261 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 260 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
| 262 } | 261 } |
| 263 | 262 |
| 264 void DoSeek(const base::TimeDelta& seek_time) { | 263 void DoSeek(const base::TimeDelta& seek_time) { |
| 265 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, | 264 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, |
| 266 base::Unretained(&callbacks_))); | 265 base::Unretained(&callbacks_))); |
| 267 message_loop_.RunUntilIdle(); | 266 message_loop_.RunUntilIdle(); |
| 268 } | 267 } |
| 269 | 268 |
| 270 void ExpectSuspend() { | 269 void ExpectSuspend() { |
| 271 EXPECT_CALL(*renderer_, SetPlaybackRate(0)); | 270 EXPECT_CALL(*renderer_, SetPlaybackRate(0)); |
| 272 EXPECT_CALL(*renderer_, Flush(_)) | 271 EXPECT_CALL(*renderer_, Flush(_)) |
| 273 .WillOnce(DoAll( | 272 .WillOnce( |
| 274 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), | 273 DoAll(SetBufferingState(&renderer_client_, BUFFERING_HAVE_NOTHING), |
| 275 RunClosure<0>())); | 274 RunClosure<0>())); |
| 276 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 275 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| 277 EXPECT_CALL(callbacks_, OnSuspend(PIPELINE_OK)); | 276 EXPECT_CALL(callbacks_, OnSuspend(PIPELINE_OK)); |
| 278 } | 277 } |
| 279 | 278 |
| 280 void DoSuspend() { | 279 void DoSuspend() { |
| 281 pipeline_->Suspend( | 280 pipeline_->Suspend( |
| 282 base::Bind(&CallbackHelper::OnSuspend, base::Unretained(&callbacks_))); | 281 base::Bind(&CallbackHelper::OnSuspend, base::Unretained(&callbacks_))); |
| 283 message_loop_.RunUntilIdle(); | 282 message_loop_.RunUntilIdle(); |
| 284 | 283 |
| 285 // |renderer_| has been deleted, replace it. | 284 // |renderer_| has been deleted, replace it. |
| 286 scoped_renderer_.reset(new StrictMock<MockRenderer>()), | 285 scoped_renderer_.reset(new StrictMock<MockRenderer>()), |
| 287 renderer_ = scoped_renderer_.get(); | 286 renderer_ = scoped_renderer_.get(); |
| 288 } | 287 } |
| 289 | 288 |
| 290 void ExpectResume(const base::TimeDelta& seek_time) { | 289 void ExpectResume(const base::TimeDelta& seek_time) { |
| 291 SetRendererExpectations(); | 290 SetRendererExpectations(); |
| 292 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) | 291 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) |
| 293 .WillOnce(RunCallback<1>(PIPELINE_OK)); | 292 .WillOnce(RunCallback<1>(PIPELINE_OK)); |
| 294 EXPECT_CALL(*renderer_, SetPlaybackRate(_)); | 293 EXPECT_CALL(*renderer_, SetPlaybackRate(_)); |
| 295 EXPECT_CALL(*renderer_, SetVolume(_)); | 294 EXPECT_CALL(*renderer_, SetVolume(_)); |
| 296 EXPECT_CALL(*renderer_, StartPlayingFrom(seek_time)) | 295 EXPECT_CALL(*renderer_, StartPlayingFrom(seek_time)) |
| 297 .WillOnce( | 296 .WillOnce(SetBufferingState(&renderer_client_, BUFFERING_HAVE_ENOUGH)); |
| 298 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_ENOUGH)); | |
| 299 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 297 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
| 300 EXPECT_CALL(callbacks_, OnResume(PIPELINE_OK)); | 298 EXPECT_CALL(callbacks_, OnResume(PIPELINE_OK)); |
| 301 } | 299 } |
| 302 | 300 |
| 303 void DoResume(const base::TimeDelta& seek_time) { | 301 void DoResume(const base::TimeDelta& seek_time) { |
| 304 pipeline_->Resume( | 302 pipeline_->Resume( |
| 305 std::move(scoped_renderer_), seek_time, | 303 std::move(scoped_renderer_), seek_time, |
| 306 base::Bind(&CallbackHelper::OnResume, base::Unretained(&callbacks_))); | 304 base::Bind(&CallbackHelper::OnResume, base::Unretained(&callbacks_))); |
| 307 message_loop_.RunUntilIdle(); | 305 message_loop_.RunUntilIdle(); |
| 308 } | 306 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 std::unique_ptr<PipelineImpl> pipeline_; | 343 std::unique_ptr<PipelineImpl> pipeline_; |
| 346 | 344 |
| 347 std::unique_ptr<StrictMock<MockDemuxer>> demuxer_; | 345 std::unique_ptr<StrictMock<MockDemuxer>> demuxer_; |
| 348 std::unique_ptr<StrictMock<MockRenderer>> scoped_renderer_; | 346 std::unique_ptr<StrictMock<MockRenderer>> scoped_renderer_; |
| 349 StrictMock<MockRenderer>* renderer_; | 347 StrictMock<MockRenderer>* renderer_; |
| 350 StrictMock<CallbackHelper> text_renderer_callbacks_; | 348 StrictMock<CallbackHelper> text_renderer_callbacks_; |
| 351 TextRenderer* text_renderer_; | 349 TextRenderer* text_renderer_; |
| 352 std::unique_ptr<StrictMock<MockDemuxerStream>> audio_stream_; | 350 std::unique_ptr<StrictMock<MockDemuxerStream>> audio_stream_; |
| 353 std::unique_ptr<StrictMock<MockDemuxerStream>> video_stream_; | 351 std::unique_ptr<StrictMock<MockDemuxerStream>> video_stream_; |
| 354 std::unique_ptr<FakeTextTrackStream> text_stream_; | 352 std::unique_ptr<FakeTextTrackStream> text_stream_; |
| 355 BufferingStateCB buffering_state_cb_; | 353 RendererClient* renderer_client_; |
| 356 base::Closure ended_cb_; | |
| 357 StatisticsCB statistics_cb_; | |
| 358 VideoDecoderConfig video_decoder_config_; | 354 VideoDecoderConfig video_decoder_config_; |
| 359 PipelineMetadata metadata_; | 355 PipelineMetadata metadata_; |
| 360 base::TimeDelta start_time_; | 356 base::TimeDelta start_time_; |
| 361 | 357 |
| 362 private: | 358 private: |
| 363 DISALLOW_COPY_AND_ASSIGN(PipelineImplTest); | 359 DISALLOW_COPY_AND_ASSIGN(PipelineImplTest); |
| 364 }; | 360 }; |
| 365 | 361 |
| 366 // Test that playback controls methods no-op when the pipeline hasn't been | 362 // Test that playback controls methods no-op when the pipeline hasn't been |
| 367 // started. | 363 // started. |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 | 573 |
| 578 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); | 574 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); |
| 579 SetRendererExpectations(); | 575 SetRendererExpectations(); |
| 580 | 576 |
| 581 StartPipelineAndExpect(PIPELINE_OK); | 577 StartPipelineAndExpect(PIPELINE_OK); |
| 582 | 578 |
| 583 // Inject some fake memory usage to verify its cleared after suspend. | 579 // Inject some fake memory usage to verify its cleared after suspend. |
| 584 PipelineStatistics stats; | 580 PipelineStatistics stats; |
| 585 stats.audio_memory_usage = 12345; | 581 stats.audio_memory_usage = 12345; |
| 586 stats.video_memory_usage = 67890; | 582 stats.video_memory_usage = 67890; |
| 587 statistics_cb_.Run(stats); | 583 renderer_client_->OnStatisticsUpdate(stats); |
| 588 EXPECT_EQ(stats.audio_memory_usage, | 584 EXPECT_EQ(stats.audio_memory_usage, |
| 589 pipeline_->GetStatistics().audio_memory_usage); | 585 pipeline_->GetStatistics().audio_memory_usage); |
| 590 EXPECT_EQ(stats.video_memory_usage, | 586 EXPECT_EQ(stats.video_memory_usage, |
| 591 pipeline_->GetStatistics().video_memory_usage); | 587 pipeline_->GetStatistics().video_memory_usage); |
| 592 | 588 |
| 593 ExpectSuspend(); | 589 ExpectSuspend(); |
| 594 DoSuspend(); | 590 DoSuspend(); |
| 595 | 591 |
| 596 EXPECT_EQ(pipeline_->GetStatistics().audio_memory_usage, 0); | 592 EXPECT_EQ(pipeline_->GetStatistics().audio_memory_usage, 0); |
| 597 EXPECT_EQ(pipeline_->GetStatistics().video_memory_usage, 0); | 593 EXPECT_EQ(pipeline_->GetStatistics().video_memory_usage, 0); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 streams.push_back(audio_stream()); | 671 streams.push_back(audio_stream()); |
| 676 streams.push_back(video_stream()); | 672 streams.push_back(video_stream()); |
| 677 | 673 |
| 678 SetDemuxerExpectations(&streams); | 674 SetDemuxerExpectations(&streams); |
| 679 SetRendererExpectations(); | 675 SetRendererExpectations(); |
| 680 StartPipelineAndExpect(PIPELINE_OK); | 676 StartPipelineAndExpect(PIPELINE_OK); |
| 681 | 677 |
| 682 AddTextStream(); | 678 AddTextStream(); |
| 683 | 679 |
| 684 // The ended callback shouldn't run until all renderers have ended. | 680 // The ended callback shouldn't run until all renderers have ended. |
| 685 ended_cb_.Run(); | 681 renderer_client_->OnEnded(); |
| 686 message_loop_.RunUntilIdle(); | 682 message_loop_.RunUntilIdle(); |
| 687 | 683 |
| 688 EXPECT_CALL(callbacks_, OnEnded()); | 684 EXPECT_CALL(callbacks_, OnEnded()); |
| 689 text_stream()->SendEosNotification(); | 685 text_stream()->SendEosNotification(); |
| 690 message_loop_.RunUntilIdle(); | 686 message_loop_.RunUntilIdle(); |
| 691 } | 687 } |
| 692 | 688 |
| 693 TEST_F(PipelineImplTest, ErrorDuringSeek) { | 689 TEST_F(PipelineImplTest, ErrorDuringSeek) { |
| 694 CreateAudioStream(); | 690 CreateAudioStream(); |
| 695 MockDemuxerStreamVector streams; | 691 MockDemuxerStreamVector streams; |
| 696 streams.push_back(audio_stream()); | 692 streams.push_back(audio_stream()); |
| 697 | 693 |
| 698 SetDemuxerExpectations(&streams); | 694 SetDemuxerExpectations(&streams); |
| 699 SetRendererExpectations(); | 695 SetRendererExpectations(); |
| 700 StartPipelineAndExpect(PIPELINE_OK); | 696 StartPipelineAndExpect(PIPELINE_OK); |
| 701 | 697 |
| 702 double playback_rate = 1.0; | 698 double playback_rate = 1.0; |
| 703 EXPECT_CALL(*renderer_, SetPlaybackRate(playback_rate)); | 699 EXPECT_CALL(*renderer_, SetPlaybackRate(playback_rate)); |
| 704 pipeline_->SetPlaybackRate(playback_rate); | 700 pipeline_->SetPlaybackRate(playback_rate); |
| 705 message_loop_.RunUntilIdle(); | 701 message_loop_.RunUntilIdle(); |
| 706 | 702 |
| 707 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 703 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| 708 | 704 |
| 709 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 705 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| 710 EXPECT_CALL(*renderer_, Flush(_)) | 706 EXPECT_CALL(*renderer_, Flush(_)) |
| 711 .WillOnce( | 707 .WillOnce( |
| 712 DoAll(SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), | 708 DoAll(SetBufferingState(&renderer_client_, BUFFERING_HAVE_NOTHING), |
| 713 RunClosure<0>())); | 709 RunClosure<0>())); |
| 714 | 710 |
| 715 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) | 711 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) |
| 716 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); | 712 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); |
| 717 EXPECT_CALL(*demuxer_, Stop()); | 713 EXPECT_CALL(*demuxer_, Stop()); |
| 718 | 714 |
| 719 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, | 715 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, |
| 720 base::Unretained(&callbacks_))); | 716 base::Unretained(&callbacks_))); |
| 721 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); | 717 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); |
| 722 message_loop_.RunUntilIdle(); | 718 message_loop_.RunUntilIdle(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 base::Callback<void(PipelineStatus)> cb = | 750 base::Callback<void(PipelineStatus)> cb = |
| 755 base::Bind(&TestNoCallsAfterError, pipeline_.get(), &message_loop_); | 751 base::Bind(&TestNoCallsAfterError, pipeline_.get(), &message_loop_); |
| 756 ON_CALL(callbacks_, OnError(_)) | 752 ON_CALL(callbacks_, OnError(_)) |
| 757 .WillByDefault(Invoke(&cb, &base::Callback<void(PipelineStatus)>::Run)); | 753 .WillByDefault(Invoke(&cb, &base::Callback<void(PipelineStatus)>::Run)); |
| 758 | 754 |
| 759 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); | 755 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| 760 | 756 |
| 761 // Seek() isn't called as the demuxer errors out first. | 757 // Seek() isn't called as the demuxer errors out first. |
| 762 EXPECT_CALL(*renderer_, Flush(_)) | 758 EXPECT_CALL(*renderer_, Flush(_)) |
| 763 .WillOnce( | 759 .WillOnce( |
| 764 DoAll(SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), | 760 DoAll(SetBufferingState(&renderer_client_, BUFFERING_HAVE_NOTHING), |
| 765 RunClosure<0>())); | 761 RunClosure<0>())); |
| 766 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 762 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| 767 | 763 |
| 768 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) | 764 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) |
| 769 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); | 765 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); |
| 770 EXPECT_CALL(*demuxer_, Stop()); | 766 EXPECT_CALL(*demuxer_, Stop()); |
| 771 | 767 |
| 772 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, | 768 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, |
| 773 base::Unretained(&callbacks_))); | 769 base::Unretained(&callbacks_))); |
| 774 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); | 770 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 794 MockDemuxerStreamVector streams; | 790 MockDemuxerStreamVector streams; |
| 795 streams.push_back(audio_stream()); | 791 streams.push_back(audio_stream()); |
| 796 streams.push_back(video_stream()); | 792 streams.push_back(video_stream()); |
| 797 | 793 |
| 798 SetDemuxerExpectations(&streams); | 794 SetDemuxerExpectations(&streams); |
| 799 SetRendererExpectations(); | 795 SetRendererExpectations(); |
| 800 StartPipelineAndExpect(PIPELINE_OK); | 796 StartPipelineAndExpect(PIPELINE_OK); |
| 801 | 797 |
| 802 // Simulate underflow. | 798 // Simulate underflow. |
| 803 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 799 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| 804 buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); | 800 renderer_client_->OnBufferingStateChange(BUFFERING_HAVE_NOTHING); |
| 805 message_loop_.RunUntilIdle(); | 801 message_loop_.RunUntilIdle(); |
| 806 | 802 |
| 807 // Seek while underflowed. | 803 // Seek while underflowed. |
| 808 base::TimeDelta expected = base::TimeDelta::FromSeconds(5); | 804 base::TimeDelta expected = base::TimeDelta::FromSeconds(5); |
| 809 ExpectSeek(expected, true); | 805 ExpectSeek(expected, true); |
| 810 DoSeek(expected); | 806 DoSeek(expected); |
| 811 } | 807 } |
| 812 | 808 |
| 813 TEST_F(PipelineImplTest, PositiveStartTime) { | 809 TEST_F(PipelineImplTest, PositiveStartTime) { |
| 814 start_time_ = base::TimeDelta::FromSeconds(1); | 810 start_time_ = base::TimeDelta::FromSeconds(1); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 MockDemuxerStreamVector streams; | 902 MockDemuxerStreamVector streams; |
| 907 streams.push_back(audio_stream()); | 903 streams.push_back(audio_stream()); |
| 908 streams.push_back(video_stream()); | 904 streams.push_back(video_stream()); |
| 909 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); | 905 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); |
| 910 | 906 |
| 911 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(true)); | 907 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(true)); |
| 912 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(true)); | 908 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(true)); |
| 913 | 909 |
| 914 if (state == kInitRenderer) { | 910 if (state == kInitRenderer) { |
| 915 if (stop_or_error == kStop) { | 911 if (stop_or_error == kStop) { |
| 916 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) | 912 EXPECT_CALL(*renderer_, Initialize(_, _, _)) |
| 917 .WillOnce( | 913 .WillOnce( |
| 918 DoAll(Stop(pipeline_.get()), PostCallback<1>(PIPELINE_OK))); | 914 DoAll(Stop(pipeline_.get()), PostCallback<2>(PIPELINE_OK))); |
| 919 // Note: OnStart or OnMetadata callback are not called | 915 // Note: OnStart or OnMetadata callback are not called |
| 920 // after pipeline is stopped. | 916 // after pipeline is stopped. |
| 921 } else { | 917 } else { |
| 922 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) | 918 EXPECT_CALL(*renderer_, Initialize(_, _, _)) |
| 923 .WillOnce(PostCallback<1>(PIPELINE_ERROR_INITIALIZATION_FAILED)); | 919 .WillOnce(PostCallback<2>(PIPELINE_ERROR_INITIALIZATION_FAILED)); |
| 924 EXPECT_CALL(callbacks_, OnMetadata(_)); | 920 EXPECT_CALL(callbacks_, OnMetadata(_)); |
| 925 EXPECT_CALL(callbacks_, OnStart(PIPELINE_ERROR_INITIALIZATION_FAILED)); | 921 EXPECT_CALL(callbacks_, OnStart(PIPELINE_ERROR_INITIALIZATION_FAILED)); |
| 926 } | 922 } |
| 927 | 923 |
| 928 EXPECT_CALL(*demuxer_, Stop()); | 924 EXPECT_CALL(*demuxer_, Stop()); |
| 929 return; | 925 return; |
| 930 } | 926 } |
| 931 | 927 |
| 932 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _, _)) | 928 EXPECT_CALL(*renderer_, Initialize(_, _, _)) |
| 933 .WillOnce(DoAll(SaveArg<3>(&buffering_state_cb_), | 929 .WillOnce( |
| 934 PostCallback<1>(PIPELINE_OK))); | 930 DoAll(SaveArg<1>(&renderer_client_), PostCallback<2>(PIPELINE_OK))); |
| 935 | 931 |
| 936 // If we get here it's a successful initialization. | 932 // If we get here it's a successful initialization. |
| 937 EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK)); | 933 EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK)); |
| 938 EXPECT_CALL(callbacks_, OnMetadata(_)); | 934 EXPECT_CALL(callbacks_, OnMetadata(_)); |
| 939 | 935 |
| 940 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0)); | 936 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0)); |
| 941 EXPECT_CALL(*renderer_, SetVolume(1.0f)); | 937 EXPECT_CALL(*renderer_, SetVolume(1.0f)); |
| 942 EXPECT_CALL(*renderer_, StartPlayingFrom(base::TimeDelta())) | 938 EXPECT_CALL(*renderer_, StartPlayingFrom(base::TimeDelta())) |
| 943 .WillOnce( | 939 .WillOnce(SetBufferingState(&renderer_client_, BUFFERING_HAVE_ENOUGH)); |
| 944 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_ENOUGH)); | |
| 945 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 940 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
| 946 } | 941 } |
| 947 | 942 |
| 948 void DoSeek(TeardownState state, StopOrError stop_or_error) { | 943 void DoSeek(TeardownState state, StopOrError stop_or_error) { |
| 949 SetSeekExpectations(state, stop_or_error); | 944 SetSeekExpectations(state, stop_or_error); |
| 950 | 945 |
| 951 EXPECT_CALL(*demuxer_, Stop()); | 946 EXPECT_CALL(*demuxer_, Stop()); |
| 952 | 947 |
| 953 pipeline_->Seek( | 948 pipeline_->Seek( |
| 954 base::TimeDelta::FromSeconds(10), | 949 base::TimeDelta::FromSeconds(10), |
| 955 base::Bind(&CallbackHelper::OnSeek, base::Unretained(&callbacks_))); | 950 base::Bind(&CallbackHelper::OnSeek, base::Unretained(&callbacks_))); |
| 956 message_loop_.RunUntilIdle(); | 951 message_loop_.RunUntilIdle(); |
| 957 } | 952 } |
| 958 | 953 |
| 959 void SetSeekExpectations(TeardownState state, StopOrError stop_or_error) { | 954 void SetSeekExpectations(TeardownState state, StopOrError stop_or_error) { |
| 960 if (state == kFlushing) { | 955 if (state == kFlushing) { |
| 961 if (stop_or_error == kStop) { | 956 if (stop_or_error == kStop) { |
| 962 EXPECT_CALL(*renderer_, Flush(_)) | 957 EXPECT_CALL(*renderer_, Flush(_)) |
| 963 .WillOnce(DoAll( | 958 .WillOnce(DoAll( |
| 964 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), | 959 SetBufferingState(&renderer_client_, BUFFERING_HAVE_NOTHING), |
| 965 Stop(pipeline_.get()), RunClosure<0>())); | 960 Stop(pipeline_.get()), RunClosure<0>())); |
| 966 // Note: OnBufferingStateChange or OnSeek callbacks are not called | 961 // Note: OnBufferingStateChange or OnSeek callbacks are not called |
| 967 // after pipeline is stopped. | 962 // after pipeline is stopped. |
| 968 } else { | 963 } else { |
| 969 EXPECT_CALL(*renderer_, Flush(_)) | 964 EXPECT_CALL(*renderer_, Flush(_)) |
| 970 .WillOnce(DoAll( | 965 .WillOnce(DoAll( |
| 971 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), | 966 SetBufferingState(&renderer_client_, BUFFERING_HAVE_NOTHING), |
| 972 SetError(pipeline_.get(), PIPELINE_ERROR_READ), | 967 SetError(pipeline_.get(), PIPELINE_ERROR_READ), |
| 973 RunClosure<0>())); | 968 RunClosure<0>())); |
| 974 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 969 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| 975 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); | 970 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); |
| 976 } | 971 } |
| 977 return; | 972 return; |
| 978 } | 973 } |
| 979 | 974 |
| 980 EXPECT_CALL(*renderer_, Flush(_)) | 975 EXPECT_CALL(*renderer_, Flush(_)) |
| 981 .WillOnce(DoAll( | 976 .WillOnce( |
| 982 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), | 977 DoAll(SetBufferingState(&renderer_client_, BUFFERING_HAVE_NOTHING), |
| 983 RunClosure<0>())); | 978 RunClosure<0>())); |
| 984 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 979 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| 985 | 980 |
| 986 if (state == kSeeking) { | 981 if (state == kSeeking) { |
| 987 if (stop_or_error == kStop) { | 982 if (stop_or_error == kStop) { |
| 988 EXPECT_CALL(*demuxer_, Seek(_, _)) | 983 EXPECT_CALL(*demuxer_, Seek(_, _)) |
| 989 .WillOnce( | 984 .WillOnce( |
| 990 DoAll(Stop(pipeline_.get()), RunCallback<1>(PIPELINE_OK))); | 985 DoAll(Stop(pipeline_.get()), RunCallback<1>(PIPELINE_OK))); |
| 991 // Note: OnSeek callback is not called after pipeline is stopped. | 986 // Note: OnSeek callback is not called after pipeline is stopped. |
| 992 } else { | 987 } else { |
| 993 EXPECT_CALL(*demuxer_, Seek(_, _)) | 988 EXPECT_CALL(*demuxer_, Seek(_, _)) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1017 // kSuspended, kSuspending never throw errors, since Resume() is always able | 1012 // kSuspended, kSuspending never throw errors, since Resume() is always able |
| 1018 // to restore the pipeline to a pristine state. | 1013 // to restore the pipeline to a pristine state. |
| 1019 DoStopOrError(stop_or_error, false); | 1014 DoStopOrError(stop_or_error, false); |
| 1020 } | 1015 } |
| 1021 | 1016 |
| 1022 void SetSuspendExpectations(TeardownState state, StopOrError stop_or_error) { | 1017 void SetSuspendExpectations(TeardownState state, StopOrError stop_or_error) { |
| 1023 EXPECT_CALL(*renderer_, SetPlaybackRate(0)); | 1018 EXPECT_CALL(*renderer_, SetPlaybackRate(0)); |
| 1024 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); | 1019 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| 1025 EXPECT_CALL(callbacks_, OnSuspend(PIPELINE_OK)); | 1020 EXPECT_CALL(callbacks_, OnSuspend(PIPELINE_OK)); |
| 1026 EXPECT_CALL(*renderer_, Flush(_)) | 1021 EXPECT_CALL(*renderer_, Flush(_)) |
| 1027 .WillOnce(DoAll( | 1022 .WillOnce( |
| 1028 SetBufferingState(&buffering_state_cb_, BUFFERING_HAVE_NOTHING), | 1023 DoAll(SetBufferingState(&renderer_client_, BUFFERING_HAVE_NOTHING), |
| 1029 RunClosure<0>())); | 1024 RunClosure<0>())); |
| 1030 if (state == kResuming) { | 1025 if (state == kResuming) { |
| 1031 if (stop_or_error == kStop) { | 1026 if (stop_or_error == kStop) { |
| 1032 EXPECT_CALL(*demuxer_, Seek(_, _)) | 1027 EXPECT_CALL(*demuxer_, Seek(_, _)) |
| 1033 .WillOnce( | 1028 .WillOnce( |
| 1034 DoAll(Stop(pipeline_.get()), RunCallback<1>(PIPELINE_OK))); | 1029 DoAll(Stop(pipeline_.get()), RunCallback<1>(PIPELINE_OK))); |
| 1035 // Note: OnResume callback is not called after pipeline is stopped. | 1030 // Note: OnResume callback is not called after pipeline is stopped. |
| 1036 } else { | 1031 } else { |
| 1037 EXPECT_CALL(*demuxer_, Seek(_, _)) | 1032 EXPECT_CALL(*demuxer_, Seek(_, _)) |
| 1038 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); | 1033 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); |
| 1039 EXPECT_CALL(callbacks_, OnResume(PIPELINE_ERROR_READ)); | 1034 EXPECT_CALL(callbacks_, OnResume(PIPELINE_ERROR_READ)); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1096 INSTANTIATE_TEARDOWN_TEST(Error, Seeking); | 1091 INSTANTIATE_TEARDOWN_TEST(Error, Seeking); |
| 1097 INSTANTIATE_TEARDOWN_TEST(Error, Playing); | 1092 INSTANTIATE_TEARDOWN_TEST(Error, Playing); |
| 1098 INSTANTIATE_TEARDOWN_TEST(Error, Suspending); | 1093 INSTANTIATE_TEARDOWN_TEST(Error, Suspending); |
| 1099 INSTANTIATE_TEARDOWN_TEST(Error, Suspended); | 1094 INSTANTIATE_TEARDOWN_TEST(Error, Suspended); |
| 1100 INSTANTIATE_TEARDOWN_TEST(Error, Resuming); | 1095 INSTANTIATE_TEARDOWN_TEST(Error, Resuming); |
| 1101 | 1096 |
| 1102 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing); | 1097 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing); |
| 1103 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Suspended); | 1098 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Suspended); |
| 1104 | 1099 |
| 1105 } // namespace media | 1100 } // namespace media |
| OLD | NEW |