Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(820)

Side by Side Diff: media/filters/renderer_impl_unittest.cc

Issue 534073002: Switch to using media::TimeSource inside media::RendererImpl. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix bad rebase Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/filters/renderer_impl.cc ('k') | media/filters/video_renderer_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "media/base/gmock_callback_support.h" 11 #include "media/base/gmock_callback_support.h"
12 #include "media/base/mock_filters.h" 12 #include "media/base/mock_filters.h"
13 #include "media/base/test_helpers.h" 13 #include "media/base/test_helpers.h"
14 #include "media/base/time_delta_interpolator.h"
15 #include "media/filters/renderer_impl.h" 14 #include "media/filters/renderer_impl.h"
16 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
17 16
18 using ::testing::_; 17 using ::testing::_;
19 using ::testing::DoAll; 18 using ::testing::DoAll;
20 using ::testing::InSequence; 19 using ::testing::InSequence;
21 using ::testing::Mock; 20 using ::testing::Mock;
22 using ::testing::Return; 21 using ::testing::Return;
23 using ::testing::SaveArg; 22 using ::testing::SaveArg;
24 using ::testing::StrictMock; 23 using ::testing::StrictMock;
25 24
26 namespace media { 25 namespace media {
27 26
28 const int64 kStartPlayingTimeInMs = 100; 27 const int64 kStartPlayingTimeInMs = 100;
29 const int64 kDurationInMs = 3000;
30 const int64 kAudioUpdateTimeMs = 150;
31 const int64 kAudioUpdateMaxTimeMs = 1000;
32 28
33 ACTION_P2(SetBufferingState, cb, buffering_state) { 29 ACTION_P2(SetBufferingState, cb, buffering_state) {
34 cb->Run(buffering_state); 30 cb->Run(buffering_state);
35 } 31 }
36 32
37 ACTION_P3(UpdateAudioTime, cb, time, max_time) {
38 cb->Run(base::TimeDelta::FromMilliseconds(time),
39 base::TimeDelta::FromMilliseconds(max_time));
40 }
41
42 ACTION_P2(AudioError, cb, error) { 33 ACTION_P2(AudioError, cb, error) {
43 cb->Run(error); 34 cb->Run(error);
44 } 35 }
45 36
46 static base::TimeDelta GetDuration() {
47 return base::TimeDelta::FromMilliseconds(kDurationInMs);
48 }
49
50 class RendererImplTest : public ::testing::Test { 37 class RendererImplTest : public ::testing::Test {
51 public: 38 public:
52 // Used for setting expectations on pipeline callbacks. Using a StrictMock 39 // Used for setting expectations on pipeline callbacks. Using a StrictMock
53 // also lets us test for missing callbacks. 40 // also lets us test for missing callbacks.
54 class CallbackHelper { 41 class CallbackHelper {
55 public: 42 public:
56 CallbackHelper() {} 43 CallbackHelper() {}
57 virtual ~CallbackHelper() {} 44 virtual ~CallbackHelper() {}
58 45
59 MOCK_METHOD0(OnInitialize, void()); 46 MOCK_METHOD0(OnInitialize, void());
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 scoped_ptr<StrictMock<MockDemuxerStream> > CreateStream( 83 scoped_ptr<StrictMock<MockDemuxerStream> > CreateStream(
97 DemuxerStream::Type type) { 84 DemuxerStream::Type type) {
98 scoped_ptr<StrictMock<MockDemuxerStream> > stream( 85 scoped_ptr<StrictMock<MockDemuxerStream> > stream(
99 new StrictMock<MockDemuxerStream>(type)); 86 new StrictMock<MockDemuxerStream>(type));
100 return stream.Pass(); 87 return stream.Pass();
101 } 88 }
102 89
103 // Sets up expectations to allow the audio renderer to initialize. 90 // Sets up expectations to allow the audio renderer to initialize.
104 void SetAudioRendererInitializeExpectations(PipelineStatus status) { 91 void SetAudioRendererInitializeExpectations(PipelineStatus status) {
105 EXPECT_CALL(*audio_renderer_, 92 EXPECT_CALL(*audio_renderer_,
106 Initialize(audio_stream_.get(), _, _, _, _, _, _)) 93 Initialize(audio_stream_.get(), _, _, _, _, _))
107 .WillOnce(DoAll(SaveArg<3>(&audio_time_cb_), 94 .WillOnce(DoAll(SaveArg<3>(&audio_buffering_state_cb_),
108 SaveArg<4>(&audio_buffering_state_cb_), 95 SaveArg<4>(&audio_ended_cb_),
109 SaveArg<5>(&audio_ended_cb_), 96 SaveArg<5>(&audio_error_cb_),
110 SaveArg<6>(&audio_error_cb_),
111 RunCallback<1>(status))); 97 RunCallback<1>(status)));
112 if (status == PIPELINE_OK) {
113 EXPECT_CALL(*audio_renderer_, GetTimeSource())
114 .WillOnce(Return(&time_source_));
115 }
116 } 98 }
117 99
118 // Sets up expectations to allow the video renderer to initialize. 100 // Sets up expectations to allow the video renderer to initialize.
119 void SetVideoRendererInitializeExpectations(PipelineStatus status) { 101 void SetVideoRendererInitializeExpectations(PipelineStatus status) {
120 EXPECT_CALL(*video_renderer_, 102 EXPECT_CALL(*video_renderer_,
121 Initialize(video_stream_.get(), _, _, _, _, _, _, _, _, _)) 103 Initialize(video_stream_.get(), _, _, _, _, _, _, _))
122 .WillOnce(DoAll(SaveArg<5>(&video_buffering_state_cb_), 104 .WillOnce(DoAll(SaveArg<4>(&video_buffering_state_cb_),
123 SaveArg<6>(&video_ended_cb_), 105 SaveArg<5>(&video_ended_cb_),
124 RunCallback<2>(status))); 106 RunCallback<2>(status)));
125 } 107 }
126 108
127 void InitializeAndExpect(PipelineStatus start_status) { 109 void InitializeAndExpect(PipelineStatus start_status) {
128 if (start_status != PIPELINE_OK) 110 if (start_status != PIPELINE_OK)
129 EXPECT_CALL(callbacks_, OnError(start_status)); 111 EXPECT_CALL(callbacks_, OnError(start_status));
130 112
131 EXPECT_CALL(callbacks_, OnInitialize()); 113 EXPECT_CALL(callbacks_, OnInitialize());
132 114
115 if (start_status == PIPELINE_OK && audio_stream_) {
116 EXPECT_CALL(*audio_renderer_, GetTimeSource())
117 .WillOnce(Return(&time_source_));
118 }
119
133 renderer_impl_->Initialize( 120 renderer_impl_->Initialize(
134 base::Bind(&CallbackHelper::OnInitialize, 121 base::Bind(&CallbackHelper::OnInitialize,
135 base::Unretained(&callbacks_)), 122 base::Unretained(&callbacks_)),
136 base::Bind(&CallbackHelper::OnUpdateStatistics, 123 base::Bind(&CallbackHelper::OnUpdateStatistics,
137 base::Unretained(&callbacks_)), 124 base::Unretained(&callbacks_)),
138 base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)), 125 base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
139 base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)), 126 base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
140 base::Bind(&CallbackHelper::OnBufferingStateChange, 127 base::Bind(&CallbackHelper::OnBufferingStateChange,
141 base::Unretained(&callbacks_)), 128 base::Unretained(&callbacks_)));
142 base::Bind(&GetDuration));
143 base::RunLoop().RunUntilIdle(); 129 base::RunLoop().RunUntilIdle();
144 } 130 }
145 131
146 void CreateAudioStream() { 132 void CreateAudioStream() {
147 audio_stream_ = CreateStream(DemuxerStream::AUDIO); 133 audio_stream_ = CreateStream(DemuxerStream::AUDIO);
148 streams_.push_back(audio_stream_.get()); 134 streams_.push_back(audio_stream_.get());
149 EXPECT_CALL(*demuxer_, GetStream(DemuxerStream::AUDIO)) 135 EXPECT_CALL(*demuxer_, GetStream(DemuxerStream::AUDIO))
150 .WillRepeatedly(Return(audio_stream_.get())); 136 .WillRepeatedly(Return(audio_stream_.get()));
151 } 137 }
152 138
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 252
267 scoped_ptr<StrictMock<MockDemuxer> > demuxer_; 253 scoped_ptr<StrictMock<MockDemuxer> > demuxer_;
268 StrictMock<MockVideoRenderer>* video_renderer_; 254 StrictMock<MockVideoRenderer>* video_renderer_;
269 StrictMock<MockAudioRenderer>* audio_renderer_; 255 StrictMock<MockAudioRenderer>* audio_renderer_;
270 scoped_ptr<RendererImpl> renderer_impl_; 256 scoped_ptr<RendererImpl> renderer_impl_;
271 257
272 StrictMock<MockTimeSource> time_source_; 258 StrictMock<MockTimeSource> time_source_;
273 scoped_ptr<StrictMock<MockDemuxerStream> > audio_stream_; 259 scoped_ptr<StrictMock<MockDemuxerStream> > audio_stream_;
274 scoped_ptr<StrictMock<MockDemuxerStream> > video_stream_; 260 scoped_ptr<StrictMock<MockDemuxerStream> > video_stream_;
275 MockDemuxerStreamVector streams_; 261 MockDemuxerStreamVector streams_;
276 AudioRenderer::TimeCB audio_time_cb_;
277 BufferingStateCB audio_buffering_state_cb_; 262 BufferingStateCB audio_buffering_state_cb_;
278 BufferingStateCB video_buffering_state_cb_; 263 BufferingStateCB video_buffering_state_cb_;
279 base::Closure audio_ended_cb_; 264 base::Closure audio_ended_cb_;
280 base::Closure video_ended_cb_; 265 base::Closure video_ended_cb_;
281 PipelineStatusCB audio_error_cb_; 266 PipelineStatusCB audio_error_cb_;
282 VideoDecoderConfig video_decoder_config_; 267 VideoDecoderConfig video_decoder_config_;
283 268
284 private: 269 private:
285 DISALLOW_COPY_AND_ASSIGN(RendererImplTest); 270 DISALLOW_COPY_AND_ASSIGN(RendererImplTest);
286 }; 271 };
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 SetPlaybackRate(1.0f); 345 SetPlaybackRate(1.0f);
361 SetPlaybackRate(2.0f); 346 SetPlaybackRate(2.0f);
362 } 347 }
363 348
364 TEST_F(RendererImplTest, SetVolume) { 349 TEST_F(RendererImplTest, SetVolume) {
365 InitializeWithAudioAndVideo(); 350 InitializeWithAudioAndVideo();
366 EXPECT_CALL(*audio_renderer_, SetVolume(2.0f)); 351 EXPECT_CALL(*audio_renderer_, SetVolume(2.0f));
367 renderer_impl_->SetVolume(2.0f); 352 renderer_impl_->SetVolume(2.0f);
368 } 353 }
369 354
370 TEST_F(RendererImplTest, GetMediaTime) {
371 // Replace what's used for interpolating to simulate wall clock time.
372 renderer_impl_->SetTimeDeltaInterpolatorForTesting(
373 new TimeDeltaInterpolator(&test_tick_clock_));
374
375 InitializeWithAudioAndVideo();
376 Play();
377
378 EXPECT_EQ(kStartPlayingTimeInMs, GetMediaTimeMs());
379
380 // Verify that the clock doesn't advance since it hasn't been started by
381 // a time update from the audio stream.
382 EXPECT_FALSE(IsMediaTimeAdvancing());
383
384 // Provide an initial time update so that the pipeline transitions out of the
385 // "waiting for time update" state.
386 audio_time_cb_.Run(base::TimeDelta::FromMilliseconds(kAudioUpdateTimeMs),
387 base::TimeDelta::FromMilliseconds(kAudioUpdateMaxTimeMs));
388 EXPECT_EQ(kAudioUpdateTimeMs, GetMediaTimeMs());
389
390 // Advance the clock so that GetMediaTime() also advances. This also verifies
391 // that the default playback rate is 1.
392 EXPECT_TRUE(IsMediaTimeAdvancing());
393
394 // Verify that playback rate affects the rate GetMediaTime() advances.
395 SetPlaybackRate(2.0f);
396 EXPECT_TRUE(IsMediaTimeAdvancing(2.0f));
397
398 // Verify that GetMediaTime() is bounded by audio max time.
399 DCHECK_GT(GetMediaTimeMs() + 2000, kAudioUpdateMaxTimeMs);
400 test_tick_clock_.Advance(base::TimeDelta::FromMilliseconds(2000));
401 EXPECT_EQ(kAudioUpdateMaxTimeMs, GetMediaTimeMs());
402 }
403
404 TEST_F(RendererImplTest, AudioTimeUpdateDuringFlush) {
405 // Replace what's used for interpolating to simulate wall clock time.
406 renderer_impl_->SetTimeDeltaInterpolatorForTesting(
407 new TimeDeltaInterpolator(&test_tick_clock_));
408
409 InitializeWithAudio();
410 Play();
411
412 // Provide an initial time update so that the pipeline transitions out of the
413 // "waiting for time update" state.
414 audio_time_cb_.Run(base::TimeDelta::FromMilliseconds(kAudioUpdateTimeMs),
415 base::TimeDelta::FromMilliseconds(kAudioUpdateMaxTimeMs));
416 EXPECT_EQ(kAudioUpdateTimeMs, GetMediaTimeMs());
417
418 int64 start_time = GetMediaTimeMs();
419
420 EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce(DoAll(
421 UpdateAudioTime(
422 &audio_time_cb_, kAudioUpdateTimeMs + 100, kAudioUpdateMaxTimeMs),
423 SetBufferingState(&audio_buffering_state_cb_, BUFFERING_HAVE_NOTHING),
424 RunClosure<0>()));
425 EXPECT_CALL(time_source_, StopTicking());
426 EXPECT_CALL(callbacks_, OnFlushed());
427 renderer_impl_->Flush(
428 base::Bind(&CallbackHelper::OnFlushed, base::Unretained(&callbacks_)));
429
430 // Audio time update during Flush() has no effect.
431 EXPECT_EQ(start_time, GetMediaTimeMs());
432
433 // Verify that the clock doesn't advance since it hasn't been started by
434 // a time update from the audio stream.
435 EXPECT_FALSE(IsMediaTimeAdvancing());
436 }
437
438 TEST_F(RendererImplTest, PostTimeUpdateDuringDestroy) {
439 InitializeWithAudioAndVideo();
440
441 // Simulate the case where TimeCB is posted during ~AudioRenderer(), which is
442 // triggered in ~Renderer().
443 base::TimeDelta time = base::TimeDelta::FromMilliseconds(100);
444 message_loop_.PostTask(FROM_HERE, base::Bind(audio_time_cb_, time, time));
445
446 renderer_impl_.reset();
447 message_loop_.RunUntilIdle();
448 }
449
450 TEST_F(RendererImplTest, AudioStreamEnded) { 355 TEST_F(RendererImplTest, AudioStreamEnded) {
451 InitializeWithAudio(); 356 InitializeWithAudio();
452 Play(); 357 Play();
453 358
454 EXPECT_CALL(time_source_, StopTicking()); 359 EXPECT_CALL(time_source_, StopTicking());
455 EXPECT_CALL(callbacks_, OnEnded()); 360 EXPECT_CALL(callbacks_, OnEnded());
456 361
457 audio_ended_cb_.Run(); 362 audio_ended_cb_.Run();
458 base::RunLoop().RunUntilIdle(); 363 base::RunLoop().RunUntilIdle();
459 } 364 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 InitializeWithAudio(); 425 InitializeWithAudio();
521 Play(); 426 Play();
522 Flush(false); 427 Flush(false);
523 428
524 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_DECODE)); 429 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_DECODE));
525 audio_error_cb_.Run(PIPELINE_ERROR_DECODE); 430 audio_error_cb_.Run(PIPELINE_ERROR_DECODE);
526 base::RunLoop().RunUntilIdle(); 431 base::RunLoop().RunUntilIdle();
527 } 432 }
528 433
529 } // namespace media 434 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/renderer_impl.cc ('k') | media/filters/video_renderer_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698