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

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

Issue 6686061: PipelineError is dead. Long live PipelineStatus! (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: responses to 2nd CR Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/base/pipeline_impl.cc ('k') | media/base/pipeline_status.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <string> 5 #include <string>
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/stl_util-inl.h" 8 #include "base/stl_util-inl.h"
9 #include "base/threading/simple_thread.h"
9 #include "media/base/pipeline_impl.h" 10 #include "media/base/pipeline_impl.h"
10 #include "media/base/media_format.h" 11 #include "media/base/media_format.h"
11 #include "media/base/filters.h" 12 #include "media/base/filters.h"
12 #include "media/base/filter_host.h" 13 #include "media/base/filter_host.h"
13 #include "media/base/mock_callback.h" 14 #include "media/base/mock_callback.h"
14 #include "media/base/mock_filters.h" 15 #include "media/base/mock_filters.h"
15 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
16 17
17 using ::testing::_; 18 using ::testing::_;
18 using ::testing::DeleteArg; 19 using ::testing::DeleteArg;
(...skipping 13 matching lines...) Expand all
32 // Buffered bytes of the data source. 33 // Buffered bytes of the data source.
33 static const int kBufferedBytes = 1024; 34 static const int kBufferedBytes = 1024;
34 35
35 // Used for setting expectations on pipeline callbacks. Using a StrictMock 36 // Used for setting expectations on pipeline callbacks. Using a StrictMock
36 // also lets us test for missing callbacks. 37 // also lets us test for missing callbacks.
37 class CallbackHelper { 38 class CallbackHelper {
38 public: 39 public:
39 CallbackHelper() {} 40 CallbackHelper() {}
40 virtual ~CallbackHelper() {} 41 virtual ~CallbackHelper() {}
41 42
42 MOCK_METHOD0(OnStart, void()); 43 MOCK_METHOD1(OnStart, void(PipelineStatus));
43 MOCK_METHOD0(OnSeek, void()); 44 MOCK_METHOD1(OnSeek, void(PipelineStatus));
44 MOCK_METHOD0(OnStop, void()); 45 MOCK_METHOD1(OnStop, void(PipelineStatus));
45 MOCK_METHOD0(OnEnded, void()); 46 MOCK_METHOD1(OnEnded, void(PipelineStatus));
46 MOCK_METHOD0(OnError, void()); 47 MOCK_METHOD1(OnError, void(PipelineStatus));
47 48
48 private: 49 private:
49 DISALLOW_COPY_AND_ASSIGN(CallbackHelper); 50 DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
50 }; 51 };
51 52
52 // TODO(scherkus): even though some filters are initialized on separate 53 // TODO(scherkus): even though some filters are initialized on separate
53 // threads these test aren't flaky... why? It's because filters' Initialize() 54 // threads these test aren't flaky... why? It's because filters' Initialize()
54 // is executed on |message_loop_| and the mock filters instantly call 55 // is executed on |message_loop_| and the mock filters instantly call
55 // InitializationComplete(), which keeps the pipeline humming along. If 56 // InitializationComplete(), which keeps the pipeline humming along. If
56 // either filters don't call InitializationComplete() immediately or filter 57 // either filters don't call InitializationComplete() immediately or filter
57 // initialization is moved to a separate thread this test will become flaky. 58 // initialization is moved to a separate thread this test will become flaky.
58 class PipelineImplTest : public ::testing::Test { 59 class PipelineImplTest : public ::testing::Test {
59 public: 60 public:
60 PipelineImplTest() 61 PipelineImplTest()
61 : pipeline_(new PipelineImpl(&message_loop_)) { 62 : pipeline_(new PipelineImpl(&message_loop_)) {
62 pipeline_->Init( 63 pipeline_->Init(
63 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), 64 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_),
64 &CallbackHelper::OnEnded), 65 &CallbackHelper::OnEnded),
65 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), 66 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_),
66 &CallbackHelper::OnError), 67 &CallbackHelper::OnError),
67 NULL); 68 static_cast<PipelineStatusCallback*>(NULL));
68 mocks_.reset(new MockFilterCollection()); 69 mocks_.reset(new MockFilterCollection());
69 } 70 }
70 71
71 virtual ~PipelineImplTest() { 72 virtual ~PipelineImplTest() {
72 if (!pipeline_->IsRunning()) { 73 if (!pipeline_->IsRunning()) {
73 return; 74 return;
74 } 75 }
75 76
76 // Expect a stop callback if we were started. 77 // Expect a stop callback if we were started.
77 EXPECT_CALL(callbacks_, OnStop()); 78 EXPECT_CALL(callbacks_, OnStop(PIPELINE_OK));
78 pipeline_->Stop(NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), 79 pipeline_->Stop(NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_),
79 &CallbackHelper::OnStop)); 80 &CallbackHelper::OnStop));
80 message_loop_.RunAllPending(); 81 message_loop_.RunAllPending();
81 82
82 mocks_.reset(); 83 mocks_.reset();
83 } 84 }
84 85
85 protected: 86 protected:
86 // Sets up expectations to allow the demuxer to initialize. 87 // Sets up expectations to allow the demuxer to initialize.
87 typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector; 88 typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 .WillOnce(Invoke(&RunFilterCallback)); 168 .WillOnce(Invoke(&RunFilterCallback));
168 EXPECT_CALL(*mocks_->audio_renderer(), Stop(NotNull())) 169 EXPECT_CALL(*mocks_->audio_renderer(), Stop(NotNull()))
169 .WillOnce(Invoke(&RunStopFilterCallback)); 170 .WillOnce(Invoke(&RunStopFilterCallback));
170 } 171 }
171 172
172 // Sets up expectations on the callback and initializes the pipeline. Called 173 // Sets up expectations on the callback and initializes the pipeline. Called
173 // after tests have set expectations any filters they wish to use. 174 // after tests have set expectations any filters they wish to use.
174 void InitializePipeline() { 175 void InitializePipeline() {
175 InitializePipeline(PIPELINE_OK); 176 InitializePipeline(PIPELINE_OK);
176 } 177 }
177 178 // Most tests can expect the |filter_collection|'s |build_status| to get
178 void InitializePipeline(PipelineError factory_error) { 179 // reflected in |Start()|'s argument.
180 void InitializePipeline(PipelineStatus start_status) {
181 InitializePipeline(start_status, start_status);
182 }
183 // But some tests require different statuses in build & Start.
184 void InitializePipeline(PipelineStatus build_status,
185 PipelineStatus start_status) {
179 // Expect an initialization callback. 186 // Expect an initialization callback.
180 EXPECT_CALL(callbacks_, OnStart()); 187 EXPECT_CALL(callbacks_, OnStart(start_status));
181 pipeline_->Start(mocks_->filter_collection(true, true, factory_error), 188 pipeline_->Start(mocks_->filter_collection(true, true, build_status), "",
182 "",
183 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), 189 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_),
184 &CallbackHelper::OnStart)); 190 &CallbackHelper::OnStart));
185 message_loop_.RunAllPending(); 191 message_loop_.RunAllPending();
186 } 192 }
187 193
188 void CreateAudioStream() { 194 void CreateAudioStream() {
189 audio_stream_ = CreateStream(DemuxerStream::AUDIO); 195 audio_stream_ = CreateStream(DemuxerStream::AUDIO);
190 } 196 }
191 197
192 void CreateVideoStream() { 198 void CreateVideoStream() {
(...skipping 21 matching lines...) Expand all
214 } 220 }
215 221
216 if (video_stream_) { 222 if (video_stream_) {
217 EXPECT_CALL(*mocks_->video_decoder(), Seek(seek_time, NotNull())) 223 EXPECT_CALL(*mocks_->video_decoder(), Seek(seek_time, NotNull()))
218 .WillOnce(Invoke(&RunFilterCallback)); 224 .WillOnce(Invoke(&RunFilterCallback));
219 EXPECT_CALL(*mocks_->video_renderer(), Seek(seek_time, NotNull())) 225 EXPECT_CALL(*mocks_->video_renderer(), Seek(seek_time, NotNull()))
220 .WillOnce(Invoke(&RunFilterCallback)); 226 .WillOnce(Invoke(&RunFilterCallback));
221 } 227 }
222 228
223 // We expect a successful seek callback. 229 // We expect a successful seek callback.
224 EXPECT_CALL(callbacks_, OnSeek()); 230 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK));
225 231
226 } 232 }
227 233
228 void DoSeek(const base::TimeDelta& seek_time) { 234 void DoSeek(const base::TimeDelta& seek_time) {
229 pipeline_->Seek(seek_time, 235 pipeline_->Seek(seek_time,
230 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), 236 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_),
231 &CallbackHelper::OnSeek)); 237 &CallbackHelper::OnSeek));
232 238
233 // We expect the time to be updated only after the seek has completed. 239 // We expect the time to be updated only after the seek has completed.
234 EXPECT_NE(seek_time, pipeline_->GetCurrentTime()); 240 EXPECT_NE(seek_time, pipeline_->GetCurrentTime());
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 292
287 EXPECT_EQ(0, pipeline_->GetBufferedBytes()); 293 EXPECT_EQ(0, pipeline_->GetBufferedBytes());
288 EXPECT_EQ(0, pipeline_->GetTotalBytes()); 294 EXPECT_EQ(0, pipeline_->GetTotalBytes());
289 295
290 // Should always get set to zero. 296 // Should always get set to zero.
291 size_t width = 1u; 297 size_t width = 1u;
292 size_t height = 1u; 298 size_t height = 1u;
293 pipeline_->GetVideoSize(&width, &height); 299 pipeline_->GetVideoSize(&width, &height);
294 EXPECT_EQ(0u, width); 300 EXPECT_EQ(0u, width);
295 EXPECT_EQ(0u, height); 301 EXPECT_EQ(0u, height);
296
297 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError());
298 } 302 }
299 303
300 TEST_F(PipelineImplTest, NeverInitializes) { 304 TEST_F(PipelineImplTest, NeverInitializes) {
301 // This test hangs during initialization by never calling 305 // This test hangs during initialization by never calling
302 // InitializationComplete(). StrictMock<> will ensure that the callback is 306 // InitializationComplete(). StrictMock<> will ensure that the callback is
303 // never executed. 307 // never executed.
304 pipeline_->Start(mocks_->filter_collection(false, false, PIPELINE_OK), "", 308 pipeline_->Start(mocks_->filter_collection(false, false, PIPELINE_OK), "",
305 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), 309 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_),
306 &CallbackHelper::OnStart)); 310 &CallbackHelper::OnStart));
307 message_loop_.RunAllPending(); 311 message_loop_.RunAllPending();
308 312
309 EXPECT_FALSE(pipeline_->IsInitialized()); 313 EXPECT_FALSE(pipeline_->IsInitialized());
310 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError());
311 314
312 // Because our callback will get executed when the test tears down, we'll 315 // Because our callback will get executed when the test tears down, we'll
313 // verify that nothing has been called, then set our expectation for the call 316 // verify that nothing has been called, then set our expectation for the call
314 // made during tear down. 317 // made during tear down.
315 Mock::VerifyAndClear(&callbacks_); 318 Mock::VerifyAndClear(&callbacks_);
316 EXPECT_CALL(callbacks_, OnStart()); 319 EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK));
317 } 320 }
318 321
319 TEST_F(PipelineImplTest, RequiredFilterMissing) { 322 TEST_F(PipelineImplTest, RequiredFilterMissing) {
320 EXPECT_CALL(callbacks_, OnError()); 323 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING));
321 324
322 // Sets up expectations on the callback and initializes the pipeline. Called 325 // Sets up expectations on the callback and initializes the pipeline. Called
323 // after tests have set expectations any filters they wish to use. 326 // after tests have set expectations any filters they wish to use.
324 // Expect an initialization callback. 327 // Expect an initialization callback.
325 EXPECT_CALL(callbacks_, OnStart()); 328 EXPECT_CALL(callbacks_, OnStart(PIPELINE_ERROR_REQUIRED_FILTER_MISSING));
326 329
327 // Create a filter collection with missing filter. 330 // Create a filter collection with missing filter.
328 FilterCollection* collection = 331 FilterCollection* collection =
329 mocks_->filter_collection(false, true, 332 mocks_->filter_collection(false, true,
330 PIPELINE_ERROR_REQUIRED_FILTER_MISSING); 333 PIPELINE_ERROR_REQUIRED_FILTER_MISSING);
331 pipeline_->Start(collection, "", 334 pipeline_->Start(collection, "",
332 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_), 335 NewCallback(reinterpret_cast<CallbackHelper*>(&callbacks_),
333 &CallbackHelper::OnStart)); 336 &CallbackHelper::OnStart));
334 message_loop_.RunAllPending(); 337 message_loop_.RunAllPending();
335 338
336 EXPECT_FALSE(pipeline_->IsInitialized()); 339 EXPECT_FALSE(pipeline_->IsInitialized());
337 EXPECT_EQ(PIPELINE_ERROR_REQUIRED_FILTER_MISSING,
338 pipeline_->GetError());
339 } 340 }
340 341
341 TEST_F(PipelineImplTest, URLNotFound) { 342 TEST_F(PipelineImplTest, URLNotFound) {
342 343 // TODO(acolwell,fischman): Since OnStart() is getting called with an error
343 EXPECT_CALL(callbacks_, OnError()); 344 // code already, OnError() doesn't also need to get called. Fix the pipeline
344 345 // (and it's consumers!) so that OnError doesn't need to be called after
346 // another callback has already reported the error. Same applies to NoStreams
347 // below.
348 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_URL_NOT_FOUND));
345 InitializePipeline(PIPELINE_ERROR_URL_NOT_FOUND); 349 InitializePipeline(PIPELINE_ERROR_URL_NOT_FOUND);
346 EXPECT_FALSE(pipeline_->IsInitialized()); 350 EXPECT_FALSE(pipeline_->IsInitialized());
347 EXPECT_EQ(PIPELINE_ERROR_URL_NOT_FOUND, pipeline_->GetError());
348 } 351 }
349 352
350 TEST_F(PipelineImplTest, NoStreams) { 353 TEST_F(PipelineImplTest, NoStreams) {
351 // Manually set these expectations because SetPlaybackRate() is not called if 354 // Manually set these expectations because SetPlaybackRate() is not called if
352 // we cannot fully initialize the pipeline. 355 // we cannot fully initialize the pipeline.
353 EXPECT_CALL(*mocks_->demuxer(), GetNumberOfStreams()) 356 EXPECT_CALL(*mocks_->demuxer(), GetNumberOfStreams())
354 .WillRepeatedly(Return(0)); 357 .WillRepeatedly(Return(0));
355 EXPECT_CALL(*mocks_->demuxer(), Stop(NotNull())) 358 EXPECT_CALL(*mocks_->demuxer(), Stop(NotNull()))
356 .WillOnce(Invoke(&RunStopFilterCallback)); 359 .WillOnce(Invoke(&RunStopFilterCallback));
357 EXPECT_CALL(callbacks_, OnError()); 360 // TODO(acolwell,fischman): see TODO in URLNotFound above.
361 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_COULD_NOT_RENDER));
358 362
359 InitializePipeline(); 363 InitializePipeline(PIPELINE_OK, PIPELINE_ERROR_COULD_NOT_RENDER);
360 EXPECT_FALSE(pipeline_->IsInitialized()); 364 EXPECT_FALSE(pipeline_->IsInitialized());
361 EXPECT_EQ(PIPELINE_ERROR_COULD_NOT_RENDER, pipeline_->GetError());
362 } 365 }
363 366
364 TEST_F(PipelineImplTest, AudioStream) { 367 TEST_F(PipelineImplTest, AudioStream) {
365 CreateAudioStream(); 368 CreateAudioStream();
366 MockDemuxerStreamVector streams; 369 MockDemuxerStreamVector streams;
367 streams.push_back(audio_stream()); 370 streams.push_back(audio_stream());
368 371
369 InitializeDemuxer(&streams, base::TimeDelta()); 372 InitializeDemuxer(&streams, base::TimeDelta());
370 InitializeAudioDecoder(audio_stream()); 373 InitializeAudioDecoder(audio_stream());
371 InitializeAudioRenderer(); 374 InitializeAudioRenderer();
372 375
373 InitializePipeline(); 376 InitializePipeline(PIPELINE_OK);
374 EXPECT_TRUE(pipeline_->IsInitialized()); 377 EXPECT_TRUE(pipeline_->IsInitialized());
375 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError());
376 EXPECT_TRUE(pipeline_->HasAudio()); 378 EXPECT_TRUE(pipeline_->HasAudio());
377 EXPECT_FALSE(pipeline_->HasVideo()); 379 EXPECT_FALSE(pipeline_->HasVideo());
378 } 380 }
379 381
380 TEST_F(PipelineImplTest, VideoStream) { 382 TEST_F(PipelineImplTest, VideoStream) {
381 CreateVideoStream(); 383 CreateVideoStream();
382 MockDemuxerStreamVector streams; 384 MockDemuxerStreamVector streams;
383 streams.push_back(video_stream()); 385 streams.push_back(video_stream());
384 386
385 InitializeDemuxer(&streams, base::TimeDelta()); 387 InitializeDemuxer(&streams, base::TimeDelta());
386 InitializeVideoDecoder(video_stream()); 388 InitializeVideoDecoder(video_stream());
387 InitializeVideoRenderer(); 389 InitializeVideoRenderer();
388 390
389 InitializePipeline(); 391 InitializePipeline(PIPELINE_OK);
390 EXPECT_TRUE(pipeline_->IsInitialized()); 392 EXPECT_TRUE(pipeline_->IsInitialized());
391 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError());
392 EXPECT_FALSE(pipeline_->HasAudio()); 393 EXPECT_FALSE(pipeline_->HasAudio());
393 EXPECT_TRUE(pipeline_->HasVideo()); 394 EXPECT_TRUE(pipeline_->HasVideo());
394 } 395 }
395 396
396 TEST_F(PipelineImplTest, AudioVideoStream) { 397 TEST_F(PipelineImplTest, AudioVideoStream) {
397 CreateAudioStream(); 398 CreateAudioStream();
398 CreateVideoStream(); 399 CreateVideoStream();
399 MockDemuxerStreamVector streams; 400 MockDemuxerStreamVector streams;
400 streams.push_back(audio_stream()); 401 streams.push_back(audio_stream());
401 streams.push_back(video_stream()); 402 streams.push_back(video_stream());
402 403
403 InitializeDemuxer(&streams, base::TimeDelta()); 404 InitializeDemuxer(&streams, base::TimeDelta());
404 InitializeAudioDecoder(audio_stream()); 405 InitializeAudioDecoder(audio_stream());
405 InitializeAudioRenderer(); 406 InitializeAudioRenderer();
406 InitializeVideoDecoder(video_stream()); 407 InitializeVideoDecoder(video_stream());
407 InitializeVideoRenderer(); 408 InitializeVideoRenderer();
408 409
409 InitializePipeline(); 410 InitializePipeline(PIPELINE_OK);
410 EXPECT_TRUE(pipeline_->IsInitialized()); 411 EXPECT_TRUE(pipeline_->IsInitialized());
411 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError());
412 EXPECT_TRUE(pipeline_->HasAudio()); 412 EXPECT_TRUE(pipeline_->HasAudio());
413 EXPECT_TRUE(pipeline_->HasVideo()); 413 EXPECT_TRUE(pipeline_->HasVideo());
414 } 414 }
415 415
416 TEST_F(PipelineImplTest, Seek) { 416 TEST_F(PipelineImplTest, Seek) {
417 CreateAudioStream(); 417 CreateAudioStream();
418 CreateVideoStream(); 418 CreateVideoStream();
419 MockDemuxerStreamVector streams; 419 MockDemuxerStreamVector streams;
420 streams.push_back(audio_stream()); 420 streams.push_back(audio_stream());
421 streams.push_back(video_stream()); 421 streams.push_back(video_stream());
422 422
423 InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(3000)); 423 InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(3000));
424 InitializeAudioDecoder(audio_stream()); 424 InitializeAudioDecoder(audio_stream());
425 InitializeAudioRenderer(); 425 InitializeAudioRenderer();
426 InitializeVideoDecoder(video_stream()); 426 InitializeVideoDecoder(video_stream());
427 InitializeVideoRenderer(); 427 InitializeVideoRenderer();
428 428
429 // Every filter should receive a call to Seek(). 429 // Every filter should receive a call to Seek().
430 base::TimeDelta expected = base::TimeDelta::FromSeconds(2000); 430 base::TimeDelta expected = base::TimeDelta::FromSeconds(2000);
431 ExpectSeek(expected); 431 ExpectSeek(expected);
432 432
433 // Initialize then seek! 433 // Initialize then seek!
434 InitializePipeline(); 434 InitializePipeline(PIPELINE_OK);
435 DoSeek(expected); 435 DoSeek(expected);
436 } 436 }
437 437
438 TEST_F(PipelineImplTest, SetVolume) { 438 TEST_F(PipelineImplTest, SetVolume) {
439 CreateAudioStream(); 439 CreateAudioStream();
440 MockDemuxerStreamVector streams; 440 MockDemuxerStreamVector streams;
441 streams.push_back(audio_stream()); 441 streams.push_back(audio_stream());
442 442
443 InitializeDemuxer(&streams, base::TimeDelta()); 443 InitializeDemuxer(&streams, base::TimeDelta());
444 InitializeAudioDecoder(audio_stream()); 444 InitializeAudioDecoder(audio_stream());
445 InitializeAudioRenderer(); 445 InitializeAudioRenderer();
446 446
447 // The audio renderer should receive a call to SetVolume(). 447 // The audio renderer should receive a call to SetVolume().
448 float expected = 0.5f; 448 float expected = 0.5f;
449 EXPECT_CALL(*mocks_->audio_renderer(), SetVolume(expected)); 449 EXPECT_CALL(*mocks_->audio_renderer(), SetVolume(expected));
450 450
451 // Initialize then set volume! 451 // Initialize then set volume!
452 InitializePipeline(); 452 InitializePipeline(PIPELINE_OK);
453 pipeline_->SetVolume(expected); 453 pipeline_->SetVolume(expected);
454 } 454 }
455 455
456 TEST_F(PipelineImplTest, Properties) { 456 TEST_F(PipelineImplTest, Properties) {
457 CreateVideoStream(); 457 CreateVideoStream();
458 MockDemuxerStreamVector streams; 458 MockDemuxerStreamVector streams;
459 streams.push_back(video_stream()); 459 streams.push_back(video_stream());
460 460
461 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); 461 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100);
462 InitializeDemuxer(&streams, kDuration); 462 InitializeDemuxer(&streams, kDuration);
463 InitializeVideoDecoder(video_stream()); 463 InitializeVideoDecoder(video_stream());
464 InitializeVideoRenderer(); 464 InitializeVideoRenderer();
465 465
466 InitializePipeline(); 466 InitializePipeline(PIPELINE_OK);
467 EXPECT_TRUE(pipeline_->IsInitialized()); 467 EXPECT_TRUE(pipeline_->IsInitialized());
468 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError());
469 EXPECT_EQ(kDuration.ToInternalValue(), 468 EXPECT_EQ(kDuration.ToInternalValue(),
470 pipeline_->GetMediaDuration().ToInternalValue()); 469 pipeline_->GetMediaDuration().ToInternalValue());
471 EXPECT_EQ(kTotalBytes, pipeline_->GetTotalBytes()); 470 EXPECT_EQ(kTotalBytes, pipeline_->GetTotalBytes());
472 EXPECT_EQ(kBufferedBytes, pipeline_->GetBufferedBytes()); 471 EXPECT_EQ(kBufferedBytes, pipeline_->GetBufferedBytes());
473 472
474 // Because kTotalBytes and kBufferedBytes are equal to each other, 473 // Because kTotalBytes and kBufferedBytes are equal to each other,
475 // the entire video should be buffered. 474 // the entire video should be buffered.
476 EXPECT_EQ(kDuration.ToInternalValue(), 475 EXPECT_EQ(kDuration.ToInternalValue(),
477 pipeline_->GetBufferedTime().ToInternalValue()); 476 pipeline_->GetBufferedTime().ToInternalValue());
478 } 477 }
479 478
480 TEST_F(PipelineImplTest, GetBufferedTime) { 479 TEST_F(PipelineImplTest, GetBufferedTime) {
481 CreateVideoStream(); 480 CreateVideoStream();
482 MockDemuxerStreamVector streams; 481 MockDemuxerStreamVector streams;
483 streams.push_back(video_stream()); 482 streams.push_back(video_stream());
484 483
485 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); 484 const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100);
486 InitializeDemuxer(&streams, kDuration); 485 InitializeDemuxer(&streams, kDuration);
487 InitializeVideoDecoder(video_stream()); 486 InitializeVideoDecoder(video_stream());
488 InitializeVideoRenderer(); 487 InitializeVideoRenderer();
489 488
490 InitializePipeline(); 489 InitializePipeline(PIPELINE_OK);
491 EXPECT_TRUE(pipeline_->IsInitialized()); 490 EXPECT_TRUE(pipeline_->IsInitialized());
492 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError());
493 491
494 // TODO(vrk): The following mini-test cases are order-dependent, and should 492 // TODO(vrk): The following mini-test cases are order-dependent, and should
495 // probably be separated into independent test cases. 493 // probably be separated into independent test cases.
496 494
497 // Buffered time is 0 if no bytes are buffered. 495 // Buffered time is 0 if no bytes are buffered.
498 pipeline_->SetBufferedBytes(0); 496 pipeline_->SetBufferedBytes(0);
499 EXPECT_EQ(0, pipeline_->GetBufferedTime().ToInternalValue()); 497 EXPECT_EQ(0, pipeline_->GetBufferedTime().ToInternalValue());
500 498
501 // We should return buffered_time_ if it is set, valid and less than 499 // We should return buffered_time_ if it is set, valid and less than
502 // the current time. 500 // the current time.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 MockDemuxerStreamVector streams; 548 MockDemuxerStreamVector streams;
551 streams.push_back(audio_stream()); 549 streams.push_back(audio_stream());
552 streams.push_back(video_stream()); 550 streams.push_back(video_stream());
553 551
554 InitializeDemuxer(&streams, base::TimeDelta()); 552 InitializeDemuxer(&streams, base::TimeDelta());
555 InitializeAudioDecoder(audio_stream()); 553 InitializeAudioDecoder(audio_stream());
556 InitializeAudioRenderer(); 554 InitializeAudioRenderer();
557 InitializeVideoDecoder(video_stream()); 555 InitializeVideoDecoder(video_stream());
558 InitializeVideoRenderer(); 556 InitializeVideoRenderer();
559 557
560 InitializePipeline(); 558 InitializePipeline(PIPELINE_OK);
561 EXPECT_TRUE(pipeline_->IsInitialized()); 559 EXPECT_TRUE(pipeline_->IsInitialized());
562 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError());
563 EXPECT_TRUE(pipeline_->HasAudio()); 560 EXPECT_TRUE(pipeline_->HasAudio());
564 EXPECT_TRUE(pipeline_->HasVideo()); 561 EXPECT_TRUE(pipeline_->HasVideo());
565 562
566 EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(1.0f)) 563 EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(1.0f))
567 .WillOnce(DisableAudioRenderer(mocks_->audio_renderer())); 564 .WillOnce(DisableAudioRenderer(mocks_->audio_renderer()));
568 EXPECT_CALL(*mocks_->demuxer(), 565 EXPECT_CALL(*mocks_->demuxer(),
569 OnAudioRendererDisabled()); 566 OnAudioRendererDisabled());
570 EXPECT_CALL(*mocks_->audio_decoder(), 567 EXPECT_CALL(*mocks_->audio_decoder(),
571 OnAudioRendererDisabled()); 568 OnAudioRendererDisabled());
572 EXPECT_CALL(*mocks_->audio_renderer(), 569 EXPECT_CALL(*mocks_->audio_renderer(),
573 OnAudioRendererDisabled()); 570 OnAudioRendererDisabled());
574 EXPECT_CALL(*mocks_->video_decoder(), 571 EXPECT_CALL(*mocks_->video_decoder(),
575 OnAudioRendererDisabled()); 572 OnAudioRendererDisabled());
576 EXPECT_CALL(*mocks_->video_renderer(), 573 EXPECT_CALL(*mocks_->video_renderer(),
577 OnAudioRendererDisabled()); 574 OnAudioRendererDisabled());
578 575
579 mocks_->audio_renderer()->SetPlaybackRate(1.0f); 576 mocks_->audio_renderer()->SetPlaybackRate(1.0f);
580 577
581 // Verify that ended event is fired when video ends. 578 // Verify that ended event is fired when video ends.
582 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) 579 EXPECT_CALL(*mocks_->video_renderer(), HasEnded())
583 .WillOnce(Return(true)); 580 .WillOnce(Return(true));
584 EXPECT_CALL(callbacks_, OnEnded()); 581 EXPECT_CALL(callbacks_, OnEnded(PIPELINE_OK));
585 FilterHost* host = pipeline_; 582 FilterHost* host = pipeline_;
586 host->NotifyEnded(); 583 host->NotifyEnded();
587 } 584 }
588 585
589 TEST_F(PipelineImplTest, DisableAudioRendererDuringInit) { 586 TEST_F(PipelineImplTest, DisableAudioRendererDuringInit) {
590 CreateAudioStream(); 587 CreateAudioStream();
591 CreateVideoStream(); 588 CreateVideoStream();
592 MockDemuxerStreamVector streams; 589 MockDemuxerStreamVector streams;
593 streams.push_back(audio_stream()); 590 streams.push_back(audio_stream());
594 streams.push_back(video_stream()); 591 streams.push_back(video_stream());
595 592
596 InitializeDemuxer(&streams, base::TimeDelta()); 593 InitializeDemuxer(&streams, base::TimeDelta());
597 InitializeAudioDecoder(audio_stream()); 594 InitializeAudioDecoder(audio_stream());
598 InitializeAudioRenderer(true); 595 InitializeAudioRenderer(true);
599 InitializeVideoDecoder(video_stream()); 596 InitializeVideoDecoder(video_stream());
600 InitializeVideoRenderer(); 597 InitializeVideoRenderer();
601 598
602 EXPECT_CALL(*mocks_->demuxer(), 599 EXPECT_CALL(*mocks_->demuxer(),
603 OnAudioRendererDisabled()); 600 OnAudioRendererDisabled());
604 EXPECT_CALL(*mocks_->audio_decoder(), 601 EXPECT_CALL(*mocks_->audio_decoder(),
605 OnAudioRendererDisabled()); 602 OnAudioRendererDisabled());
606 EXPECT_CALL(*mocks_->audio_renderer(), 603 EXPECT_CALL(*mocks_->audio_renderer(),
607 OnAudioRendererDisabled()); 604 OnAudioRendererDisabled());
608 EXPECT_CALL(*mocks_->video_decoder(), 605 EXPECT_CALL(*mocks_->video_decoder(),
609 OnAudioRendererDisabled()); 606 OnAudioRendererDisabled());
610 EXPECT_CALL(*mocks_->video_renderer(), 607 EXPECT_CALL(*mocks_->video_renderer(),
611 OnAudioRendererDisabled()); 608 OnAudioRendererDisabled());
612 609
613 InitializePipeline(); 610 InitializePipeline(PIPELINE_OK);
614 EXPECT_TRUE(pipeline_->IsInitialized()); 611 EXPECT_TRUE(pipeline_->IsInitialized());
615 EXPECT_EQ(PIPELINE_OK, pipeline_->GetError());
616 EXPECT_FALSE(pipeline_->HasAudio()); 612 EXPECT_FALSE(pipeline_->HasAudio());
617 EXPECT_TRUE(pipeline_->HasVideo()); 613 EXPECT_TRUE(pipeline_->HasVideo());
618 614
619 // Verify that ended event is fired when video ends. 615 // Verify that ended event is fired when video ends.
620 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) 616 EXPECT_CALL(*mocks_->video_renderer(), HasEnded())
621 .WillOnce(Return(true)); 617 .WillOnce(Return(true));
622 EXPECT_CALL(callbacks_, OnEnded()); 618 EXPECT_CALL(callbacks_, OnEnded(PIPELINE_OK));
623 FilterHost* host = pipeline_; 619 FilterHost* host = pipeline_;
624 host->NotifyEnded(); 620 host->NotifyEnded();
625 } 621 }
626 622
627 TEST_F(PipelineImplTest, EndedCallback) { 623 TEST_F(PipelineImplTest, EndedCallback) {
628 CreateAudioStream(); 624 CreateAudioStream();
629 CreateVideoStream(); 625 CreateVideoStream();
630 MockDemuxerStreamVector streams; 626 MockDemuxerStreamVector streams;
631 streams.push_back(audio_stream()); 627 streams.push_back(audio_stream());
632 streams.push_back(video_stream()); 628 streams.push_back(video_stream());
633 629
634 InitializeDemuxer(&streams, base::TimeDelta()); 630 InitializeDemuxer(&streams, base::TimeDelta());
635 InitializeAudioDecoder(audio_stream()); 631 InitializeAudioDecoder(audio_stream());
636 InitializeAudioRenderer(); 632 InitializeAudioRenderer();
637 InitializeVideoDecoder(video_stream()); 633 InitializeVideoDecoder(video_stream());
638 InitializeVideoRenderer(); 634 InitializeVideoRenderer();
639 InitializePipeline(); 635 InitializePipeline(PIPELINE_OK);
640 636
641 // For convenience to simulate filters calling the methods. 637 // For convenience to simulate filters calling the methods.
642 FilterHost* host = pipeline_; 638 FilterHost* host = pipeline_;
643 639
644 // Due to short circuit evaluation we only need to test a subset of cases. 640 // Due to short circuit evaluation we only need to test a subset of cases.
645 InSequence s; 641 InSequence s;
646 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) 642 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded())
647 .WillOnce(Return(false)); 643 .WillOnce(Return(false));
648 host->NotifyEnded(); 644 host->NotifyEnded();
649 645
650 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) 646 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded())
651 .WillOnce(Return(true)); 647 .WillOnce(Return(true));
652 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) 648 EXPECT_CALL(*mocks_->video_renderer(), HasEnded())
653 .WillOnce(Return(false)); 649 .WillOnce(Return(false));
654 host->NotifyEnded(); 650 host->NotifyEnded();
655 651
656 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) 652 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded())
657 .WillOnce(Return(true)); 653 .WillOnce(Return(true));
658 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) 654 EXPECT_CALL(*mocks_->video_renderer(), HasEnded())
659 .WillOnce(Return(true)); 655 .WillOnce(Return(true));
660 EXPECT_CALL(callbacks_, OnEnded()); 656 EXPECT_CALL(callbacks_, OnEnded(PIPELINE_OK));
661 host->NotifyEnded(); 657 host->NotifyEnded();
662 } 658 }
663 659
664 // Static function & time variable used to simulate changes in wallclock time. 660 // Static function & time variable used to simulate changes in wallclock time.
665 static int64 g_static_clock_time; 661 static int64 g_static_clock_time;
666 static base::Time StaticClockFunction() { 662 static base::Time StaticClockFunction() {
667 return base::Time::FromInternalValue(g_static_clock_time); 663 return base::Time::FromInternalValue(g_static_clock_time);
668 } 664 }
669 665
670 TEST_F(PipelineImplTest, AudioStreamShorterThanVideo) { 666 TEST_F(PipelineImplTest, AudioStreamShorterThanVideo) {
671 base::TimeDelta duration = base::TimeDelta::FromSeconds(10); 667 base::TimeDelta duration = base::TimeDelta::FromSeconds(10);
672 668
673 CreateAudioStream(); 669 CreateAudioStream();
674 CreateVideoStream(); 670 CreateVideoStream();
675 MockDemuxerStreamVector streams; 671 MockDemuxerStreamVector streams;
676 streams.push_back(audio_stream()); 672 streams.push_back(audio_stream());
677 streams.push_back(video_stream()); 673 streams.push_back(video_stream());
678 674
679 InitializeDemuxer(&streams, duration); 675 InitializeDemuxer(&streams, duration);
680 InitializeAudioDecoder(audio_stream()); 676 InitializeAudioDecoder(audio_stream());
681 InitializeAudioRenderer(); 677 InitializeAudioRenderer();
682 InitializeVideoDecoder(video_stream()); 678 InitializeVideoDecoder(video_stream());
683 InitializeVideoRenderer(); 679 InitializeVideoRenderer();
684 InitializePipeline(); 680 InitializePipeline(PIPELINE_OK);
685 681
686 // For convenience to simulate filters calling the methods. 682 // For convenience to simulate filters calling the methods.
687 FilterHost* host = pipeline_; 683 FilterHost* host = pipeline_;
688 684
689 // Replace the clock so we can simulate wallclock time advancing w/o using 685 // Replace the clock so we can simulate wallclock time advancing w/o using
690 // Sleep(). 686 // Sleep().
691 pipeline_->SetClockForTesting(new Clock(&StaticClockFunction)); 687 pipeline_->SetClockForTesting(new Clock(&StaticClockFunction));
692 688
693 EXPECT_EQ(0, host->GetTime().ToInternalValue()); 689 EXPECT_EQ(0, host->GetTime().ToInternalValue());
694 690
(...skipping 27 matching lines...) Expand all
722 start_time = host->GetTime().ToInternalValue(); 718 start_time = host->GetTime().ToInternalValue();
723 g_static_clock_time += 719 g_static_clock_time +=
724 base::TimeDelta::FromMilliseconds(100).ToInternalValue(); 720 base::TimeDelta::FromMilliseconds(100).ToInternalValue();
725 EXPECT_GT(host->GetTime().ToInternalValue(), start_time); 721 EXPECT_GT(host->GetTime().ToInternalValue(), start_time);
726 722
727 // Signal end of video stream and make sure OnEnded() callback occurs. 723 // Signal end of video stream and make sure OnEnded() callback occurs.
728 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded()) 724 EXPECT_CALL(*mocks_->audio_renderer(), HasEnded())
729 .WillOnce(Return(true)); 725 .WillOnce(Return(true));
730 EXPECT_CALL(*mocks_->video_renderer(), HasEnded()) 726 EXPECT_CALL(*mocks_->video_renderer(), HasEnded())
731 .WillOnce(Return(true)); 727 .WillOnce(Return(true));
732 EXPECT_CALL(callbacks_, OnEnded()); 728 EXPECT_CALL(callbacks_, OnEnded(PIPELINE_OK));
733 host->NotifyEnded(); 729 host->NotifyEnded();
734 } 730 }
735 731
736 TEST_F(PipelineImplTest, ErrorDuringSeek) { 732 TEST_F(PipelineImplTest, ErrorDuringSeek) {
737 CreateAudioStream(); 733 CreateAudioStream();
738 MockDemuxerStreamVector streams; 734 MockDemuxerStreamVector streams;
739 streams.push_back(audio_stream()); 735 streams.push_back(audio_stream());
740 736
741 InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(10)); 737 InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(10));
742 InitializeAudioDecoder(audio_stream()); 738 InitializeAudioDecoder(audio_stream());
743 InitializeAudioRenderer(); 739 InitializeAudioRenderer();
744 InitializePipeline(); 740 InitializePipeline(PIPELINE_OK);
745 741
746 float playback_rate = 1.0f; 742 float playback_rate = 1.0f;
747 EXPECT_CALL(*mocks_->demuxer(), SetPlaybackRate(playback_rate)); 743 EXPECT_CALL(*mocks_->demuxer(), SetPlaybackRate(playback_rate));
748 EXPECT_CALL(*mocks_->audio_decoder(), SetPlaybackRate(playback_rate)); 744 EXPECT_CALL(*mocks_->audio_decoder(), SetPlaybackRate(playback_rate));
749 EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(playback_rate)); 745 EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(playback_rate));
750 pipeline_->SetPlaybackRate(playback_rate); 746 pipeline_->SetPlaybackRate(playback_rate);
751 message_loop_.RunAllPending(); 747 message_loop_.RunAllPending();
752 748
753 InSequence s; 749 InSequence s;
754 750
755 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); 751 base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
756 752
757 EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, NotNull())) 753 EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, NotNull()))
758 .WillOnce(DoAll(SetError(mocks_->demuxer(), 754 .WillOnce(DoAll(SetError(mocks_->demuxer(),
759 PIPELINE_ERROR_READ), 755 PIPELINE_ERROR_READ),
760 Invoke(&RunFilterCallback))); 756 Invoke(&RunFilterCallback)));
761 757
762 pipeline_->Seek(seek_time, NewExpectedCallback()); 758 pipeline_->Seek(seek_time, NewCallback(
763 EXPECT_CALL(callbacks_, OnError()); 759 reinterpret_cast<CallbackHelper*>(&callbacks_), &CallbackHelper::OnSeek));
760 EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ));
761 EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ));
764 message_loop_.RunAllPending(); 762 message_loop_.RunAllPending();
765 } 763 }
766 764
765 class FlexibleCallbackRunner : public base::DelegateSimpleThread::Delegate {
766 public:
767 FlexibleCallbackRunner(int delayInMs, PipelineStatus status,
768 PipelineStatusCallback* callback)
769 : delayInMs_(delayInMs), status_(status), callback_(callback) {
770 if (delayInMs_ < 0) {
771 callback_->Run(status_);
772 return;
773 }
774 }
775 virtual void Run() {
776 if (delayInMs_ < 0) return;
777 base::PlatformThread::Sleep(delayInMs_);
778 callback_->Run(status_);
779 }
780
781 private:
782 int delayInMs_;
783 PipelineStatus status_;
784 PipelineStatusCallback* callback_;
785 };
786
787 void TestPipelineStatusNotification(int delayInMs) {
788 PipelineStatusNotification note;
789 // Arbitrary error value we expect to fish out of the notification after the
790 // callback is fired.
791 const PipelineStatus expected_error = PIPELINE_ERROR_URL_NOT_FOUND;
792 FlexibleCallbackRunner runner(delayInMs, expected_error, note.Callback());
793 base::DelegateSimpleThread thread(&runner, "FlexibleCallbackRunner");
794 thread.Start();
795 note.Wait();
796 EXPECT_EQ(note.status(), expected_error);
797 thread.Join();
798 }
799
800 // Test that in-line callback (same thread, no yield) works correctly.
801 TEST(PipelineStatusNotificationTest, InlineCallback) {
802 TestPipelineStatusNotification(-1);
803 }
804
805 // Test that different-thread, no-delay callback works correctly.
806 TEST(PipelineStatusNotificationTest, ImmediateCallback) {
807 TestPipelineStatusNotification(0);
808 }
809
810 // Test that different-thread, some-delay callback (the expected common case)
811 // works correctly.
812 TEST(PipelineStatusNotificationTest, DelayedCallback) {
813 TestPipelineStatusNotification(20);
814 }
815
767 } // namespace media 816 } // namespace media
OLDNEW
« no previous file with comments | « media/base/pipeline_impl.cc ('k') | media/base/pipeline_status.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698