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

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

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

Powered by Google App Engine
This is Rietveld 408576698