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

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: fix media/BUILD.gn 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 {
scherkus (not reviewing) 2014/08/21 21:17:00 OOC why move here? so it doesn't pollute namespace
xhwang 2014/08/22 19:11:31 Yep. RendererImplTest is also using CallbackHelp,
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 ExpectStop(); 124 ExpectStop();
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 ExpectStop() { 276 void ExpectStop() {
318 if (demuxer_) 277 if (demuxer_)
319 EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>()); 278 EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
320 } 279 }
321 280
322 MOCK_METHOD2(OnAddTextTrack, void(const TextTrackConfig&, 281 MOCK_METHOD2(OnAddTextTrack, void(const TextTrackConfig&,
323 const AddTextTrackDoneCB&)); 282 const AddTextTrackDoneCB&));
324 283
325 void DoOnAddTextTrack(const TextTrackConfig& config, 284 void DoOnAddTextTrack(const TextTrackConfig& config,
326 const AddTextTrackDoneCB& done_cb) { 285 const AddTextTrackDoneCB& done_cb) {
327 scoped_ptr<TextTrack> text_track(new MockTextTrack); 286 scoped_ptr<TextTrack> text_track(new MockTextTrack);
328 done_cb.Run(text_track.Pass()); 287 done_cb.Run(text_track.Pass());
329 } 288 }
330 289
331 // Fixture members. 290 // Fixture members.
332 StrictMock<CallbackHelper> callbacks_; 291 StrictMock<CallbackHelper> callbacks_;
333 base::SimpleTestTickClock test_tick_clock_; 292 base::SimpleTestTickClock test_tick_clock_;
334 base::MessageLoop message_loop_; 293 base::MessageLoop message_loop_;
335 scoped_ptr<Pipeline> pipeline_; 294 scoped_ptr<Pipeline> pipeline_;
336 295
337 scoped_ptr<FilterCollection> filter_collection_; 296 scoped_ptr<FilterCollection> filter_collection_;
338 scoped_ptr<StrictMock<MockDemuxer> > demuxer_; 297 scoped_ptr<StrictMock<MockDemuxer> > demuxer_;
339 StrictMock<MockVideoRenderer>* video_renderer_; 298 StrictMock<MockRenderer>* renderer_;
340 StrictMock<MockAudioRenderer>* audio_renderer_;
341 StrictMock<MockTimeSource> time_source_;
342 StrictMock<CallbackHelper> text_renderer_callbacks_; 299 StrictMock<CallbackHelper> text_renderer_callbacks_;
343 TextRenderer* text_renderer_; 300 TextRenderer* text_renderer_;
344 scoped_ptr<StrictMock<MockDemuxerStream> > audio_stream_; 301 scoped_ptr<StrictMock<MockDemuxerStream> > audio_stream_;
345 scoped_ptr<StrictMock<MockDemuxerStream> > video_stream_; 302 scoped_ptr<StrictMock<MockDemuxerStream> > video_stream_;
346 scoped_ptr<FakeTextTrackStream> text_stream_; 303 scoped_ptr<FakeTextTrackStream> text_stream_;
347 AudioRenderer::TimeCB audio_time_cb_; 304 BufferingStateCB buffering_state_cb_;
348 BufferingStateCB audio_buffering_state_cb_; 305 base::Closure ended_cb_;
349 BufferingStateCB video_buffering_state_cb_;
350 base::Closure audio_ended_cb_;
351 base::Closure video_ended_cb_;
352 VideoDecoderConfig video_decoder_config_; 306 VideoDecoderConfig video_decoder_config_;
353 PipelineMetadata metadata_; 307 PipelineMetadata metadata_;
354 308
355 private: 309 private:
356 DISALLOW_COPY_AND_ASSIGN(PipelineTest); 310 DISALLOW_COPY_AND_ASSIGN(PipelineTest);
357 }; 311 };
358 312
359 // Test that playback controls methods no-op when the pipeline hasn't been 313 // Test that playback controls methods no-op when the pipeline hasn't been
360 // started. 314 // started.
361 TEST_F(PipelineTest, NotStarted) { 315 TEST_F(PipelineTest, NotStarted) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); 394 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_)));
441 message_loop_.RunUntilIdle(); 395 message_loop_.RunUntilIdle();
442 } 396 }
443 397
444 TEST_F(PipelineTest, DemuxerErrorDuringStop) { 398 TEST_F(PipelineTest, DemuxerErrorDuringStop) {
445 CreateAudioStream(); 399 CreateAudioStream();
446 MockDemuxerStreamVector streams; 400 MockDemuxerStreamVector streams;
447 streams.push_back(audio_stream()); 401 streams.push_back(audio_stream());
448 402
449 SetDemuxerExpectations(&streams); 403 SetDemuxerExpectations(&streams);
450 SetAudioRendererExpectations(audio_stream()); 404 SetRendererExpectations();
451 405
452 StartPipeline(PIPELINE_OK); 406 StartPipeline(PIPELINE_OK);
453 407
454 EXPECT_CALL(*demuxer_, Stop(_)) 408 EXPECT_CALL(*demuxer_, Stop(_))
455 .WillOnce(DoAll(InvokeWithoutArgs(this, &PipelineTest::OnDemuxerError), 409 .WillOnce(DoAll(InvokeWithoutArgs(this, &PipelineTest::OnDemuxerError),
456 RunClosure<0>())); 410 RunClosure<0>()));
457 EXPECT_CALL(callbacks_, OnStop()); 411 EXPECT_CALL(callbacks_, OnStop());
458 412
459 pipeline_->Stop( 413 pipeline_->Stop(
460 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_))); 414 base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_)));
(...skipping 17 matching lines...) Expand all
478 432
479 StartPipeline(PIPELINE_ERROR_COULD_NOT_RENDER); 433 StartPipeline(PIPELINE_ERROR_COULD_NOT_RENDER);
480 } 434 }
481 435
482 TEST_F(PipelineTest, AudioStream) { 436 TEST_F(PipelineTest, AudioStream) {
483 CreateAudioStream(); 437 CreateAudioStream();
484 MockDemuxerStreamVector streams; 438 MockDemuxerStreamVector streams;
485 streams.push_back(audio_stream()); 439 streams.push_back(audio_stream());
486 440
487 SetDemuxerExpectations(&streams); 441 SetDemuxerExpectations(&streams);
488 SetAudioRendererExpectations(audio_stream()); 442 SetRendererExpectations();
489 443
490 StartPipeline(PIPELINE_OK); 444 StartPipeline(PIPELINE_OK);
491 EXPECT_TRUE(metadata_.has_audio); 445 EXPECT_TRUE(metadata_.has_audio);
492 EXPECT_FALSE(metadata_.has_video); 446 EXPECT_FALSE(metadata_.has_video);
493 } 447 }
494 448
495 TEST_F(PipelineTest, VideoStream) { 449 TEST_F(PipelineTest, VideoStream) {
496 CreateVideoStream(); 450 CreateVideoStream();
497 MockDemuxerStreamVector streams; 451 MockDemuxerStreamVector streams;
498 streams.push_back(video_stream()); 452 streams.push_back(video_stream());
499 453
500 SetDemuxerExpectations(&streams); 454 SetDemuxerExpectations(&streams);
501 SetVideoRendererExpectations(video_stream()); 455 SetRendererExpectations();
502 456
503 StartPipeline(PIPELINE_OK); 457 StartPipeline(PIPELINE_OK);
504 EXPECT_FALSE(metadata_.has_audio); 458 EXPECT_FALSE(metadata_.has_audio);
505 EXPECT_TRUE(metadata_.has_video); 459 EXPECT_TRUE(metadata_.has_video);
506 } 460 }
507 461
508 TEST_F(PipelineTest, AudioVideoStream) { 462 TEST_F(PipelineTest, AudioVideoStream) {
509 CreateAudioStream(); 463 CreateAudioStream();
510 CreateVideoStream(); 464 CreateVideoStream();
511 MockDemuxerStreamVector streams; 465 MockDemuxerStreamVector streams;
512 streams.push_back(audio_stream()); 466 streams.push_back(audio_stream());
513 streams.push_back(video_stream()); 467 streams.push_back(video_stream());
514 468
515 SetDemuxerExpectations(&streams); 469 SetDemuxerExpectations(&streams);
516 SetAudioRendererExpectations(audio_stream()); 470 SetRendererExpectations();
517 SetVideoRendererExpectations(video_stream());
518 471
519 StartPipeline(PIPELINE_OK); 472 StartPipeline(PIPELINE_OK);
520 EXPECT_TRUE(metadata_.has_audio); 473 EXPECT_TRUE(metadata_.has_audio);
521 EXPECT_TRUE(metadata_.has_video); 474 EXPECT_TRUE(metadata_.has_video);
522 } 475 }
523 476
524 TEST_F(PipelineTest, VideoTextStream) { 477 TEST_F(PipelineTest, VideoTextStream) {
525 CreateVideoStream(); 478 CreateVideoStream();
526 CreateTextStream(); 479 CreateTextStream();
527 MockDemuxerStreamVector streams; 480 MockDemuxerStreamVector streams;
528 streams.push_back(video_stream()); 481 streams.push_back(video_stream());
529 482
530 SetDemuxerExpectations(&streams); 483 SetDemuxerExpectations(&streams);
531 SetVideoRendererExpectations(video_stream()); 484 SetRendererExpectations();
532 485
533 StartPipeline(PIPELINE_OK); 486 StartPipeline(PIPELINE_OK);
534 EXPECT_FALSE(metadata_.has_audio); 487 EXPECT_FALSE(metadata_.has_audio);
535 EXPECT_TRUE(metadata_.has_video); 488 EXPECT_TRUE(metadata_.has_video);
536 489
537 AddTextStream(); 490 AddTextStream();
538 message_loop_.RunUntilIdle();
539 } 491 }
540 492
541 TEST_F(PipelineTest, VideoAudioTextStream) { 493 TEST_F(PipelineTest, VideoAudioTextStream) {
542 CreateVideoStream(); 494 CreateVideoStream();
543 CreateAudioStream(); 495 CreateAudioStream();
544 CreateTextStream(); 496 CreateTextStream();
545 MockDemuxerStreamVector streams; 497 MockDemuxerStreamVector streams;
546 streams.push_back(video_stream()); 498 streams.push_back(video_stream());
547 streams.push_back(audio_stream()); 499 streams.push_back(audio_stream());
548 500
549 SetDemuxerExpectations(&streams); 501 SetDemuxerExpectations(&streams);
550 SetVideoRendererExpectations(video_stream()); 502 SetRendererExpectations();
551 SetAudioRendererExpectations(audio_stream());
552 503
553 StartPipeline(PIPELINE_OK); 504 StartPipeline(PIPELINE_OK);
554 EXPECT_TRUE(metadata_.has_audio); 505 EXPECT_TRUE(metadata_.has_audio);
555 EXPECT_TRUE(metadata_.has_video); 506 EXPECT_TRUE(metadata_.has_video);
556 507
557 AddTextStream(); 508 AddTextStream();
558 message_loop_.RunUntilIdle();
559 } 509 }
560 510
561 TEST_F(PipelineTest, Seek) { 511 TEST_F(PipelineTest, Seek) {
562 CreateAudioStream(); 512 CreateAudioStream();
563 CreateVideoStream(); 513 CreateVideoStream();
564 CreateTextStream(); 514 CreateTextStream();
565 MockDemuxerStreamVector streams; 515 MockDemuxerStreamVector streams;
566 streams.push_back(audio_stream()); 516 streams.push_back(audio_stream());
567 streams.push_back(video_stream()); 517 streams.push_back(video_stream());
568 518
569 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); 519 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000));
570 SetAudioRendererExpectations(audio_stream()); 520 SetRendererExpectations();
571 SetVideoRendererExpectations(video_stream());
572 521
573 // Initialize then seek! 522 // Initialize then seek!
574 StartPipeline(PIPELINE_OK); 523 StartPipeline(PIPELINE_OK);
575 524
576 // Every filter should receive a call to Seek(). 525 // Every filter should receive a call to Seek().
577 base::TimeDelta expected = base::TimeDelta::FromSeconds(2000); 526 base::TimeDelta expected = base::TimeDelta::FromSeconds(2000);
578 ExpectSeek(expected, false); 527 ExpectSeek(expected, false);
579 DoSeek(expected); 528 DoSeek(expected);
580 } 529 }
581 530
582 TEST_F(PipelineTest, SeekAfterError) { 531 TEST_F(PipelineTest, SeekAfterError) {
583 CreateAudioStream(); 532 CreateAudioStream();
584 MockDemuxerStreamVector streams; 533 MockDemuxerStreamVector streams;
585 streams.push_back(audio_stream()); 534 streams.push_back(audio_stream());
586 535
587 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); 536 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000));
588 SetAudioRendererExpectations(audio_stream()); 537 SetRendererExpectations();
589 538
590 // Initialize then seek! 539 // Initialize then seek!
591 StartPipeline(PIPELINE_OK); 540 StartPipeline(PIPELINE_OK);
592 541
593 EXPECT_CALL(*demuxer_, Stop(_)) 542 EXPECT_CALL(*demuxer_, Stop(_))
594 .WillOnce(RunClosure<0>()); 543 .WillOnce(RunClosure<0>());
595 EXPECT_CALL(callbacks_, OnError(_)); 544 EXPECT_CALL(callbacks_, OnError(_));
596 545
597 static_cast<DemuxerHost*>(pipeline_.get()) 546 static_cast<DemuxerHost*>(pipeline_.get())
598 ->OnDemuxerError(PIPELINE_ERROR_ABORT); 547 ->OnDemuxerError(PIPELINE_ERROR_ABORT);
599 message_loop_.RunUntilIdle(); 548 message_loop_.RunUntilIdle();
600 549
601 pipeline_->Seek( 550 pipeline_->Seek(
602 base::TimeDelta::FromMilliseconds(100), 551 base::TimeDelta::FromMilliseconds(100),
603 base::Bind(&CallbackHelper::OnSeek, base::Unretained(&callbacks_))); 552 base::Bind(&CallbackHelper::OnSeek, base::Unretained(&callbacks_)));
604 message_loop_.RunUntilIdle(); 553 message_loop_.RunUntilIdle();
605 } 554 }
606 555
607 TEST_F(PipelineTest, SetVolume) { 556 TEST_F(PipelineTest, SetVolume) {
608 CreateAudioStream(); 557 CreateAudioStream();
609 MockDemuxerStreamVector streams; 558 MockDemuxerStreamVector streams;
610 streams.push_back(audio_stream()); 559 streams.push_back(audio_stream());
611 560
612 SetDemuxerExpectations(&streams); 561 SetDemuxerExpectations(&streams);
613 SetAudioRendererExpectations(audio_stream()); 562 SetRendererExpectations();
614 563
615 // The audio renderer should receive a call to SetVolume(). 564 // The audio renderer should receive a call to SetVolume().
616 float expected = 0.5f; 565 float expected = 0.5f;
617 EXPECT_CALL(*audio_renderer_, SetVolume(expected)); 566 EXPECT_CALL(*renderer_, SetVolume(expected));
618 567
619 // Initialize then set volume! 568 // Initialize then set volume!
620 StartPipeline(PIPELINE_OK); 569 StartPipeline(PIPELINE_OK);
621 pipeline_->SetVolume(expected); 570 pipeline_->SetVolume(expected);
622 } 571 }
623 572
624 TEST_F(PipelineTest, Properties) { 573 TEST_F(PipelineTest, Properties) {
625 CreateVideoStream(); 574 CreateVideoStream();
626 MockDemuxerStreamVector streams; 575 MockDemuxerStreamVector streams;
627 streams.push_back(video_stream()); 576 streams.push_back(video_stream());
628 577
629 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); 578 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100);
630 SetDemuxerExpectations(&streams, kDuration); 579 SetDemuxerExpectations(&streams, kDuration);
631 SetVideoRendererExpectations(video_stream()); 580 SetRendererExpectations();
632 581
633 StartPipeline(PIPELINE_OK); 582 StartPipeline(PIPELINE_OK);
634 EXPECT_EQ(kDuration.ToInternalValue(), 583 EXPECT_EQ(kDuration.ToInternalValue(),
635 pipeline_->GetMediaDuration().ToInternalValue()); 584 pipeline_->GetMediaDuration().ToInternalValue());
636 EXPECT_FALSE(pipeline_->DidLoadingProgress()); 585 EXPECT_FALSE(pipeline_->DidLoadingProgress());
637 } 586 }
638 587
639 TEST_F(PipelineTest, GetBufferedTimeRanges) { 588 TEST_F(PipelineTest, GetBufferedTimeRanges) {
640 CreateVideoStream(); 589 CreateVideoStream();
641 MockDemuxerStreamVector streams; 590 MockDemuxerStreamVector streams;
642 streams.push_back(video_stream()); 591 streams.push_back(video_stream());
643 592
644 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); 593 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100);
645 SetDemuxerExpectations(&streams, kDuration); 594 SetDemuxerExpectations(&streams, kDuration);
646 SetVideoRendererExpectations(video_stream()); 595 SetRendererExpectations();
647 596
648 StartPipeline(PIPELINE_OK); 597 StartPipeline(PIPELINE_OK);
649 598
650 EXPECT_EQ(0u, pipeline_->GetBufferedTimeRanges().size()); 599 EXPECT_EQ(0u, pipeline_->GetBufferedTimeRanges().size());
651 600
652 EXPECT_FALSE(pipeline_->DidLoadingProgress()); 601 EXPECT_FALSE(pipeline_->DidLoadingProgress());
653 pipeline_->AddBufferedTimeRange(base::TimeDelta(), kDuration / 8); 602 pipeline_->AddBufferedTimeRange(base::TimeDelta(), kDuration / 8);
654 EXPECT_TRUE(pipeline_->DidLoadingProgress()); 603 EXPECT_TRUE(pipeline_->DidLoadingProgress());
655 EXPECT_FALSE(pipeline_->DidLoadingProgress()); 604 EXPECT_FALSE(pipeline_->DidLoadingProgress());
656 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); 605 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size());
657 EXPECT_EQ(base::TimeDelta(), pipeline_->GetBufferedTimeRanges().start(0)); 606 EXPECT_EQ(base::TimeDelta(), pipeline_->GetBufferedTimeRanges().start(0));
658 EXPECT_EQ(kDuration / 8, pipeline_->GetBufferedTimeRanges().end(0)); 607 EXPECT_EQ(kDuration / 8, pipeline_->GetBufferedTimeRanges().end(0));
659 608
660 base::TimeDelta kSeekTime = kDuration / 2; 609 base::TimeDelta kSeekTime = kDuration / 2;
661 ExpectSeek(kSeekTime, false); 610 ExpectSeek(kSeekTime, false);
662 DoSeek(kSeekTime); 611 DoSeek(kSeekTime);
663 612
664 EXPECT_FALSE(pipeline_->DidLoadingProgress()); 613 EXPECT_FALSE(pipeline_->DidLoadingProgress());
665 } 614 }
666 615
667 TEST_F(PipelineTest, EndedCallback) { 616 TEST_F(PipelineTest, EndedCallback) {
668 CreateAudioStream(); 617 CreateAudioStream();
669 CreateVideoStream(); 618 CreateVideoStream();
670 CreateTextStream(); 619 CreateTextStream();
671 MockDemuxerStreamVector streams; 620 MockDemuxerStreamVector streams;
672 streams.push_back(audio_stream()); 621 streams.push_back(audio_stream());
673 streams.push_back(video_stream()); 622 streams.push_back(video_stream());
674 623
675 SetDemuxerExpectations(&streams); 624 SetDemuxerExpectations(&streams);
676 SetAudioRendererExpectations(audio_stream()); 625 SetRendererExpectations();
677 SetVideoRendererExpectations(video_stream());
678 StartPipeline(PIPELINE_OK); 626 StartPipeline(PIPELINE_OK);
679 627
680 AddTextStream(); 628 AddTextStream();
681 629
682 // The ended callback shouldn't run until all renderers have ended. 630 // The ended callback shouldn't run until all renderers have ended.
683 audio_ended_cb_.Run(); 631 ended_cb_.Run();
684 message_loop_.RunUntilIdle(); 632 message_loop_.RunUntilIdle();
685 633
686 video_ended_cb_.Run();
687 message_loop_.RunUntilIdle();
688
689 EXPECT_CALL(time_source_, StopTicking());
690 EXPECT_CALL(callbacks_, OnEnded()); 634 EXPECT_CALL(callbacks_, OnEnded());
691 text_stream()->SendEosNotification(); 635 text_stream()->SendEosNotification();
692 message_loop_.RunUntilIdle(); 636 message_loop_.RunUntilIdle();
693 } 637 }
694 638
695 TEST_F(PipelineTest, AudioStreamShorterThanVideo) {
696 base::TimeDelta duration = base::TimeDelta::FromSeconds(10);
697
698 CreateAudioStream();
699 CreateVideoStream();
700 MockDemuxerStreamVector streams;
701 streams.push_back(audio_stream());
702 streams.push_back(video_stream());
703
704 // Replace what's used for interpolating to simulate wall clock time.
705 pipeline_->SetTimeDeltaInterpolatorForTesting(
706 new TimeDeltaInterpolator(&test_tick_clock_));
707
708 SetDemuxerExpectations(&streams, duration);
709 SetAudioRendererExpectations(audio_stream());
710 SetVideoRendererExpectations(video_stream());
711 StartPipeline(PIPELINE_OK);
712
713 EXPECT_EQ(0, pipeline_->GetMediaTime().ToInternalValue());
714
715 float playback_rate = 1.0f;
716 EXPECT_CALL(time_source_, SetPlaybackRate(playback_rate));
717 pipeline_->SetPlaybackRate(playback_rate);
718 message_loop_.RunUntilIdle();
719
720 InSequence s;
721
722 // Verify that the clock doesn't advance since it hasn't been started by
723 // a time update from the audio stream.
724 int64 start_time = pipeline_->GetMediaTime().ToInternalValue();
725 test_tick_clock_.Advance(base::TimeDelta::FromMilliseconds(100));
726 EXPECT_EQ(pipeline_->GetMediaTime().ToInternalValue(), start_time);
727
728 // Signal end of audio stream.
729 audio_ended_cb_.Run();
730 message_loop_.RunUntilIdle();
731
732 // Verify that the clock advances.
733 start_time = pipeline_->GetMediaTime().ToInternalValue();
734 test_tick_clock_.Advance(base::TimeDelta::FromMilliseconds(100));
735 EXPECT_GT(pipeline_->GetMediaTime().ToInternalValue(), start_time);
736
737 // Signal end of video stream and make sure OnEnded() callback occurs.
738 EXPECT_CALL(time_source_, StopTicking());
739 EXPECT_CALL(callbacks_, OnEnded());
740 video_ended_cb_.Run();
741 }
742
743 TEST_F(PipelineTest, ErrorDuringSeek) { 639 TEST_F(PipelineTest, ErrorDuringSeek) {
744 CreateAudioStream(); 640 CreateAudioStream();
745 MockDemuxerStreamVector streams; 641 MockDemuxerStreamVector streams;
746 streams.push_back(audio_stream()); 642 streams.push_back(audio_stream());
747 643
748 SetDemuxerExpectations(&streams); 644 SetDemuxerExpectations(&streams);
749 SetAudioRendererExpectations(audio_stream()); 645 SetRendererExpectations();
750 StartPipeline(PIPELINE_OK); 646 StartPipeline(PIPELINE_OK);
751 647
752 float playback_rate = 1.0f; 648 float playback_rate = 1.0f;
753 EXPECT_CALL(time_source_, SetPlaybackRate(playback_rate)); 649 EXPECT_CALL(*renderer_, SetPlaybackRate(playback_rate));
754 pipeline_->SetPlaybackRate(playback_rate); 650 pipeline_->SetPlaybackRate(playback_rate);
755 message_loop_.RunUntilIdle(); 651 message_loop_.RunUntilIdle();
756 652
757 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); 653 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
758 654
759 // Preroll() isn't called as the demuxer errors out first. 655 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
760 EXPECT_CALL(time_source_, StopTicking()); 656 EXPECT_CALL(*renderer_, Flush(_))
761 EXPECT_CALL(*audio_renderer_, Flush(_)) 657 .WillOnce(DoAll(SetBufferingState(&buffering_state_cb_,
762 .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
763 BUFFERING_HAVE_NOTHING), 658 BUFFERING_HAVE_NOTHING),
764 RunClosure<0>())); 659 RunClosure<0>()));
765 660
766 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) 661 EXPECT_CALL(*demuxer_, Seek(seek_time, _))
767 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); 662 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ));
768 EXPECT_CALL(*demuxer_, Stop(_)) 663 EXPECT_CALL(*demuxer_, Stop(_))
769 .WillOnce(RunClosure<0>()); 664 .WillOnce(RunClosure<0>());
770 665
771 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, 666 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek,
772 base::Unretained(&callbacks_))); 667 base::Unretained(&callbacks_)));
(...skipping 19 matching lines...) Expand all
792 // No additional tasks should be queued as a result of these calls. 687 // No additional tasks should be queued as a result of these calls.
793 EXPECT_TRUE(message_loop->IsIdleForTesting()); 688 EXPECT_TRUE(message_loop->IsIdleForTesting());
794 } 689 }
795 690
796 TEST_F(PipelineTest, NoMessageDuringTearDownFromError) { 691 TEST_F(PipelineTest, NoMessageDuringTearDownFromError) {
797 CreateAudioStream(); 692 CreateAudioStream();
798 MockDemuxerStreamVector streams; 693 MockDemuxerStreamVector streams;
799 streams.push_back(audio_stream()); 694 streams.push_back(audio_stream());
800 695
801 SetDemuxerExpectations(&streams); 696 SetDemuxerExpectations(&streams);
802 SetAudioRendererExpectations(audio_stream()); 697 SetRendererExpectations();
803 StartPipeline(PIPELINE_OK); 698 StartPipeline(PIPELINE_OK);
804 699
805 // Trigger additional requests on the pipeline during tear down from error. 700 // Trigger additional requests on the pipeline during tear down from error.
806 base::Callback<void(PipelineStatus)> cb = base::Bind( 701 base::Callback<void(PipelineStatus)> cb = base::Bind(
807 &TestNoCallsAfterError, pipeline_.get(), &message_loop_); 702 &TestNoCallsAfterError, pipeline_.get(), &message_loop_);
808 ON_CALL(callbacks_, OnError(_)) 703 ON_CALL(callbacks_, OnError(_))
809 .WillByDefault(Invoke(&cb, &base::Callback<void(PipelineStatus)>::Run)); 704 .WillByDefault(Invoke(&cb, &base::Callback<void(PipelineStatus)>::Run));
810 705
811 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); 706 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
812 707
813 // Seek() isn't called as the demuxer errors out first. 708 // Seek() isn't called as the demuxer errors out first.
814 EXPECT_CALL(time_source_, StopTicking()); 709 EXPECT_CALL(*renderer_, Flush(_))
815 EXPECT_CALL(*audio_renderer_, Flush(_)) 710 .WillOnce(DoAll(SetBufferingState(&buffering_state_cb_,
816 .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
817 BUFFERING_HAVE_NOTHING), 711 BUFFERING_HAVE_NOTHING),
818 RunClosure<0>())); 712 RunClosure<0>()));
713 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
819 714
820 EXPECT_CALL(*demuxer_, Seek(seek_time, _)) 715 EXPECT_CALL(*demuxer_, Seek(seek_time, _))
821 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); 716 .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ));
822 EXPECT_CALL(*demuxer_, Stop(_)) 717 EXPECT_CALL(*demuxer_, Stop(_))
823 .WillOnce(RunClosure<0>()); 718 .WillOnce(RunClosure<0>());
824 719
825 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek, 720 pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek,
826 base::Unretained(&callbacks_))); 721 base::Unretained(&callbacks_)));
827 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ)); 722 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ));
828 message_loop_.RunUntilIdle(); 723 message_loop_.RunUntilIdle();
829 } 724 }
830 725
831 static void RunTimeCB(const AudioRenderer::TimeCB& time_cb,
832 int time_in_ms,
833 int max_time_in_ms) {
834 time_cb.Run(base::TimeDelta::FromMilliseconds(time_in_ms),
835 base::TimeDelta::FromMilliseconds(max_time_in_ms));
836 }
837
838 TEST_F(PipelineTest, AudioTimeUpdateDuringSeek) {
839 CreateAudioStream();
840 MockDemuxerStreamVector streams;
841 streams.push_back(audio_stream());
842
843 SetDemuxerExpectations(&streams);
844 SetAudioRendererExpectations(audio_stream());
845 StartPipeline(PIPELINE_OK);
846
847 float playback_rate = 1.0f;
848 EXPECT_CALL(time_source_, SetPlaybackRate(playback_rate));
849 pipeline_->SetPlaybackRate(playback_rate);
850 message_loop_.RunUntilIdle();
851
852 // Provide an initial time update so that the pipeline transitions out of the
853 // "waiting for time update" state.
854 audio_time_cb_.Run(base::TimeDelta::FromMilliseconds(100),
855 base::TimeDelta::FromMilliseconds(500));
856
857 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
858
859 // Arrange to trigger a time update while the demuxer is in the middle of
860 // seeking. This update should be ignored by the pipeline and the clock should
861 // not get updated.
862 base::Closure closure = base::Bind(&RunTimeCB, audio_time_cb_, 300, 700);
863 EXPECT_CALL(*demuxer_, Seek(seek_time, _))
864 .WillOnce(DoAll(InvokeWithoutArgs(&closure, &base::Closure::Run),
865 RunCallback<1>(PIPELINE_OK)));
866
867 EXPECT_CALL(time_source_, StopTicking());
868 EXPECT_CALL(*audio_renderer_, Flush(_))
869 .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
870 BUFFERING_HAVE_NOTHING),
871 RunClosure<0>()));
872 EXPECT_CALL(time_source_, SetMediaTime(seek_time));
873 EXPECT_CALL(time_source_, SetPlaybackRate(_));
874 EXPECT_CALL(time_source_, StartTicking());
875 EXPECT_CALL(*audio_renderer_, StartPlaying())
876 .WillOnce(SetBufferingState(&audio_buffering_state_cb_,
877 BUFFERING_HAVE_ENOUGH));
878 EXPECT_CALL(*audio_renderer_, SetVolume(_));
879
880 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK));
881 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
882 DoSeek(seek_time);
883
884 EXPECT_EQ(pipeline_->GetMediaTime(), seek_time);
885
886 // Now that the seek is complete, verify that time updates advance the current
887 // time.
888 base::TimeDelta new_time = seek_time + base::TimeDelta::FromMilliseconds(100);
889 audio_time_cb_.Run(new_time, new_time);
890
891 EXPECT_EQ(pipeline_->GetMediaTime(), new_time);
892 }
893
894 static void DeletePipeline(scoped_ptr<Pipeline> pipeline) { 726 static void DeletePipeline(scoped_ptr<Pipeline> pipeline) {
895 // |pipeline| will go out of scope. 727 // |pipeline| will go out of scope.
896 } 728 }
897 729
898 TEST_F(PipelineTest, DeleteAfterStop) { 730 TEST_F(PipelineTest, DeleteAfterStop) {
899 CreateAudioStream(); 731 CreateAudioStream();
900 MockDemuxerStreamVector streams; 732 MockDemuxerStreamVector streams;
901 streams.push_back(audio_stream()); 733 streams.push_back(audio_stream());
902 SetDemuxerExpectations(&streams); 734 SetDemuxerExpectations(&streams);
903 SetAudioRendererExpectations(audio_stream()); 735 SetRendererExpectations();
904 StartPipeline(PIPELINE_OK); 736 StartPipeline(PIPELINE_OK);
905 737
906 ExpectStop(); 738 ExpectStop();
907 739
908 Pipeline* pipeline = pipeline_.get(); 740 Pipeline* pipeline = pipeline_.get();
909 pipeline->Stop(base::Bind(&DeletePipeline, base::Passed(&pipeline_))); 741 pipeline->Stop(base::Bind(&DeletePipeline, base::Passed(&pipeline_)));
910 message_loop_.RunUntilIdle(); 742 message_loop_.RunUntilIdle();
911 } 743 }
912 744
913 TEST_F(PipelineTest, Underflow) { 745 TEST_F(PipelineTest, Underflow) {
914 CreateAudioStream(); 746 CreateAudioStream();
915 CreateVideoStream(); 747 CreateVideoStream();
916 MockDemuxerStreamVector streams; 748 MockDemuxerStreamVector streams;
917 streams.push_back(audio_stream()); 749 streams.push_back(audio_stream());
918 streams.push_back(video_stream()); 750 streams.push_back(video_stream());
919 751
920 SetDemuxerExpectations(&streams); 752 SetDemuxerExpectations(&streams);
921 SetAudioRendererExpectations(audio_stream()); 753 SetRendererExpectations();
922 SetVideoRendererExpectations(video_stream());
923 StartPipeline(PIPELINE_OK); 754 StartPipeline(PIPELINE_OK);
924 755
925 // Simulate underflow. 756 // Simulate underflow.
926 EXPECT_CALL(time_source_, StopTicking()); 757 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
927 audio_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); 758 buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING);
928 759
929 // Seek while underflowed. We shouldn't call StopTicking() again. 760 // Seek while underflowed.
930 base::TimeDelta expected = base::TimeDelta::FromSeconds(5); 761 base::TimeDelta expected = base::TimeDelta::FromSeconds(5);
931 ExpectSeek(expected, true); 762 ExpectSeek(expected, true);
932 DoSeek(expected); 763 DoSeek(expected);
933 } 764 }
934 765
935 static void PostTimeCB(base::MessageLoop* message_loop,
936 const AudioRenderer::TimeCB& time_cb) {
937 base::TimeDelta new_time = base::TimeDelta::FromMilliseconds(100);
938 message_loop->PostTask(FROM_HERE, base::Bind(time_cb, new_time, new_time));
939 }
940
941 TEST_F(PipelineTest, TimeUpdateAfterStop) {
942 CreateAudioStream();
943 CreateVideoStream();
944 MockDemuxerStreamVector streams;
945 streams.push_back(audio_stream());
946 streams.push_back(video_stream());
947
948 SetDemuxerExpectations(&streams);
949 SetAudioRendererExpectations(audio_stream());
950 SetVideoRendererExpectations(video_stream());
951 StartPipeline(PIPELINE_OK);
952
953 // Double post here! This is a hack to simulate the case where TimeCB is
954 // posted during ~AudioRenderer(), which is triggered in Pipeline::DoStop.
955 // Since we can't EXPECT_CALL the dtor and Pipeline::DoStop() is posted
956 // as well, we need to post twice here.
957 message_loop_.PostTask(
958 FROM_HERE, base::Bind(&PostTimeCB, &message_loop_, audio_time_cb_));
959
960 EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
961
962 Pipeline* pipeline = pipeline_.get();
963 pipeline->Stop(base::Bind(&DeletePipeline, base::Passed(&pipeline_)));
964 message_loop_.RunUntilIdle();
965 }
966
967 class PipelineTeardownTest : public PipelineTest { 766 class PipelineTeardownTest : public PipelineTest {
968 public: 767 public:
969 enum TeardownState { 768 enum TeardownState {
970 kInitDemuxer, 769 kInitDemuxer,
971 kInitAudioRenderer, 770 kInitRenderer,
972 kInitVideoRenderer,
973 kFlushing, 771 kFlushing,
974 kSeeking, 772 kSeeking,
975 kPlaying, 773 kPlaying,
976 }; 774 };
977 775
978 enum StopOrError { 776 enum StopOrError {
979 kStop, 777 kStop,
980 kError, 778 kError,
981 kErrorAndStop, 779 kErrorAndStop,
982 }; 780 };
983 781
984 PipelineTeardownTest() {} 782 PipelineTeardownTest() {}
985 virtual ~PipelineTeardownTest() {} 783 virtual ~PipelineTeardownTest() {}
986 784
987 void RunTest(TeardownState state, StopOrError stop_or_error) { 785 void RunTest(TeardownState state, StopOrError stop_or_error) {
988 switch (state) { 786 switch (state) {
989 case kInitDemuxer: 787 case kInitDemuxer:
990 case kInitAudioRenderer: 788 case kInitRenderer:
991 case kInitVideoRenderer:
992 DoInitialize(state, stop_or_error); 789 DoInitialize(state, stop_or_error);
993 break; 790 break;
994 791
995 case kFlushing: 792 case kFlushing:
996 case kSeeking: 793 case kSeeking:
997 DoInitialize(state, stop_or_error); 794 DoInitialize(state, stop_or_error);
998 DoSeek(state, stop_or_error); 795 DoSeek(state, stop_or_error);
999 break; 796 break;
1000 797
1001 case kPlaying: 798 case kPlaying:
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 return status; 846 return status;
1050 } 847 }
1051 848
1052 CreateAudioStream(); 849 CreateAudioStream();
1053 CreateVideoStream(); 850 CreateVideoStream();
1054 MockDemuxerStreamVector streams; 851 MockDemuxerStreamVector streams;
1055 streams.push_back(audio_stream()); 852 streams.push_back(audio_stream());
1056 streams.push_back(video_stream()); 853 streams.push_back(video_stream());
1057 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); 854 SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000));
1058 855
1059 if (state == kInitAudioRenderer) { 856 EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(true));
857 EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(true));
858
859 if (state == kInitRenderer) {
1060 if (stop_or_error == kStop) { 860 if (stop_or_error == kStop) {
1061 EXPECT_CALL(*audio_renderer_, Initialize(_, _, _, _, _, _, _)) 861 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _))
1062 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), 862 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
1063 RunCallback<1>(PIPELINE_OK))); 863 RunCallback<0>(PIPELINE_OK)));
1064 EXPECT_CALL(callbacks_, OnStop()); 864 EXPECT_CALL(callbacks_, OnStop());
1065 } else { 865 } else {
1066 status = PIPELINE_ERROR_INITIALIZATION_FAILED; 866 status = PIPELINE_ERROR_INITIALIZATION_FAILED;
1067 EXPECT_CALL(*audio_renderer_, Initialize(_, _, _, _, _, _, _)) 867 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _))
1068 .WillOnce(RunCallback<1>(status)); 868 .WillOnce(RunCallback<0>(status));
1069 } 869 }
1070 870
1071 EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>()); 871 EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
1072 return status; 872 return status;
1073 } 873 }
1074 874
1075 EXPECT_CALL(*audio_renderer_, Initialize(_, _, _, _, _, _, _)) 875 EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _))
1076 .WillOnce(DoAll(SaveArg<4>(&audio_buffering_state_cb_), 876 .WillOnce(DoAll(SaveArg<4>(&buffering_state_cb_),
1077 RunCallback<1>(PIPELINE_OK))); 877 RunCallback<0>(PIPELINE_OK)));
1078
1079 if (state == kInitVideoRenderer) {
1080 if (stop_or_error == kStop) {
1081 EXPECT_CALL(*video_renderer_, Initialize(_, _, _, _, _, _, _, _, _, _))
1082 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
1083 RunCallback<2>(PIPELINE_OK)));
1084 EXPECT_CALL(callbacks_, OnStop());
1085 } else {
1086 status = PIPELINE_ERROR_INITIALIZATION_FAILED;
1087 EXPECT_CALL(*video_renderer_, Initialize(_, _, _, _, _, _, _, _, _, _))
1088 .WillOnce(RunCallback<2>(status));
1089 }
1090
1091 EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
1092 return status;
1093 }
1094
1095 EXPECT_CALL(*video_renderer_, Initialize(_, _, _, _, _, _, _, _, _, _))
1096 .WillOnce(DoAll(SaveArg<5>(&video_buffering_state_cb_),
1097 RunCallback<2>(PIPELINE_OK)));
1098 878
1099 EXPECT_CALL(callbacks_, OnMetadata(_)); 879 EXPECT_CALL(callbacks_, OnMetadata(_));
1100 880
1101 // If we get here it's a successful initialization. 881 // If we get here it's a successful initialization.
1102 EXPECT_CALL(*audio_renderer_, GetTimeSource()) 882 EXPECT_CALL(*renderer_, SetPlaybackRate(0.0f));
1103 .WillOnce(Return(&time_source_)); 883 EXPECT_CALL(*renderer_, SetVolume(1.0f));
1104 EXPECT_CALL(time_source_, SetMediaTime(base::TimeDelta())); 884 EXPECT_CALL(*renderer_, StartPlayingFrom(base::TimeDelta()))
1105 EXPECT_CALL(time_source_, SetPlaybackRate(0.0f)); 885 .WillOnce(SetBufferingState(&buffering_state_cb_,
1106 EXPECT_CALL(time_source_, StartTicking());
1107 EXPECT_CALL(*audio_renderer_, SetVolume(1.0f));
1108 EXPECT_CALL(*audio_renderer_, StartPlaying())
1109 .WillOnce(SetBufferingState(&audio_buffering_state_cb_,
1110 BUFFERING_HAVE_ENOUGH));
1111 EXPECT_CALL(*video_renderer_, StartPlaying())
1112 .WillOnce(SetBufferingState(&video_buffering_state_cb_,
1113 BUFFERING_HAVE_ENOUGH)); 886 BUFFERING_HAVE_ENOUGH));
1114 887
1115 if (status == PIPELINE_OK) 888 if (status == PIPELINE_OK)
1116 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); 889 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
1117 890
1118 return status; 891 return status;
1119 } 892 }
1120 893
1121 void DoSeek(TeardownState state, StopOrError stop_or_error) { 894 void DoSeek(TeardownState state, StopOrError stop_or_error) {
1122 InSequence s; 895 InSequence s;
(...skipping 10 matching lines...) Expand all
1133 &CallbackHelper::OnSeek, base::Unretained(&callbacks_))); 906 &CallbackHelper::OnSeek, base::Unretained(&callbacks_)));
1134 message_loop_.RunUntilIdle(); 907 message_loop_.RunUntilIdle();
1135 } 908 }
1136 909
1137 PipelineStatus SetSeekExpectations(TeardownState state, 910 PipelineStatus SetSeekExpectations(TeardownState state,
1138 StopOrError stop_or_error) { 911 StopOrError stop_or_error) {
1139 PipelineStatus status = PIPELINE_OK; 912 PipelineStatus status = PIPELINE_OK;
1140 base::Closure stop_cb = base::Bind( 913 base::Closure stop_cb = base::Bind(
1141 &CallbackHelper::OnStop, base::Unretained(&callbacks_)); 914 &CallbackHelper::OnStop, base::Unretained(&callbacks_));
1142 915
1143 EXPECT_CALL(time_source_, StopTicking());
1144
1145 if (state == kFlushing) { 916 if (state == kFlushing) {
1146 if (stop_or_error == kStop) { 917 if (stop_or_error == kStop) {
1147 EXPECT_CALL(*audio_renderer_, Flush(_)) 918 EXPECT_CALL(*renderer_, Flush(_))
1148 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), 919 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
1149 SetBufferingState(&audio_buffering_state_cb_, 920 SetBufferingState(&buffering_state_cb_,
1150 BUFFERING_HAVE_NOTHING), 921 BUFFERING_HAVE_NOTHING),
1151 RunClosure<0>())); 922 RunClosure<0>()));
923 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
1152 } else { 924 } else {
1153 status = PIPELINE_ERROR_READ; 925 status = PIPELINE_ERROR_READ;
1154 EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce( 926 EXPECT_CALL(*renderer_, Flush(_))
1155 DoAll(SetError(pipeline_.get(), status), 927 .WillOnce(DoAll(SetError(pipeline_.get(), status),
1156 SetBufferingState(&audio_buffering_state_cb_, 928 SetBufferingState(&buffering_state_cb_,
1157 BUFFERING_HAVE_NOTHING), 929 BUFFERING_HAVE_NOTHING),
1158 RunClosure<0>())); 930 RunClosure<0>()));
931 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
1159 } 932 }
1160 933
1161 return status; 934 return status;
1162 } 935 }
1163 936
1164 EXPECT_CALL(*audio_renderer_, Flush(_)) 937 EXPECT_CALL(*renderer_, Flush(_))
1165 .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_, 938 .WillOnce(DoAll(SetBufferingState(&buffering_state_cb_,
1166 BUFFERING_HAVE_NOTHING), 939 BUFFERING_HAVE_NOTHING),
1167 RunClosure<0>())); 940 RunClosure<0>()));
1168 EXPECT_CALL(*video_renderer_, Flush(_)) 941 EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
1169 .WillOnce(DoAll(SetBufferingState(&video_buffering_state_cb_,
1170 BUFFERING_HAVE_NOTHING),
1171 RunClosure<0>()));
1172 942
1173 if (state == kSeeking) { 943 if (state == kSeeking) {
1174 if (stop_or_error == kStop) { 944 if (stop_or_error == kStop) {
1175 EXPECT_CALL(*demuxer_, Seek(_, _)) 945 EXPECT_CALL(*demuxer_, Seek(_, _))
1176 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), 946 .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
1177 RunCallback<1>(PIPELINE_OK))); 947 RunCallback<1>(PIPELINE_OK)));
1178 } else { 948 } else {
1179 status = PIPELINE_ERROR_READ; 949 status = PIPELINE_ERROR_READ;
1180 EXPECT_CALL(*demuxer_, Seek(_, _)) 950 EXPECT_CALL(*demuxer_, Seek(_, _))
1181 .WillOnce(RunCallback<1>(status)); 951 .WillOnce(RunCallback<1>(status));
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 989
1220 DISALLOW_COPY_AND_ASSIGN(PipelineTeardownTest); 990 DISALLOW_COPY_AND_ASSIGN(PipelineTeardownTest);
1221 }; 991 };
1222 992
1223 #define INSTANTIATE_TEARDOWN_TEST(stop_or_error, state) \ 993 #define INSTANTIATE_TEARDOWN_TEST(stop_or_error, state) \
1224 TEST_F(PipelineTeardownTest, stop_or_error##_##state) { \ 994 TEST_F(PipelineTeardownTest, stop_or_error##_##state) { \
1225 RunTest(k##state, k##stop_or_error); \ 995 RunTest(k##state, k##stop_or_error); \
1226 } 996 }
1227 997
1228 INSTANTIATE_TEARDOWN_TEST(Stop, InitDemuxer); 998 INSTANTIATE_TEARDOWN_TEST(Stop, InitDemuxer);
1229 INSTANTIATE_TEARDOWN_TEST(Stop, InitAudioRenderer); 999 INSTANTIATE_TEARDOWN_TEST(Stop, InitRenderer);
1230 INSTANTIATE_TEARDOWN_TEST(Stop, InitVideoRenderer);
1231 INSTANTIATE_TEARDOWN_TEST(Stop, Flushing); 1000 INSTANTIATE_TEARDOWN_TEST(Stop, Flushing);
1232 INSTANTIATE_TEARDOWN_TEST(Stop, Seeking); 1001 INSTANTIATE_TEARDOWN_TEST(Stop, Seeking);
1233 INSTANTIATE_TEARDOWN_TEST(Stop, Playing); 1002 INSTANTIATE_TEARDOWN_TEST(Stop, Playing);
1234 1003
1235 INSTANTIATE_TEARDOWN_TEST(Error, InitDemuxer); 1004 INSTANTIATE_TEARDOWN_TEST(Error, InitDemuxer);
1236 INSTANTIATE_TEARDOWN_TEST(Error, InitAudioRenderer); 1005 INSTANTIATE_TEARDOWN_TEST(Error, InitRenderer);
1237 INSTANTIATE_TEARDOWN_TEST(Error, InitVideoRenderer);
1238 INSTANTIATE_TEARDOWN_TEST(Error, Flushing); 1006 INSTANTIATE_TEARDOWN_TEST(Error, Flushing);
1239 INSTANTIATE_TEARDOWN_TEST(Error, Seeking); 1007 INSTANTIATE_TEARDOWN_TEST(Error, Seeking);
1240 INSTANTIATE_TEARDOWN_TEST(Error, Playing); 1008 INSTANTIATE_TEARDOWN_TEST(Error, Playing);
1241 1009
1242 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing); 1010 INSTANTIATE_TEARDOWN_TEST(ErrorAndStop, Playing);
1243 1011
1244 } // namespace media 1012 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698