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

Side by Side Diff: media/base/pipeline_unittest.cc

Issue 503053007: Revert of media: Introduce Renderer interface and RendererImpl. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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 | Annotate | Revision Log
« no previous file with comments | « media/base/pipeline.cc ('k') | media/base/renderer.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 (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 <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/stl_util.h" 9 #include "base/stl_util.h"
10 #include "base/test/simple_test_tick_clock.h" 10 #include "base/test/simple_test_tick_clock.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 } 48 }
49 49
50 ACTION_P2(SetError, pipeline, status) { 50 ACTION_P2(SetError, pipeline, status) {
51 pipeline->SetErrorForTesting(status); 51 pipeline->SetErrorForTesting(status);
52 } 52 }
53 53
54 ACTION_P2(SetBufferingState, cb, buffering_state) { 54 ACTION_P2(SetBufferingState, cb, buffering_state) {
55 cb->Run(buffering_state); 55 cb->Run(buffering_state);
56 } 56 }
57 57
58 // Used for setting expectations on pipeline callbacks. Using a StrictMock
59 // also lets us test for missing callbacks.
60 class CallbackHelper {
61 public:
62 CallbackHelper() {}
63 virtual ~CallbackHelper() {}
64
65 MOCK_METHOD1(OnStart, void(PipelineStatus));
66 MOCK_METHOD1(OnSeek, void(PipelineStatus));
67 MOCK_METHOD0(OnStop, void());
68 MOCK_METHOD0(OnEnded, void());
69 MOCK_METHOD1(OnError, void(PipelineStatus));
70 MOCK_METHOD1(OnMetadata, void(PipelineMetadata));
71 MOCK_METHOD1(OnBufferingStateChange, void(BufferingState));
72 MOCK_METHOD0(OnDurationChange, void());
73
74 private:
75 DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
76 };
77
58 // TODO(scherkus): even though some filters are initialized on separate 78 // TODO(scherkus): even though some filters are initialized on separate
59 // threads these test aren't flaky... why? It's because filters' Initialize() 79 // threads these test aren't flaky... why? It's because filters' Initialize()
60 // is executed on |message_loop_| and the mock filters instantly call 80 // is executed on |message_loop_| and the mock filters instantly call
61 // InitializationComplete(), which keeps the pipeline humming along. If 81 // InitializationComplete(), which keeps the pipeline humming along. If
62 // either filters don't call InitializationComplete() immediately or filter 82 // either filters don't call InitializationComplete() immediately or filter
63 // initialization is moved to a separate thread this test will become flaky. 83 // initialization is moved to a separate thread this test will become flaky.
64 class PipelineTest : public ::testing::Test { 84 class PipelineTest : public ::testing::Test {
65 public: 85 public:
66 // Used for setting expectations on pipeline callbacks. Using a StrictMock
67 // also lets us test for missing callbacks.
68 class CallbackHelper {
69 public:
70 CallbackHelper() {}
71 virtual ~CallbackHelper() {}
72
73 MOCK_METHOD1(OnStart, void(PipelineStatus));
74 MOCK_METHOD1(OnSeek, void(PipelineStatus));
75 MOCK_METHOD0(OnStop, void());
76 MOCK_METHOD0(OnEnded, void());
77 MOCK_METHOD1(OnError, void(PipelineStatus));
78 MOCK_METHOD1(OnMetadata, void(PipelineMetadata));
79 MOCK_METHOD1(OnBufferingStateChange, void(BufferingState));
80 MOCK_METHOD0(OnDurationChange, void());
81
82 private:
83 DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
84 };
85
86 PipelineTest() 86 PipelineTest()
87 : pipeline_(new Pipeline(message_loop_.message_loop_proxy(), 87 : pipeline_(new Pipeline(message_loop_.message_loop_proxy(),
88 new MediaLog())), 88 new MediaLog())),
89 filter_collection_(new FilterCollection()), 89 filter_collection_(new FilterCollection()),
90 demuxer_(new StrictMock<MockDemuxer>()) { 90 demuxer_(new StrictMock<MockDemuxer>()) {
91 filter_collection_->SetDemuxer(demuxer_.get()); 91 filter_collection_->SetDemuxer(demuxer_.get());
92 92
93 renderer_ = new StrictMock<MockRenderer>(); 93 video_renderer_ = new StrictMock<MockVideoRenderer>();
94 scoped_ptr<Renderer> renderer(renderer_); 94 scoped_ptr<VideoRenderer> video_renderer(video_renderer_);
95 filter_collection_->SetRenderer(renderer.Pass()); 95 filter_collection_->SetVideoRenderer(video_renderer.Pass());
96
97 audio_renderer_ = new StrictMock<MockAudioRenderer>();
98 scoped_ptr<AudioRenderer> audio_renderer(audio_renderer_);
99 filter_collection_->SetAudioRenderer(audio_renderer.Pass());
96 100
97 text_renderer_ = new TextRenderer( 101 text_renderer_ = new TextRenderer(
98 message_loop_.message_loop_proxy(), 102 message_loop_.message_loop_proxy(),
99 base::Bind(&PipelineTest::OnAddTextTrack, 103 base::Bind(&PipelineTest::OnAddTextTrack,
100 base::Unretained(this))); 104 base::Unretained(this)));
101 scoped_ptr<TextRenderer> text_renderer(text_renderer_); 105 scoped_ptr<TextRenderer> text_renderer(text_renderer_);
102 filter_collection_->SetTextRenderer(text_renderer.Pass()); 106 filter_collection_->SetTextRenderer(text_renderer.Pass());
103 107
104 // SetDemuxerExpectations() adds overriding expectations for expected 108 // SetDemuxerExpectations() adds overriding expectations for expected
105 // non-NULL streams. 109 // non-NULL streams.
106 DemuxerStream* null_pointer = NULL; 110 DemuxerStream* null_pointer = NULL;
107 EXPECT_CALL(*demuxer_, GetStream(_)) 111 EXPECT_CALL(*demuxer_, GetStream(_))
108 .WillRepeatedly(Return(null_pointer)); 112 .WillRepeatedly(Return(null_pointer));
109 113
110 EXPECT_CALL(*demuxer_, GetTimelineOffset()) 114 EXPECT_CALL(*demuxer_, GetTimelineOffset())
111 .WillRepeatedly(Return(base::Time())); 115 .WillRepeatedly(Return(base::Time()));
112 116
113 EXPECT_CALL(*demuxer_, GetLiveness()) 117 EXPECT_CALL(*demuxer_, GetLiveness())
114 .WillRepeatedly(Return(Demuxer::LIVENESS_UNKNOWN)); 118 .WillRepeatedly(Return(Demuxer::LIVENESS_UNKNOWN));
115
116 EXPECT_CALL(*renderer_, GetMediaTime())
117 .WillRepeatedly(Return(base::TimeDelta()));
118 } 119 }
119 120
120 virtual ~PipelineTest() { 121 virtual ~PipelineTest() {
121 if (!pipeline_ || !pipeline_->IsRunning()) 122 if (!pipeline_ || !pipeline_->IsRunning())
122 return; 123 return;
123 124
124 ExpectDemuxerStop(); 125 ExpectDemuxerStop();
125 126
126 // The mock demuxer doesn't stop the fake text track stream, 127 // The mock demuxer doesn't stop the fake text track stream,
127 // so just stop it manually. 128 // so just stop it manually.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 } 168 }
168 169
169 scoped_ptr<StrictMock<MockDemuxerStream> > CreateStream( 170 scoped_ptr<StrictMock<MockDemuxerStream> > CreateStream(
170 DemuxerStream::Type type) { 171 DemuxerStream::Type type) {
171 scoped_ptr<StrictMock<MockDemuxerStream> > stream( 172 scoped_ptr<StrictMock<MockDemuxerStream> > stream(
172 new StrictMock<MockDemuxerStream>(type)); 173 new StrictMock<MockDemuxerStream>(type));
173 return stream.Pass(); 174 return stream.Pass();
174 } 175 }
175 176
176 // Sets up expectations to allow the video renderer to initialize. 177 // Sets up expectations to allow the video renderer to initialize.
177 void SetRendererExpectations() { 178 void SetVideoRendererExpectations(DemuxerStream* stream) {
178 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _)) 179 EXPECT_CALL(*video_renderer_, Initialize(stream, _, _, _, _, _, _, _, _, _))
179 .WillOnce(DoAll(SaveArg<2>(&ended_cb_), 180 .WillOnce(DoAll(SaveArg<5>(&video_buffering_state_cb_),
180 SaveArg<4>(&buffering_state_cb_), 181 SaveArg<6>(&video_ended_cb_),
181 RunCallback<0>(PIPELINE_OK))); 182 RunCallback<2>(PIPELINE_OK)));
182 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(audio_stream())); 183 }
183 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(video_stream())); 184
185 // Sets up expectations to allow the audio renderer to initialize.
186 void SetAudioRendererExpectations(DemuxerStream* stream) {
187 EXPECT_CALL(*audio_renderer_, Initialize(stream, _, _, _, _, _, _))
188 .WillOnce(DoAll(SaveArg<3>(&audio_time_cb_),
189 SaveArg<4>(&audio_buffering_state_cb_),
190 SaveArg<5>(&audio_ended_cb_),
191 RunCallback<1>(PIPELINE_OK)));
184 } 192 }
185 193
186 void AddTextStream() { 194 void AddTextStream() {
187 EXPECT_CALL(*this, OnAddTextTrack(_,_)) 195 EXPECT_CALL(*this, OnAddTextTrack(_,_))
188 .WillOnce(Invoke(this, &PipelineTest::DoOnAddTextTrack)); 196 .WillOnce(Invoke(this, &PipelineTest::DoOnAddTextTrack));
189 static_cast<DemuxerHost*>(pipeline_.get())->AddTextStream(text_stream(), 197 static_cast<DemuxerHost*>(pipeline_.get())->AddTextStream(text_stream(),
190 TextTrackConfig(kTextSubtitles, "", "", "")); 198 TextTrackConfig(kTextSubtitles, "", "", ""));
191 message_loop_.RunUntilIdle();
192 } 199 }
193 200
194 // Sets up expectations on the callback and initializes the pipeline. Called 201 // Sets up expectations on the callback and initializes the pipeline. Called
195 // after tests have set expectations any filters they wish to use. 202 // after tests have set expectations any filters they wish to use.
196 void StartPipeline(PipelineStatus start_status) { 203 void StartPipeline(PipelineStatus start_status) {
197 EXPECT_CALL(callbacks_, OnStart(start_status)); 204 EXPECT_CALL(callbacks_, OnStart(start_status));
198 205
199 if (start_status == PIPELINE_OK) { 206 if (start_status == PIPELINE_OK) {
200 EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_)); 207 EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_));
201 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0f)); 208
202 EXPECT_CALL(*renderer_, SetVolume(1.0f)); 209 if (audio_stream_) {
203 EXPECT_CALL(*renderer_, StartPlayingFrom(base::TimeDelta())) 210 EXPECT_CALL(*audio_renderer_, GetTimeSource())
204 .WillOnce(SetBufferingState(&buffering_state_cb_, 211 .WillOnce(Return(&time_source_));
205 BUFFERING_HAVE_ENOUGH)); 212 EXPECT_CALL(time_source_, SetPlaybackRate(0.0f));
213 EXPECT_CALL(time_source_, SetMediaTime(base::TimeDelta()));
214 EXPECT_CALL(time_source_, StartTicking());
215 EXPECT_CALL(*audio_renderer_, SetVolume(1.0f));
216 EXPECT_CALL(*audio_renderer_, StartPlaying())
217 .WillOnce(SetBufferingState(&audio_buffering_state_cb_,
218 BUFFERING_HAVE_ENOUGH));
219 }
220
221 if (video_stream_) {
222 EXPECT_CALL(*video_renderer_, StartPlaying())
223 .WillOnce(SetBufferingState(&video_buffering_state_cb_,
224 BUFFERING_HAVE_ENOUGH));
225 }
226
206 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); 227 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
207 } 228 }
208 229
209 pipeline_->Start( 230 pipeline_->Start(
210 filter_collection_.Pass(), 231 filter_collection_.Pass(),
211 base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)), 232 base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
212 base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)), 233 base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
213 base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)), 234 base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)),
214 base::Bind(&CallbackHelper::OnMetadata, base::Unretained(&callbacks_)), 235 base::Bind(&CallbackHelper::OnMetadata, base::Unretained(&callbacks_)),
215 base::Bind(&CallbackHelper::OnBufferingStateChange, 236 base::Bind(&CallbackHelper::OnBufferingStateChange,
(...skipping 24 matching lines...) Expand all
240 261
241 MockDemuxerStream* video_stream() { 262 MockDemuxerStream* video_stream() {
242 return video_stream_.get(); 263 return video_stream_.get();
243 } 264 }
244 265
245 FakeTextTrackStream* text_stream() { 266 FakeTextTrackStream* text_stream() {
246 return text_stream_.get(); 267 return text_stream_.get();
247 } 268 }
248 269
249 void ExpectSeek(const base::TimeDelta& seek_time, bool underflowed) { 270 void ExpectSeek(const base::TimeDelta& seek_time, bool underflowed) {
271 // Every filter should receive a call to Seek().
250 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) 272 EXPECT_CALL(*demuxer_, Seek(seek_time, _))
251 .WillOnce(RunCallback<1>(PIPELINE_OK)); 273 .WillOnce(RunCallback<1>(PIPELINE_OK));
252 274
253 EXPECT_CALL(*renderer_, Flush(_)) 275 if (audio_stream_) {
254 .WillOnce(DoAll(SetBufferingState(&buffering_state_cb_, 276 if (!underflowed)
255 BUFFERING_HAVE_NOTHING), 277 EXPECT_CALL(time_source_, StopTicking());
256 RunClosure<0>())); 278 EXPECT_CALL(*audio_renderer_, Flush(_))
257 EXPECT_CALL(*renderer_, SetPlaybackRate(_)); 279 .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
258 EXPECT_CALL(*renderer_, SetVolume(_)); 280 BUFFERING_HAVE_NOTHING),
259 EXPECT_CALL(*renderer_, StartPlayingFrom(seek_time)) 281 RunClosure<0>()));
260 .WillOnce(SetBufferingState(&buffering_state_cb_, 282 EXPECT_CALL(time_source_, SetMediaTime(seek_time));
261 BUFFERING_HAVE_ENOUGH)); 283 EXPECT_CALL(time_source_, SetPlaybackRate(_));
262 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); 284 EXPECT_CALL(time_source_, StartTicking());
285 EXPECT_CALL(*audio_renderer_, StartPlaying())
286 .WillOnce(SetBufferingState(&audio_buffering_state_cb_,
287 BUFFERING_HAVE_ENOUGH));
288 EXPECT_CALL(*audio_renderer_, SetVolume(_));
289 }
290
291 if (video_stream_) {
292 EXPECT_CALL(*video_renderer_, Flush(_))
293 .WillOnce(DoAll(SetBufferingState(&video_buffering_state_cb_,
294 BUFFERING_HAVE_NOTHING),
295 RunClosure<0>()));
296 EXPECT_CALL(*video_renderer_, StartPlaying())
297 .WillOnce(SetBufferingState(&video_buffering_state_cb_,
298 BUFFERING_HAVE_ENOUGH));
299 }
263 300
264 // We expect a successful seek callback followed by a buffering update. 301 // We expect a successful seek callback followed by a buffering update.
265 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); 302 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK));
266 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); 303 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
267 } 304 }
268 305
269 void DoSeek(const base::TimeDelta& seek_time) { 306 void DoSeek(const base::TimeDelta& seek_time) {
270 pipeline_->Seek(seek_time, 307 pipeline_->Seek(seek_time,
271 base::Bind(&CallbackHelper::OnSeek, 308 base::Bind(&CallbackHelper::OnSeek,
272 base::Unretained(&callbacks_))); 309 base::Unretained(&callbacks_)));
310
311 // We expect the time to be updated only after the seek has completed.
312 EXPECT_NE(seek_time, pipeline_->GetMediaTime());
273 message_loop_.RunUntilIdle(); 313 message_loop_.RunUntilIdle();
314 EXPECT_EQ(seek_time, pipeline_->GetMediaTime());
274 } 315 }
275 316
276 void DestroyPipeline() { 317 void DestroyPipeline() {
277 // In real code Pipeline could be destroyed on a different thread. All weak 318 // In real code Pipeline could be destroyed on a different thread. All weak
278 // pointers must have been invalidated before the stop callback returns. 319 // pointers must have been invalidated before the stop callback returns.
279 DCHECK(!pipeline_->HasWeakPtrsForTesting()); 320 DCHECK(!pipeline_->HasWeakPtrsForTesting());
280 pipeline_.reset(); 321 pipeline_.reset();
281 } 322 }
282 323
283 void ExpectDemuxerStop() { 324 void ExpectDemuxerStop() {
(...skipping 18 matching lines...) Expand all
302 } 343 }
303 344
304 // Fixture members. 345 // Fixture members.
305 StrictMock<CallbackHelper> callbacks_; 346 StrictMock<CallbackHelper> callbacks_;
306 base::SimpleTestTickClock test_tick_clock_; 347 base::SimpleTestTickClock test_tick_clock_;
307 base::MessageLoop message_loop_; 348 base::MessageLoop message_loop_;
308 scoped_ptr<Pipeline> pipeline_; 349 scoped_ptr<Pipeline> pipeline_;
309 350
310 scoped_ptr<FilterCollection> filter_collection_; 351 scoped_ptr<FilterCollection> filter_collection_;
311 scoped_ptr<StrictMock<MockDemuxer> > demuxer_; 352 scoped_ptr<StrictMock<MockDemuxer> > demuxer_;
312 StrictMock<MockRenderer>* renderer_; 353 StrictMock<MockVideoRenderer>* video_renderer_;
354 StrictMock<MockAudioRenderer>* audio_renderer_;
355 StrictMock<MockTimeSource> time_source_;
313 StrictMock<CallbackHelper> text_renderer_callbacks_; 356 StrictMock<CallbackHelper> text_renderer_callbacks_;
314 TextRenderer* text_renderer_; 357 TextRenderer* text_renderer_;
315 scoped_ptr<StrictMock<MockDemuxerStream> > audio_stream_; 358 scoped_ptr<StrictMock<MockDemuxerStream> > audio_stream_;
316 scoped_ptr<StrictMock<MockDemuxerStream> > video_stream_; 359 scoped_ptr<StrictMock<MockDemuxerStream> > video_stream_;
317 scoped_ptr<FakeTextTrackStream> text_stream_; 360 scoped_ptr<FakeTextTrackStream> text_stream_;
318 BufferingStateCB buffering_state_cb_; 361 AudioRenderer::TimeCB audio_time_cb_;
319 base::Closure ended_cb_; 362 BufferingStateCB audio_buffering_state_cb_;
363 BufferingStateCB video_buffering_state_cb_;
364 base::Closure audio_ended_cb_;
365 base::Closure video_ended_cb_;
320 VideoDecoderConfig video_decoder_config_; 366 VideoDecoderConfig video_decoder_config_;
321 PipelineMetadata metadata_; 367 PipelineMetadata metadata_;
322 368
323 private: 369 private:
324 DISALLOW_COPY_AND_ASSIGN(PipelineTest); 370 DISALLOW_COPY_AND_ASSIGN(PipelineTest);
325 }; 371 };
326 372
327 // Test that playback controls methods no-op when the pipeline hasn't been 373 // Test that playback controls methods no-op when the pipeline hasn't been
328 // started. 374 // started.
329 TEST_F(PipelineTest, NotStarted) { 375 TEST_F(PipelineTest, NotStarted) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); 454 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_)));
409 message_loop_.RunUntilIdle(); 455 message_loop_.RunUntilIdle();
410 } 456 }
411 457
412 TEST_F(PipelineTest, DemuxerErrorDuringStop) { 458 TEST_F(PipelineTest, DemuxerErrorDuringStop) {
413 CreateAudioStream(); 459 CreateAudioStream();
414 MockDemuxerStreamVector streams; 460 MockDemuxerStreamVector streams;
415 streams.push_back(audio_stream()); 461 streams.push_back(audio_stream());
416 462
417 SetDemuxerExpectations(&streams); 463 SetDemuxerExpectations(&streams);
418 SetRendererExpectations(); 464 SetAudioRendererExpectations(audio_stream());
419 465
420 StartPipeline(PIPELINE_OK); 466 StartPipeline(PIPELINE_OK);
421 467
422 EXPECT_CALL(*demuxer_, Stop(_)) 468 EXPECT_CALL(*demuxer_, Stop(_))
423 .WillOnce(DoAll(InvokeWithoutArgs(this, &PipelineTest::OnDemuxerError), 469 .WillOnce(DoAll(InvokeWithoutArgs(this, &PipelineTest::OnDemuxerError),
424 RunClosure<0>())); 470 RunClosure<0>()));
425 ExpectPipelineStopAndDestroyPipeline(); 471 ExpectPipelineStopAndDestroyPipeline();
426 472
427 pipeline_->Stop( 473 pipeline_->Stop(
428 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); 474 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_)));
(...skipping 17 matching lines...) Expand all
446 492
447 StartPipeline(PIPELINE_ERROR_COULD_NOT_RENDER); 493 StartPipeline(PIPELINE_ERROR_COULD_NOT_RENDER);
448 } 494 }
449 495
450 TEST_F(PipelineTest, AudioStream) { 496 TEST_F(PipelineTest, AudioStream) {
451 CreateAudioStream(); 497 CreateAudioStream();
452 MockDemuxerStreamVector streams; 498 MockDemuxerStreamVector streams;
453 streams.push_back(audio_stream()); 499 streams.push_back(audio_stream());
454 500
455 SetDemuxerExpectations(&streams); 501 SetDemuxerExpectations(&streams);
456 SetRendererExpectations(); 502 SetAudioRendererExpectations(audio_stream());
457 503
458 StartPipeline(PIPELINE_OK); 504 StartPipeline(PIPELINE_OK);
459 EXPECT_TRUE(metadata_.has_audio); 505 EXPECT_TRUE(metadata_.has_audio);
460 EXPECT_FALSE(metadata_.has_video); 506 EXPECT_FALSE(metadata_.has_video);
461 } 507 }
462 508
463 TEST_F(PipelineTest, VideoStream) { 509 TEST_F(PipelineTest, VideoStream) {
464 CreateVideoStream(); 510 CreateVideoStream();
465 MockDemuxerStreamVector streams; 511 MockDemuxerStreamVector streams;
466 streams.push_back(video_stream()); 512 streams.push_back(video_stream());
467 513
468 SetDemuxerExpectations(&streams); 514 SetDemuxerExpectations(&streams);
469 SetRendererExpectations(); 515 SetVideoRendererExpectations(video_stream());
470 516
471 StartPipeline(PIPELINE_OK); 517 StartPipeline(PIPELINE_OK);
472 EXPECT_FALSE(metadata_.has_audio); 518 EXPECT_FALSE(metadata_.has_audio);
473 EXPECT_TRUE(metadata_.has_video); 519 EXPECT_TRUE(metadata_.has_video);
474 } 520 }
475 521
476 TEST_F(PipelineTest, AudioVideoStream) { 522 TEST_F(PipelineTest, AudioVideoStream) {
477 CreateAudioStream(); 523 CreateAudioStream();
478 CreateVideoStream(); 524 CreateVideoStream();
479 MockDemuxerStreamVector streams; 525 MockDemuxerStreamVector streams;
480 streams.push_back(audio_stream()); 526 streams.push_back(audio_stream());
481 streams.push_back(video_stream()); 527 streams.push_back(video_stream());
482 528
483 SetDemuxerExpectations(&streams); 529 SetDemuxerExpectations(&streams);
484 SetRendererExpectations(); 530 SetAudioRendererExpectations(audio_stream());
531 SetVideoRendererExpectations(video_stream());
485 532
486 StartPipeline(PIPELINE_OK); 533 StartPipeline(PIPELINE_OK);
487 EXPECT_TRUE(metadata_.has_audio); 534 EXPECT_TRUE(metadata_.has_audio);
488 EXPECT_TRUE(metadata_.has_video); 535 EXPECT_TRUE(metadata_.has_video);
489 } 536 }
490 537
491 TEST_F(PipelineTest, VideoTextStream) { 538 TEST_F(PipelineTest, VideoTextStream) {
492 CreateVideoStream(); 539 CreateVideoStream();
493 CreateTextStream(); 540 CreateTextStream();
494 MockDemuxerStreamVector streams; 541 MockDemuxerStreamVector streams;
495 streams.push_back(video_stream()); 542 streams.push_back(video_stream());
496 543
497 SetDemuxerExpectations(&streams); 544 SetDemuxerExpectations(&streams);
498 SetRendererExpectations(); 545 SetVideoRendererExpectations(video_stream());
499 546
500 StartPipeline(PIPELINE_OK); 547 StartPipeline(PIPELINE_OK);
501 EXPECT_FALSE(metadata_.has_audio); 548 EXPECT_FALSE(metadata_.has_audio);
502 EXPECT_TRUE(metadata_.has_video); 549 EXPECT_TRUE(metadata_.has_video);
503 550
504 AddTextStream(); 551 AddTextStream();
552 message_loop_.RunUntilIdle();
505 } 553 }
506 554
507 TEST_F(PipelineTest, VideoAudioTextStream) { 555 TEST_F(PipelineTest, VideoAudioTextStream) {
508 CreateVideoStream(); 556 CreateVideoStream();
509 CreateAudioStream(); 557 CreateAudioStream();
510 CreateTextStream(); 558 CreateTextStream();
511 MockDemuxerStreamVector streams; 559 MockDemuxerStreamVector streams;
512 streams.push_back(video_stream()); 560 streams.push_back(video_stream());
513 streams.push_back(audio_stream()); 561 streams.push_back(audio_stream());
514 562
515 SetDemuxerExpectations(&streams); 563 SetDemuxerExpectations(&streams);
516 SetRendererExpectations(); 564 SetVideoRendererExpectations(video_stream());
565 SetAudioRendererExpectations(audio_stream());
517 566
518 StartPipeline(PIPELINE_OK); 567 StartPipeline(PIPELINE_OK);
519 EXPECT_TRUE(metadata_.has_audio); 568 EXPECT_TRUE(metadata_.has_audio);
520 EXPECT_TRUE(metadata_.has_video); 569 EXPECT_TRUE(metadata_.has_video);
521 570
522 AddTextStream(); 571 AddTextStream();
572 message_loop_.RunUntilIdle();
523 } 573 }
524 574
525 TEST_F(PipelineTest, Seek) { 575 TEST_F(PipelineTest, Seek) {
526 CreateAudioStream(); 576 CreateAudioStream();
527 CreateVideoStream(); 577 CreateVideoStream();
528 CreateTextStream(); 578 CreateTextStream();
529 MockDemuxerStreamVector streams; 579 MockDemuxerStreamVector streams;
530 streams.push_back(audio_stream()); 580 streams.push_back(audio_stream());
531 streams.push_back(video_stream()); 581 streams.push_back(video_stream());
532 582
533 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); 583 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000));
534 SetRendererExpectations(); 584 SetAudioRendererExpectations(audio_stream());
585 SetVideoRendererExpectations(video_stream());
535 586
536 // Initialize then seek! 587 // Initialize then seek!
537 StartPipeline(PIPELINE_OK); 588 StartPipeline(PIPELINE_OK);
538 589
539 // Every filter should receive a call to Seek(). 590 // Every filter should receive a call to Seek().
540 base::TimeDelta expected = base::TimeDelta::FromSeconds(2000); 591 base::TimeDelta expected = base::TimeDelta::FromSeconds(2000);
541 ExpectSeek(expected, false); 592 ExpectSeek(expected, false);
542 DoSeek(expected); 593 DoSeek(expected);
543 } 594 }
544 595
545 TEST_F(PipelineTest, SeekAfterError) { 596 TEST_F(PipelineTest, SeekAfterError) {
546 CreateAudioStream(); 597 CreateAudioStream();
547 MockDemuxerStreamVector streams; 598 MockDemuxerStreamVector streams;
548 streams.push_back(audio_stream()); 599 streams.push_back(audio_stream());
549 600
550 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); 601 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000));
551 SetRendererExpectations(); 602 SetAudioRendererExpectations(audio_stream());
552 603
553 // Initialize then seek! 604 // Initialize then seek!
554 StartPipeline(PIPELINE_OK); 605 StartPipeline(PIPELINE_OK);
555 606
556 EXPECT_CALL(*demuxer_, Stop(_)) 607 EXPECT_CALL(*demuxer_, Stop(_))
557 .WillOnce(RunClosure<0>()); 608 .WillOnce(RunClosure<0>());
558 EXPECT_CALL(callbacks_, OnError(_)); 609 EXPECT_CALL(callbacks_, OnError(_));
559 610
560 static_cast<DemuxerHost*>(pipeline_.get()) 611 static_cast<DemuxerHost*>(pipeline_.get())
561 ->OnDemuxerError(PIPELINE_ERROR_ABORT); 612 ->OnDemuxerError(PIPELINE_ERROR_ABORT);
562 message_loop_.RunUntilIdle(); 613 message_loop_.RunUntilIdle();
563 614
564 pipeline_->Seek( 615 pipeline_->Seek(
565 base::TimeDelta::FromMilliseconds(100), 616 base::TimeDelta::FromMilliseconds(100),
566 base::Bind(&CallbackHelper::OnSeek, base::Unretained(&callbacks_))); 617 base::Bind(&CallbackHelper::OnSeek, base::Unretained(&callbacks_)));
567 message_loop_.RunUntilIdle(); 618 message_loop_.RunUntilIdle();
568 } 619 }
569 620
570 TEST_F(PipelineTest, SetVolume) { 621 TEST_F(PipelineTest, SetVolume) {
571 CreateAudioStream(); 622 CreateAudioStream();
572 MockDemuxerStreamVector streams; 623 MockDemuxerStreamVector streams;
573 streams.push_back(audio_stream()); 624 streams.push_back(audio_stream());
574 625
575 SetDemuxerExpectations(&streams); 626 SetDemuxerExpectations(&streams);
576 SetRendererExpectations(); 627 SetAudioRendererExpectations(audio_stream());
577 628
578 // The audio renderer should receive a call to SetVolume(). 629 // The audio renderer should receive a call to SetVolume().
579 float expected = 0.5f; 630 float expected = 0.5f;
580 EXPECT_CALL(*renderer_, SetVolume(expected)); 631 EXPECT_CALL(*audio_renderer_, SetVolume(expected));
581 632
582 // Initialize then set volume! 633 // Initialize then set volume!
583 StartPipeline(PIPELINE_OK); 634 StartPipeline(PIPELINE_OK);
584 pipeline_->SetVolume(expected); 635 pipeline_->SetVolume(expected);
585 } 636 }
586 637
587 TEST_F(PipelineTest, Properties) { 638 TEST_F(PipelineTest, Properties) {
588 CreateVideoStream(); 639 CreateVideoStream();
589 MockDemuxerStreamVector streams; 640 MockDemuxerStreamVector streams;
590 streams.push_back(video_stream()); 641 streams.push_back(video_stream());
591 642
592 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); 643 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100);
593 SetDemuxerExpectations(&streams, kDuration); 644 SetDemuxerExpectations(&streams, kDuration);
594 SetRendererExpectations(); 645 SetVideoRendererExpectations(video_stream());
595 646
596 StartPipeline(PIPELINE_OK); 647 StartPipeline(PIPELINE_OK);
597 EXPECT_EQ(kDuration.ToInternalValue(), 648 EXPECT_EQ(kDuration.ToInternalValue(),
598 pipeline_->GetMediaDuration().ToInternalValue()); 649 pipeline_->GetMediaDuration().ToInternalValue());
599 EXPECT_FALSE(pipeline_->DidLoadingProgress()); 650 EXPECT_FALSE(pipeline_->DidLoadingProgress());
600 } 651 }
601 652
602 TEST_F(PipelineTest, GetBufferedTimeRanges) { 653 TEST_F(PipelineTest, GetBufferedTimeRanges) {
603 CreateVideoStream(); 654 CreateVideoStream();
604 MockDemuxerStreamVector streams; 655 MockDemuxerStreamVector streams;
605 streams.push_back(video_stream()); 656 streams.push_back(video_stream());
606 657
607 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); 658 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100);
608 SetDemuxerExpectations(&streams, kDuration); 659 SetDemuxerExpectations(&streams, kDuration);
609 SetRendererExpectations(); 660 SetVideoRendererExpectations(video_stream());
610 661
611 StartPipeline(PIPELINE_OK); 662 StartPipeline(PIPELINE_OK);
612 663
613 EXPECT_EQ(0u, pipeline_->GetBufferedTimeRanges().size()); 664 EXPECT_EQ(0u, pipeline_->GetBufferedTimeRanges().size());
614 665
615 EXPECT_FALSE(pipeline_->DidLoadingProgress()); 666 EXPECT_FALSE(pipeline_->DidLoadingProgress());
616 pipeline_->AddBufferedTimeRange(base::TimeDelta(), kDuration / 8); 667 pipeline_->AddBufferedTimeRange(base::TimeDelta(), kDuration / 8);
617 EXPECT_TRUE(pipeline_->DidLoadingProgress()); 668 EXPECT_TRUE(pipeline_->DidLoadingProgress());
618 EXPECT_FALSE(pipeline_->DidLoadingProgress()); 669 EXPECT_FALSE(pipeline_->DidLoadingProgress());
619 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); 670 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
620 EXPECT_EQ(base::TimeDelta(), pipeline_->GetBufferedTimeRanges().start(0)); 671 EXPECT_EQ(base::TimeDelta(), pipeline_->GetBufferedTimeRanges().start(0));
621 EXPECT_EQ(kDuration / 8, pipeline_->GetBufferedTimeRanges().end(0)); 672 EXPECT_EQ(kDuration / 8, pipeline_->GetBufferedTimeRanges().end(0));
622 673
623 base::TimeDelta kSeekTime = kDuration / 2; 674 base::TimeDelta kSeekTime = kDuration / 2;
624 ExpectSeek(kSeekTime, false); 675 ExpectSeek(kSeekTime, false);
625 DoSeek(kSeekTime); 676 DoSeek(kSeekTime);
626 677
627 EXPECT_FALSE(pipeline_->DidLoadingProgress()); 678 EXPECT_FALSE(pipeline_->DidLoadingProgress());
628 } 679 }
629 680
630 TEST_F(PipelineTest, EndedCallback) { 681 TEST_F(PipelineTest, EndedCallback) {
631 CreateAudioStream(); 682 CreateAudioStream();
632 CreateVideoStream(); 683 CreateVideoStream();
633 CreateTextStream(); 684 CreateTextStream();
634 MockDemuxerStreamVector streams; 685 MockDemuxerStreamVector streams;
635 streams.push_back(audio_stream()); 686 streams.push_back(audio_stream());
636 streams.push_back(video_stream()); 687 streams.push_back(video_stream());
637 688
638 SetDemuxerExpectations(&streams); 689 SetDemuxerExpectations(&streams);
639 SetRendererExpectations(); 690 SetAudioRendererExpectations(audio_stream());
691 SetVideoRendererExpectations(video_stream());
640 StartPipeline(PIPELINE_OK); 692 StartPipeline(PIPELINE_OK);
641 693
642 AddTextStream(); 694 AddTextStream();
643 695
644 // The ended callback shouldn't run until all renderers have ended. 696 // The ended callback shouldn't run until all renderers have ended.
645 ended_cb_.Run(); 697 audio_ended_cb_.Run();
646 message_loop_.RunUntilIdle(); 698 message_loop_.RunUntilIdle();
647 699
700 video_ended_cb_.Run();
701 message_loop_.RunUntilIdle();
702
703 EXPECT_CALL(time_source_, StopTicking());
648 EXPECT_CALL(callbacks_, OnEnded()); 704 EXPECT_CALL(callbacks_, OnEnded());
649 text_stream()->SendEosNotification(); 705 text_stream()->SendEosNotification();
650 message_loop_.RunUntilIdle(); 706 message_loop_.RunUntilIdle();
651 } 707 }
652 708
709 TEST_F(PipelineTest, AudioStreamShorterThanVideo) {
710 base::TimeDelta duration = base::TimeDelta::FromSeconds(10);
711
712 CreateAudioStream();
713 CreateVideoStream();
714 MockDemuxerStreamVector streams;
715 streams.push_back(audio_stream());
716 streams.push_back(video_stream());
717
718 // Replace what's used for interpolating to simulate wall clock time.
719 pipeline_->SetTimeDeltaInterpolatorForTesting(
720 new TimeDeltaInterpolator(&test_tick_clock_));
721
722 SetDemuxerExpectations(&streams, duration);
723 SetAudioRendererExpectations(audio_stream());
724 SetVideoRendererExpectations(video_stream());
725 StartPipeline(PIPELINE_OK);
726
727 EXPECT_EQ(0, pipeline_->GetMediaTime().ToInternalValue());
728
729 float playback_rate = 1.0f;
730 EXPECT_CALL(time_source_, SetPlaybackRate(playback_rate));
731 pipeline_->SetPlaybackRate(playback_rate);
732 message_loop_.RunUntilIdle();
733
734 InSequence s;
735
736 // Verify that the clock doesn't advance since it hasn't been started by
737 // a time update from the audio stream.
738 int64 start_time = pipeline_->GetMediaTime().ToInternalValue();
739 test_tick_clock_.Advance(base::TimeDelta::FromMilliseconds(100));
740 EXPECT_EQ(pipeline_->GetMediaTime().ToInternalValue(), start_time);
741
742 // Signal end of audio stream.
743 audio_ended_cb_.Run();
744 message_loop_.RunUntilIdle();
745
746 // Verify that the clock advances.
747 start_time = pipeline_->GetMediaTime().ToInternalValue();
748 test_tick_clock_.Advance(base::TimeDelta::FromMilliseconds(100));
749 EXPECT_GT(pipeline_->GetMediaTime().ToInternalValue(), start_time);
750
751 // Signal end of video stream and make sure OnEnded() callback occurs.
752 EXPECT_CALL(time_source_, StopTicking());
753 EXPECT_CALL(callbacks_, OnEnded());
754 video_ended_cb_.Run();
755 }
756
653 TEST_F(PipelineTest, ErrorDuringSeek) { 757 TEST_F(PipelineTest, ErrorDuringSeek) {
654 CreateAudioStream(); 758 CreateAudioStream();
655 MockDemuxerStreamVector streams; 759 MockDemuxerStreamVector streams;
656 streams.push_back(audio_stream()); 760 streams.push_back(audio_stream());
657 761
658 SetDemuxerExpectations(&streams); 762 SetDemuxerExpectations(&streams);
659 SetRendererExpectations(); 763 SetAudioRendererExpectations(audio_stream());
660 StartPipeline(PIPELINE_OK); 764 StartPipeline(PIPELINE_OK);
661 765
662 float playback_rate = 1.0f; 766 float playback_rate = 1.0f;
663 EXPECT_CALL(*renderer_, SetPlaybackRate(playback_rate)); 767 EXPECT_CALL(time_source_, SetPlaybackRate(playback_rate));
664 pipeline_->SetPlaybackRate(playback_rate); 768 pipeline_->SetPlaybackRate(playback_rate);
665 message_loop_.RunUntilIdle(); 769 message_loop_.RunUntilIdle();
666 770
667 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); 771 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
668 772
669 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); 773 // Preroll() isn't called as the demuxer errors out first.
670 EXPECT_CALL(*renderer_, Flush(_)) 774 EXPECT_CALL(time_source_, StopTicking());
671 .WillOnce(DoAll(SetBufferingState(&buffering_state_cb_, 775 EXPECT_CALL(*audio_renderer_, Flush(_))
776 .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
672 BUFFERING_HAVE_NOTHING), 777 BUFFERING_HAVE_NOTHING),
673 RunClosure<0>())); 778 RunClosure<0>()));
674 779
675 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) 780 EXPECT_CALL(*demuxer_, Seek(seek_time, _))
676 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); 781 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ));
677 EXPECT_CALL(*demuxer_, Stop(_)) 782 EXPECT_CALL(*demuxer_, Stop(_))
678 .WillOnce(RunClosure<0>()); 783 .WillOnce(RunClosure<0>());
679 784
680 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, 785 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek,
681 base::Unretained(&callbacks_))); 786 base::Unretained(&callbacks_)));
(...skipping 19 matching lines...) Expand all
701 // No additional tasks should be queued as a result of these calls. 806 // No additional tasks should be queued as a result of these calls.
702 EXPECT_TRUE(message_loop->IsIdleForTesting()); 807 EXPECT_TRUE(message_loop->IsIdleForTesting());
703 } 808 }
704 809
705 TEST_F(PipelineTest, NoMessageDuringTearDownFromError) { 810 TEST_F(PipelineTest, NoMessageDuringTearDownFromError) {
706 CreateAudioStream(); 811 CreateAudioStream();
707 MockDemuxerStreamVector streams; 812 MockDemuxerStreamVector streams;
708 streams.push_back(audio_stream()); 813 streams.push_back(audio_stream());
709 814
710 SetDemuxerExpectations(&streams); 815 SetDemuxerExpectations(&streams);
711 SetRendererExpectations(); 816 SetAudioRendererExpectations(audio_stream());
712 StartPipeline(PIPELINE_OK); 817 StartPipeline(PIPELINE_OK);
713 818
714 // Trigger additional requests on the pipeline during tear down from error. 819 // Trigger additional requests on the pipeline during tear down from error.
715 base::Callback<void(PipelineStatus)> cb = base::Bind( 820 base::Callback<void(PipelineStatus)> cb = base::Bind(
716 &TestNoCallsAfterError, pipeline_.get(), &message_loop_); 821 &TestNoCallsAfterError, pipeline_.get(), &message_loop_);
717 ON_CALL(callbacks_, OnError(_)) 822 ON_CALL(callbacks_, OnError(_))
718 .WillByDefault(Invoke(&cb, &base::Callback<void(PipelineStatus)>::Run)); 823 .WillByDefault(Invoke(&cb, &base::Callback<void(PipelineStatus)>::Run));
719 824
720 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); 825 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
721 826
722 // Seek() isn't called as the demuxer errors out first. 827 // Seek() isn't called as the demuxer errors out first.
723 EXPECT_CALL(*renderer_, Flush(_)) 828 EXPECT_CALL(time_source_, StopTicking());
724 .WillOnce(DoAll(SetBufferingState(&buffering_state_cb_, 829 EXPECT_CALL(*audio_renderer_, Flush(_))
830 .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
725 BUFFERING_HAVE_NOTHING), 831 BUFFERING_HAVE_NOTHING),
726 RunClosure<0>())); 832 RunClosure<0>()));
727 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
728 833
729 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) 834 EXPECT_CALL(*demuxer_, Seek(seek_time, _))
730 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); 835 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ));
731 EXPECT_CALL(*demuxer_, Stop(_)) 836 EXPECT_CALL(*demuxer_, Stop(_))
732 .WillOnce(RunClosure<0>()); 837 .WillOnce(RunClosure<0>());
733 838
734 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, 839 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek,
735 base::Unretained(&callbacks_))); 840 base::Unretained(&callbacks_)));
736 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); 841 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ));
737 message_loop_.RunUntilIdle(); 842 message_loop_.RunUntilIdle();
738 } 843 }
739 844
845 static void RunTimeCB(const AudioRenderer::TimeCB& time_cb,
846 int time_in_ms,
847 int max_time_in_ms) {
848 time_cb.Run(base::TimeDelta::FromMilliseconds(time_in_ms),
849 base::TimeDelta::FromMilliseconds(max_time_in_ms));
850 }
851
852 TEST_F(PipelineTest, AudioTimeUpdateDuringSeek) {
853 CreateAudioStream();
854 MockDemuxerStreamVector streams;
855 streams.push_back(audio_stream());
856
857 SetDemuxerExpectations(&streams);
858 SetAudioRendererExpectations(audio_stream());
859 StartPipeline(PIPELINE_OK);
860
861 float playback_rate = 1.0f;
862 EXPECT_CALL(time_source_, SetPlaybackRate(playback_rate));
863 pipeline_->SetPlaybackRate(playback_rate);
864 message_loop_.RunUntilIdle();
865
866 // Provide an initial time update so that the pipeline transitions out of the
867 // "waiting for time update" state.
868 audio_time_cb_.Run(base::TimeDelta::FromMilliseconds(100),
869 base::TimeDelta::FromMilliseconds(500));
870
871 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
872
873 // Arrange to trigger a time update while the demuxer is in the middle of
874 // seeking. This update should be ignored by the pipeline and the clock should
875 // not get updated.
876 base::Closure closure = base::Bind(&RunTimeCB, audio_time_cb_, 300, 700);
877 EXPECT_CALL(*demuxer_, Seek(seek_time, _))
878 .WillOnce(DoAll(InvokeWithoutArgs(&closure, &base::Closure::Run),
879 RunCallback<1>(PIPELINE_OK)));
880
881 EXPECT_CALL(time_source_, StopTicking());
882 EXPECT_CALL(*audio_renderer_, Flush(_))
883 .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
884 BUFFERING_HAVE_NOTHING),
885 RunClosure<0>()));
886 EXPECT_CALL(time_source_, SetMediaTime(seek_time));
887 EXPECT_CALL(time_source_, SetPlaybackRate(_));
888 EXPECT_CALL(time_source_, StartTicking());
889 EXPECT_CALL(*audio_renderer_, StartPlaying())
890 .WillOnce(SetBufferingState(&audio_buffering_state_cb_,
891 BUFFERING_HAVE_ENOUGH));
892 EXPECT_CALL(*audio_renderer_, SetVolume(_));
893
894 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK));
895 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
896 DoSeek(seek_time);
897
898 EXPECT_EQ(pipeline_->GetMediaTime(), seek_time);
899
900 // Now that the seek is complete, verify that time updates advance the current
901 // time.
902 base::TimeDelta new_time = seek_time + base::TimeDelta::FromMilliseconds(100);
903 audio_time_cb_.Run(new_time, new_time);
904
905 EXPECT_EQ(pipeline_->GetMediaTime(), new_time);
906 }
907
740 TEST_F(PipelineTest, DestroyAfterStop) { 908 TEST_F(PipelineTest, DestroyAfterStop) {
741 CreateAudioStream(); 909 CreateAudioStream();
742 MockDemuxerStreamVector streams; 910 MockDemuxerStreamVector streams;
743 streams.push_back(audio_stream()); 911 streams.push_back(audio_stream());
744 SetDemuxerExpectations(&streams); 912 SetDemuxerExpectations(&streams);
745 SetRendererExpectations(); 913 SetAudioRendererExpectations(audio_stream());
746 StartPipeline(PIPELINE_OK); 914 StartPipeline(PIPELINE_OK);
747 915
748 ExpectDemuxerStop(); 916 ExpectDemuxerStop();
749 917
750 ExpectPipelineStopAndDestroyPipeline(); 918 ExpectPipelineStopAndDestroyPipeline();
751 pipeline_->Stop( 919 pipeline_->Stop(
752 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); 920 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_)));
753 message_loop_.RunUntilIdle(); 921 message_loop_.RunUntilIdle();
754 } 922 }
755 923
756 TEST_F(PipelineTest, Underflow) { 924 TEST_F(PipelineTest, Underflow) {
757 CreateAudioStream(); 925 CreateAudioStream();
758 CreateVideoStream(); 926 CreateVideoStream();
759 MockDemuxerStreamVector streams; 927 MockDemuxerStreamVector streams;
760 streams.push_back(audio_stream()); 928 streams.push_back(audio_stream());
761 streams.push_back(video_stream()); 929 streams.push_back(video_stream());
762 930
763 SetDemuxerExpectations(&streams); 931 SetDemuxerExpectations(&streams);
764 SetRendererExpectations(); 932 SetAudioRendererExpectations(audio_stream());
933 SetVideoRendererExpectations(video_stream());
765 StartPipeline(PIPELINE_OK); 934 StartPipeline(PIPELINE_OK);
766 935
767 // Simulate underflow. 936 // Simulate underflow.
768 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); 937 EXPECT_CALL(time_source_, StopTicking());
769 buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); 938 audio_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING);
770 939
771 // Seek while underflowed. 940 // Seek while underflowed. We shouldn't call StopTicking() again.
772 base::TimeDelta expected = base::TimeDelta::FromSeconds(5); 941 base::TimeDelta expected = base::TimeDelta::FromSeconds(5);
773 ExpectSeek(expected, true); 942 ExpectSeek(expected, true);
774 DoSeek(expected); 943 DoSeek(expected);
775 } 944 }
776 945
946 static void PostTimeCB(base::MessageLoop* message_loop,
947 const AudioRenderer::TimeCB& time_cb) {
948 base::TimeDelta new_time = base::TimeDelta::FromMilliseconds(100);
949 message_loop->PostTask(FROM_HERE, base::Bind(time_cb, new_time, new_time));
950 }
951
952 TEST_F(PipelineTest, TimeUpdateAfterStop) {
953 CreateAudioStream();
954 CreateVideoStream();
955 MockDemuxerStreamVector streams;
956 streams.push_back(audio_stream());
957 streams.push_back(video_stream());
958
959 SetDemuxerExpectations(&streams);
960 SetAudioRendererExpectations(audio_stream());
961 SetVideoRendererExpectations(video_stream());
962 StartPipeline(PIPELINE_OK);
963
964 // Double post here! This is a hack to simulate the case where TimeCB is
965 // posted during ~AudioRenderer(), which is triggered in Pipeline::DoStop.
966 // Since we can't EXPECT_CALL the dtor and Pipeline::DoStop() is posted
967 // as well, we need to post twice here.
968 message_loop_.PostTask(
969 FROM_HERE, base::Bind(&PostTimeCB, &message_loop_, audio_time_cb_));
970
971 EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
972
973 ExpectPipelineStopAndDestroyPipeline();
974 pipeline_->Stop(
975 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_)));
976 message_loop_.RunUntilIdle();
977 }
978
777 class PipelineTeardownTest : public PipelineTest { 979 class PipelineTeardownTest : public PipelineTest {
778 public: 980 public:
779 enum TeardownState { 981 enum TeardownState {
780 kInitDemuxer, 982 kInitDemuxer,
781 kInitRenderer, 983 kInitAudioRenderer,
984 kInitVideoRenderer,
782 kFlushing, 985 kFlushing,
783 kSeeking, 986 kSeeking,
784 kPlaying, 987 kPlaying,
785 }; 988 };
786 989
787 enum StopOrError { 990 enum StopOrError {
788 kStop, 991 kStop,
789 kError, 992 kError,
790 kErrorAndStop, 993 kErrorAndStop,
791 }; 994 };
792 995
793 PipelineTeardownTest() {} 996 PipelineTeardownTest() {}
794 virtual ~PipelineTeardownTest() {} 997 virtual ~PipelineTeardownTest() {}
795 998
796 void RunTest(TeardownState state, StopOrError stop_or_error) { 999 void RunTest(TeardownState state, StopOrError stop_or_error) {
797 switch (state) { 1000 switch (state) {
798 case kInitDemuxer: 1001 case kInitDemuxer:
799 case kInitRenderer: 1002 case kInitAudioRenderer:
1003 case kInitVideoRenderer:
800 DoInitialize(state, stop_or_error); 1004 DoInitialize(state, stop_or_error);
801 break; 1005 break;
802 1006
803 case kFlushing: 1007 case kFlushing:
804 case kSeeking: 1008 case kSeeking:
805 DoInitialize(state, stop_or_error); 1009 DoInitialize(state, stop_or_error);
806 DoSeek(state, stop_or_error); 1010 DoSeek(state, stop_or_error);
807 break; 1011 break;
808 1012
809 case kPlaying: 1013 case kPlaying:
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 return status; 1061 return status;
858 } 1062 }
859 1063
860 CreateAudioStream(); 1064 CreateAudioStream();
861 CreateVideoStream(); 1065 CreateVideoStream();
862 MockDemuxerStreamVector streams; 1066 MockDemuxerStreamVector streams;
863 streams.push_back(audio_stream()); 1067 streams.push_back(audio_stream());
864 streams.push_back(video_stream()); 1068 streams.push_back(video_stream());
865 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); 1069 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000));
866 1070
867 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(true)); 1071 if (state == kInitAudioRenderer) {
868 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(true));
869
870 if (state == kInitRenderer) {
871 if (stop_or_error == kStop) { 1072 if (stop_or_error == kStop) {
872 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _)) 1073 EXPECT_CALL(*audio_renderer_, Initialize(_, _, _, _, _, _, _))
873 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), 1074 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
874 RunCallback<0>(PIPELINE_OK))); 1075 RunCallback<1>(PIPELINE_OK)));
875 ExpectPipelineStopAndDestroyPipeline(); 1076 ExpectPipelineStopAndDestroyPipeline();
876 } else { 1077 } else {
877 status = PIPELINE_ERROR_INITIALIZATION_FAILED; 1078 status = PIPELINE_ERROR_INITIALIZATION_FAILED;
878 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _)) 1079 EXPECT_CALL(*audio_renderer_, Initialize(_, _, _, _, _, _, _))
879 .WillOnce(RunCallback<0>(status)); 1080 .WillOnce(RunCallback<1>(status));
880 } 1081 }
881 1082
882 EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>()); 1083 EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
883 return status; 1084 return status;
884 } 1085 }
885 1086
886 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _)) 1087 EXPECT_CALL(*audio_renderer_, Initialize(_, _, _, _, _, _, _))
887 .WillOnce(DoAll(SaveArg<4>(&buffering_state_cb_), 1088 .WillOnce(DoAll(SaveArg<4>(&audio_buffering_state_cb_),
888 RunCallback<0>(PIPELINE_OK))); 1089 RunCallback<1>(PIPELINE_OK)));
1090
1091 if (state == kInitVideoRenderer) {
1092 if (stop_or_error == kStop) {
1093 EXPECT_CALL(*video_renderer_, Initialize(_, _, _, _, _, _, _, _, _, _))
1094 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
1095 RunCallback<2>(PIPELINE_OK)));
1096 ExpectPipelineStopAndDestroyPipeline();
1097 } else {
1098 status = PIPELINE_ERROR_INITIALIZATION_FAILED;
1099 EXPECT_CALL(*video_renderer_, Initialize(_, _, _, _, _, _, _, _, _, _))
1100 .WillOnce(RunCallback<2>(status));
1101 }
1102
1103 EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
1104 return status;
1105 }
1106
1107 EXPECT_CALL(*video_renderer_, Initialize(_, _, _, _, _, _, _, _, _, _))
1108 .WillOnce(DoAll(SaveArg<5>(&video_buffering_state_cb_),
1109 RunCallback<2>(PIPELINE_OK)));
889 1110
890 EXPECT_CALL(callbacks_, OnMetadata(_)); 1111 EXPECT_CALL(callbacks_, OnMetadata(_));
891 1112
892 // If we get here it's a successful initialization. 1113 // If we get here it's a successful initialization.
893 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0f)); 1114 EXPECT_CALL(*audio_renderer_, GetTimeSource())
894 EXPECT_CALL(*renderer_, SetVolume(1.0f)); 1115 .WillOnce(Return(&time_source_));
895 EXPECT_CALL(*renderer_, StartPlayingFrom(base::TimeDelta())) 1116 EXPECT_CALL(time_source_, SetMediaTime(base::TimeDelta()));
896 .WillOnce(SetBufferingState(&buffering_state_cb_, 1117 EXPECT_CALL(time_source_, SetPlaybackRate(0.0f));
1118 EXPECT_CALL(time_source_, StartTicking());
1119 EXPECT_CALL(*audio_renderer_, SetVolume(1.0f));
1120 EXPECT_CALL(*audio_renderer_, StartPlaying())
1121 .WillOnce(SetBufferingState(&audio_buffering_state_cb_,
1122 BUFFERING_HAVE_ENOUGH));
1123 EXPECT_CALL(*video_renderer_, StartPlaying())
1124 .WillOnce(SetBufferingState(&video_buffering_state_cb_,
897 BUFFERING_HAVE_ENOUGH)); 1125 BUFFERING_HAVE_ENOUGH));
898 1126
899 if (status == PIPELINE_OK) 1127 if (status == PIPELINE_OK)
900 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); 1128 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
901 1129
902 return status; 1130 return status;
903 } 1131 }
904 1132
905 void DoSeek(TeardownState state, StopOrError stop_or_error) { 1133 void DoSeek(TeardownState state, StopOrError stop_or_error) {
906 InSequence s; 1134 InSequence s;
(...skipping 10 matching lines...) Expand all
917 &CallbackHelper::OnSeek, base::Unretained(&callbacks_))); 1145 &CallbackHelper::OnSeek, base::Unretained(&callbacks_)));
918 message_loop_.RunUntilIdle(); 1146 message_loop_.RunUntilIdle();
919 } 1147 }
920 1148
921 PipelineStatus SetSeekExpectations(TeardownState state, 1149 PipelineStatus SetSeekExpectations(TeardownState state,
922 StopOrError stop_or_error) { 1150 StopOrError stop_or_error) {
923 PipelineStatus status = PIPELINE_OK; 1151 PipelineStatus status = PIPELINE_OK;
924 base::Closure stop_cb = base::Bind( 1152 base::Closure stop_cb = base::Bind(
925 &CallbackHelper::OnStop, base::Unretained(&callbacks_)); 1153 &CallbackHelper::OnStop, base::Unretained(&callbacks_));
926 1154
1155 EXPECT_CALL(time_source_, StopTicking());
1156
927 if (state == kFlushing) { 1157 if (state == kFlushing) {
928 if (stop_or_error == kStop) { 1158 if (stop_or_error == kStop) {
929 EXPECT_CALL(*renderer_, Flush(_)) 1159 EXPECT_CALL(*audio_renderer_, Flush(_))
930 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), 1160 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
931 SetBufferingState(&buffering_state_cb_, 1161 SetBufferingState(&audio_buffering_state_cb_,
932 BUFFERING_HAVE_NOTHING), 1162 BUFFERING_HAVE_NOTHING),
933 RunClosure<0>())); 1163 RunClosure<0>()));
934 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
935 } else { 1164 } else {
936 status = PIPELINE_ERROR_READ; 1165 status = PIPELINE_ERROR_READ;
937 EXPECT_CALL(*renderer_, Flush(_)) 1166 EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce(
938 .WillOnce(DoAll(SetError(pipeline_.get(), status), 1167 DoAll(SetError(pipeline_.get(), status),
939 SetBufferingState(&buffering_state_cb_, 1168 SetBufferingState(&audio_buffering_state_cb_,
940 BUFFERING_HAVE_NOTHING), 1169 BUFFERING_HAVE_NOTHING),
941 RunClosure<0>())); 1170 RunClosure<0>()));
942 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
943 } 1171 }
944 1172
945 return status; 1173 return status;
946 } 1174 }
947 1175
948 EXPECT_CALL(*renderer_, Flush(_)) 1176 EXPECT_CALL(*audio_renderer_, Flush(_))
949 .WillOnce(DoAll(SetBufferingState(&buffering_state_cb_, 1177 .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
950 BUFFERING_HAVE_NOTHING), 1178 BUFFERING_HAVE_NOTHING),
951 RunClosure<0>())); 1179 RunClosure<0>()));
952 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); 1180 EXPECT_CALL(*video_renderer_, Flush(_))
1181 .WillOnce(DoAll(SetBufferingState(&video_buffering_state_cb_,
1182 BUFFERING_HAVE_NOTHING),
1183 RunClosure<0>()));
953 1184
954 if (state == kSeeking) { 1185 if (state == kSeeking) {
955 if (stop_or_error == kStop) { 1186 if (stop_or_error == kStop) {
956 EXPECT_CALL(*demuxer_, Seek(_, _)) 1187 EXPECT_CALL(*demuxer_, Seek(_, _))
957 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), 1188 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
958 RunCallback<1>(PIPELINE_OK))); 1189 RunCallback<1>(PIPELINE_OK)));
959 } else { 1190 } else {
960 status = PIPELINE_ERROR_READ; 1191 status = PIPELINE_ERROR_READ;
961 EXPECT_CALL(*demuxer_, Seek(_, _)) 1192 EXPECT_CALL(*demuxer_, Seek(_, _))
962 .WillOnce(RunCallback<1>(status)); 1193 .WillOnce(RunCallback<1>(status));
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 1231
1001 DISALLOW_COPY_AND_ASSIGN(PipelineTeardownTest); 1232 DISALLOW_COPY_AND_ASSIGN(PipelineTeardownTest);
1002 }; 1233 };
1003 1234
1004 #define INSTANTIATE_TEARDOWN_TEST(stop_or_error, state) \ 1235 #define INSTANTIATE_TEARDOWN_TEST(stop_or_error, state) \
1005 TEST_F(PipelineTeardownTest, stop_or_error##_##state) { \ 1236 TEST_F(PipelineTeardownTest, stop_or_error##_##state) { \
1006 RunTest(k##state, k##stop_or_error); \ 1237 RunTest(k##state, k##stop_or_error); \
1007 } 1238 }
1008 1239
1009 INSTANTIATE_TEARDOWN_TEST(Stop, InitDemuxer); 1240 INSTANTIATE_TEARDOWN_TEST(Stop, InitDemuxer);
1010 INSTANTIATE_TEARDOWN_TEST(Stop, InitRenderer); 1241 INSTANTIATE_TEARDOWN_TEST(Stop, InitAudioRenderer);
1242 INSTANTIATE_TEARDOWN_TEST(Stop, InitVideoRenderer);
1011 INSTANTIATE_TEARDOWN_TEST(Stop, Flushing); 1243 INSTANTIATE_TEARDOWN_TEST(Stop, Flushing);
1012 INSTANTIATE_TEARDOWN_TEST(Stop, Seeking); 1244 INSTANTIATE_TEARDOWN_TEST(Stop, Seeking);
1013 INSTANTIATE_TEARDOWN_TEST(Stop, Playing); 1245 INSTANTIATE_TEARDOWN_TEST(Stop, Playing);
1014 1246
1015 INSTANTIATE_TEARDOWN_TEST(Error, InitDemuxer); 1247 INSTANTIATE_TEARDOWN_TEST(Error, InitDemuxer);
1016 INSTANTIATE_TEARDOWN_TEST(Error, InitRenderer); 1248 INSTANTIATE_TEARDOWN_TEST(Error, InitAudioRenderer);
1249 INSTANTIATE_TEARDOWN_TEST(Error, InitVideoRenderer);
1017 INSTANTIATE_TEARDOWN_TEST(Error, Flushing); 1250 INSTANTIATE_TEARDOWN_TEST(Error, Flushing);
1018 INSTANTIATE_TEARDOWN_TEST(Error, Seeking); 1251 INSTANTIATE_TEARDOWN_TEST(Error, Seeking);
1019 INSTANTIATE_TEARDOWN_TEST(Error, Playing); 1252 INSTANTIATE_TEARDOWN_TEST(Error, Playing);
1020 1253
1021 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing); 1254 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing);
1022 1255
1023 } // namespace media 1256 } // namespace media
OLDNEW
« no previous file with comments | « media/base/pipeline.cc ('k') | media/base/renderer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698