OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <vector> | 5 #include <vector> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
10 #include "base/test/simple_test_tick_clock.h" | 10 #include "base/test/simple_test_tick_clock.h" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
103 SaveArg<6>(&video_ended_cb_), RunCallback<1>(status))); | 103 SaveArg<6>(&video_ended_cb_), RunCallback<1>(status))); |
104 } | 104 } |
105 | 105 |
106 void InitializeAndExpect(PipelineStatus start_status) { | 106 void InitializeAndExpect(PipelineStatus start_status) { |
107 EXPECT_CALL(callbacks_, OnInitialize(start_status)); | 107 EXPECT_CALL(callbacks_, OnInitialize(start_status)); |
108 EXPECT_CALL(callbacks_, OnWaitingForDecryptionKey()).Times(0); | 108 EXPECT_CALL(callbacks_, OnWaitingForDecryptionKey()).Times(0); |
109 | 109 |
110 if (start_status == PIPELINE_OK && audio_stream_) { | 110 if (start_status == PIPELINE_OK && audio_stream_) { |
111 EXPECT_CALL(*audio_renderer_, GetTimeSource()) | 111 EXPECT_CALL(*audio_renderer_, GetTimeSource()) |
112 .WillOnce(Return(&time_source_)); | 112 .WillOnce(Return(&time_source_)); |
113 } else { | |
114 renderer_impl_->set_time_source_for_testing(&time_source_); | |
113 } | 115 } |
114 | 116 |
115 renderer_impl_->Initialize( | 117 renderer_impl_->Initialize( |
116 demuxer_.get(), | 118 demuxer_.get(), |
117 base::Bind(&CallbackHelper::OnInitialize, | 119 base::Bind(&CallbackHelper::OnInitialize, |
118 base::Unretained(&callbacks_)), | 120 base::Unretained(&callbacks_)), |
119 base::Bind(&CallbackHelper::OnUpdateStatistics, | 121 base::Bind(&CallbackHelper::OnUpdateStatistics, |
120 base::Unretained(&callbacks_)), | 122 base::Unretained(&callbacks_)), |
121 base::Bind(&CallbackHelper::OnBufferingStateChange, | 123 base::Bind(&CallbackHelper::OnBufferingStateChange, |
122 base::Unretained(&callbacks_)), | 124 base::Unretained(&callbacks_)), |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
167 SetVideoRendererInitializeExpectations(PIPELINE_OK); | 169 SetVideoRendererInitializeExpectations(PIPELINE_OK); |
168 InitializeAndExpect(PIPELINE_OK); | 170 InitializeAndExpect(PIPELINE_OK); |
169 } | 171 } |
170 | 172 |
171 void Play() { | 173 void Play() { |
172 DCHECK(audio_stream_ || video_stream_); | 174 DCHECK(audio_stream_ || video_stream_); |
173 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); | 175 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
174 | 176 |
175 base::TimeDelta start_time( | 177 base::TimeDelta start_time( |
176 base::TimeDelta::FromMilliseconds(kStartPlayingTimeInMs)); | 178 base::TimeDelta::FromMilliseconds(kStartPlayingTimeInMs)); |
179 EXPECT_CALL(time_source_, SetMediaTime(start_time)); | |
180 EXPECT_CALL(time_source_, StartTicking()); | |
177 | 181 |
178 if (audio_stream_) { | 182 if (audio_stream_) { |
179 EXPECT_CALL(time_source_, SetMediaTime(start_time)); | |
180 EXPECT_CALL(time_source_, StartTicking()); | |
181 EXPECT_CALL(*audio_renderer_, StartPlaying()) | 183 EXPECT_CALL(*audio_renderer_, StartPlaying()) |
182 .WillOnce(SetBufferingState(&audio_buffering_state_cb_, | 184 .WillOnce(SetBufferingState(&audio_buffering_state_cb_, |
183 BUFFERING_HAVE_ENOUGH)); | 185 BUFFERING_HAVE_ENOUGH)); |
184 } | 186 } |
185 | 187 |
186 if (video_stream_) { | 188 if (video_stream_) { |
187 EXPECT_CALL(*video_renderer_, StartPlayingFrom(start_time)) | 189 EXPECT_CALL(*video_renderer_, StartPlayingFrom(start_time)) |
188 .WillOnce(SetBufferingState(&video_buffering_state_cb_, | 190 .WillOnce(SetBufferingState(&video_buffering_state_cb_, |
189 BUFFERING_HAVE_ENOUGH)); | 191 BUFFERING_HAVE_ENOUGH)); |
190 } | 192 } |
191 | 193 |
192 renderer_impl_->StartPlayingFrom(start_time); | 194 renderer_impl_->StartPlayingFrom(start_time); |
193 base::RunLoop().RunUntilIdle(); | 195 base::RunLoop().RunUntilIdle(); |
194 } | 196 } |
195 | 197 |
196 void Flush(bool underflowed) { | 198 void Flush(bool underflowed) { |
199 if (!underflowed) | |
200 EXPECT_CALL(time_source_, StopTicking()); | |
201 | |
197 if (audio_stream_) { | 202 if (audio_stream_) { |
198 if (!underflowed) | |
199 EXPECT_CALL(time_source_, StopTicking()); | |
200 EXPECT_CALL(*audio_renderer_, Flush(_)) | 203 EXPECT_CALL(*audio_renderer_, Flush(_)) |
201 .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_, | 204 .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_, |
202 BUFFERING_HAVE_NOTHING), | 205 BUFFERING_HAVE_NOTHING), |
203 RunClosure<0>())); | 206 RunClosure<0>())); |
204 } | 207 } |
205 | 208 |
206 if (video_stream_) { | 209 if (video_stream_) { |
207 EXPECT_CALL(*video_renderer_, Flush(_)) | 210 EXPECT_CALL(*video_renderer_, Flush(_)) |
208 .WillOnce(DoAll(SetBufferingState(&video_buffering_state_cb_, | 211 .WillOnce(DoAll(SetBufferingState(&video_buffering_state_cb_, |
209 BUFFERING_HAVE_NOTHING), | 212 BUFFERING_HAVE_NOTHING), |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
360 EXPECT_CALL(callbacks_, OnEnded()); | 363 EXPECT_CALL(callbacks_, OnEnded()); |
361 | 364 |
362 audio_ended_cb_.Run(); | 365 audio_ended_cb_.Run(); |
363 base::RunLoop().RunUntilIdle(); | 366 base::RunLoop().RunUntilIdle(); |
364 } | 367 } |
365 | 368 |
366 TEST_F(RendererImplTest, VideoStreamEnded) { | 369 TEST_F(RendererImplTest, VideoStreamEnded) { |
367 InitializeWithVideo(); | 370 InitializeWithVideo(); |
368 Play(); | 371 Play(); |
369 | 372 |
370 // Video ended won't affect |time_source_|. | 373 EXPECT_CALL(time_source_, StopTicking()); |
371 EXPECT_CALL(callbacks_, OnEnded()); | 374 EXPECT_CALL(callbacks_, OnEnded()); |
372 | 375 |
373 video_ended_cb_.Run(); | 376 video_ended_cb_.Run(); |
374 base::RunLoop().RunUntilIdle(); | 377 base::RunLoop().RunUntilIdle(); |
375 } | 378 } |
376 | 379 |
377 TEST_F(RendererImplTest, AudioVideoStreamsEnded) { | 380 TEST_F(RendererImplTest, AudioVideoStreamsEnded) { |
378 InitializeWithAudioAndVideo(); | 381 InitializeWithAudioAndVideo(); |
379 Play(); | 382 Play(); |
380 | 383 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
439 EXPECT_CALL(*video_renderer_, | 442 EXPECT_CALL(*video_renderer_, |
440 Initialize(video_stream_.get(), _, _, _, _, _, _, _, _, _)) | 443 Initialize(video_stream_.get(), _, _, _, _, _, _, _, _, _)) |
441 .WillOnce(DoAll(AudioError(&audio_error_cb_, PIPELINE_ERROR_DECODE), | 444 .WillOnce(DoAll(AudioError(&audio_error_cb_, PIPELINE_ERROR_DECODE), |
442 SaveArg<4>(&video_buffering_state_cb_), | 445 SaveArg<4>(&video_buffering_state_cb_), |
443 SaveArg<6>(&video_ended_cb_), | 446 SaveArg<6>(&video_ended_cb_), |
444 RunCallback<1>(PIPELINE_OK))); | 447 RunCallback<1>(PIPELINE_OK))); |
445 | 448 |
446 InitializeAndExpect(PIPELINE_ERROR_DECODE); | 449 InitializeAndExpect(PIPELINE_ERROR_DECODE); |
447 } | 450 } |
448 | 451 |
452 TEST_F(RendererImplTest, AudioUnderflow) { | |
453 InitializeWithAudio(); | |
454 Play(); | |
455 | |
456 // Underflow should occur immediately with a single audio track. | |
457 EXPECT_CALL(time_source_, StopTicking()); | |
458 audio_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); | |
459 } | |
460 | |
461 TEST_F(RendererImplTest, AudioUnderflowWithVideo) { | |
462 InitializeWithAudioAndVideo(); | |
463 Play(); | |
464 | |
465 // Underflow should be immediate when both audio and video are present and | |
466 // audio underflows. | |
467 EXPECT_CALL(time_source_, StopTicking()); | |
468 audio_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); | |
469 } | |
470 | |
471 TEST_F(RendererImplTest, VideoUnderflow) { | |
472 InitializeWithVideo(); | |
473 Play(); | |
474 | |
475 // Underflow should occur immediately with a single video track. | |
xhwang
2015/03/26 21:24:43
I am not sure about this... did you try to trigger
DaleCurtis
2015/03/26 21:36:08
Hmm, the main goal is to fix http://crbug.com/4238
xhwang
2015/03/28 00:32:40
Ah, I forgot about the bug. Thanks for reminding m
DaleCurtis
2015/03/30 16:17:16
Thanks for the detailed thoughts. I agree with wha
| |
476 EXPECT_CALL(time_source_, StopTicking()); | |
477 video_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); | |
478 } | |
479 | |
480 TEST_F(RendererImplTest, VideoUnderflowWithAudio) { | |
481 InitializeWithAudioAndVideo(); | |
482 Play(); | |
483 | |
484 // Set a zero threshold such that the underflow will be executed on the next | |
485 // run of the message loop. | |
486 renderer_impl_->set_video_underflow_threshold_for_testing(base::TimeDelta()); | |
487 | |
488 // Underflow should be delayed when both audio and video are present and video | |
489 // underflows. | |
490 video_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); | |
491 Mock::VerifyAndClearExpectations(&time_source_); | |
492 | |
493 EXPECT_CALL(time_source_, StopTicking()); | |
494 base::RunLoop().RunUntilIdle(); | |
495 } | |
496 | |
497 TEST_F(RendererImplTest, VideoUnderflowWithAudioVideoRecovers) { | |
498 InitializeWithAudioAndVideo(); | |
499 Play(); | |
500 | |
501 // Set a zero threshold such that the underflow will be executed on the next | |
502 // run of the message loop. | |
503 renderer_impl_->set_video_underflow_threshold_for_testing(base::TimeDelta()); | |
504 | |
505 // Underflow should be delayed when both audio and video are present and video | |
506 // underflows. | |
xhwang
2015/03/26 21:24:43
This is not accurate now given the threshold is 0.
DaleCurtis
2015/03/26 21:36:08
Well, it's accurate in the sense that it's delayed
| |
507 video_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); | |
508 Mock::VerifyAndClearExpectations(&time_source_); | |
509 | |
510 // If video recovers, the underflow should never occur. | |
511 video_buffering_state_cb_.Run(BUFFERING_HAVE_ENOUGH); | |
512 base::RunLoop().RunUntilIdle(); | |
513 } | |
514 | |
515 TEST_F(RendererImplTest, VideoAndAudioUnderflow) { | |
516 InitializeWithAudioAndVideo(); | |
517 Play(); | |
518 | |
519 // Set a zero threshold such that the underflow will be executed on the next | |
520 // run of the message loop. | |
521 renderer_impl_->set_video_underflow_threshold_for_testing(base::TimeDelta()); | |
522 | |
523 // Underflow should be delayed when both audio and video are present and video | |
524 // underflows. | |
525 video_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); | |
526 Mock::VerifyAndClearExpectations(&time_source_); | |
527 | |
528 EXPECT_CALL(time_source_, StopTicking()); | |
529 audio_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); | |
530 | |
531 // Nothing else should primed on the message loop. | |
532 base::RunLoop().RunUntilIdle(); | |
533 } | |
534 | |
449 } // namespace media | 535 } // namespace media |
OLD | NEW |