Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "media/filters/pipeline_integration_test_base.h" | 5 #include "media/filters/pipeline_integration_test_base.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 11 #include "build/build_config.h" | 11 #include "build/build_config.h" |
| 12 #include "media/base/decoder_buffer.h" | 12 #include "media/base/decoder_buffer.h" |
| 13 #include "media/base/media_keys.h" | 13 #include "media/base/media_keys.h" |
| 14 #include "media/base/media_switches.h" | 14 #include "media/base/media_switches.h" |
| 15 #include "media/base/test_data_util.h" | 15 #include "media/base/test_data_util.h" |
| 16 #include "media/cdm/aes_decryptor.h" | 16 #include "media/cdm/aes_decryptor.h" |
| 17 #include "media/cdm/json_web_key.h" | 17 #include "media/cdm/json_web_key.h" |
| 18 #include "media/filters/chunk_demuxer.h" | 18 #include "media/filters/chunk_demuxer.h" |
| 19 | 19 |
| 20 using testing::_; | 20 using testing::_; |
| 21 using testing::AnyNumber; | 21 using testing::AnyNumber; |
| 22 using testing::AtMost; | 22 using testing::AtMost; |
| 23 using testing::SaveArg; | |
| 23 using testing::Values; | 24 using testing::Values; |
| 24 | 25 |
| 25 namespace media { | 26 namespace media { |
| 26 | 27 |
| 27 const char kSourceId[] = "SourceId"; | 28 const char kSourceId[] = "SourceId"; |
| 28 const uint8 kInitData[] = { 0x69, 0x6e, 0x69, 0x74 }; | 29 const uint8 kInitData[] = { 0x69, 0x6e, 0x69, 0x74 }; |
| 29 | 30 |
| 30 const char kWebM[] = "video/webm; codecs=\"vp8,vorbis\""; | 31 const char kWebM[] = "video/webm; codecs=\"vp8,vorbis\""; |
| 31 const char kWebMVP9[] = "video/webm; codecs=\"vp9\""; | 32 const char kWebMVP9[] = "video/webm; codecs=\"vp9\""; |
| 32 const char kAudioOnlyWebM[] = "video/webm; codecs=\"vorbis\""; | 33 const char kAudioOnlyWebM[] = "video/webm; codecs=\"vorbis\""; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 const int kVP9WebMFileDurationMs = 2736; | 67 const int kVP9WebMFileDurationMs = 2736; |
| 67 const int kVP8AWebMFileDurationMs = 2734; | 68 const int kVP8AWebMFileDurationMs = 2734; |
| 68 | 69 |
| 69 #if defined(USE_PROPRIETARY_CODECS) | 70 #if defined(USE_PROPRIETARY_CODECS) |
| 70 const int k640IsoFileDurationMs = 2737; | 71 const int k640IsoFileDurationMs = 2737; |
| 71 const int k640IsoCencFileDurationMs = 2736; | 72 const int k640IsoCencFileDurationMs = 2736; |
| 72 const int k1280IsoFileDurationMs = 2736; | 73 const int k1280IsoFileDurationMs = 2736; |
| 73 const int k1280IsoAVC3FileDurationMs = 2736; | 74 const int k1280IsoAVC3FileDurationMs = 2736; |
| 74 #endif // defined(USE_PROPRIETARY_CODECS) | 75 #endif // defined(USE_PROPRIETARY_CODECS) |
| 75 | 76 |
| 77 // Return a wallclock timeline offset for bear-320x240-live.webm. | |
| 78 static base::Time kLiveWallclockTimelineOffset() { | |
| 79 // The file contians the following UTC timeline offset: | |
| 80 // 2012-11-10 12:34:56.789123456 | |
| 81 // Since base::Time only has a resolution of microseconds, | |
| 82 // construct a base::Time for 2012-11-10 12:34:56.789123. | |
| 83 base::Time::Exploded exploded_time; | |
| 84 exploded_time.year = 2012; | |
| 85 exploded_time.month = 11; | |
| 86 exploded_time.day_of_month = 10; | |
| 87 exploded_time.hour = 12; | |
| 88 exploded_time.minute = 34; | |
| 89 exploded_time.second = 56; | |
| 90 exploded_time.millisecond = 789; | |
| 91 base::Time wallclock_time = base::Time::FromUTCExploded(exploded_time); | |
| 92 | |
| 93 wallclock_time += base::TimeDelta::FromMicroseconds(123); | |
| 94 | |
| 95 return wallclock_time; | |
| 96 } | |
| 97 | |
| 98 // FFmpeg only supports time a resolution of seconds so this | |
| 99 // helper function truncates a base::Time to seconds resolution. | |
| 100 static base::Time TruncateToFFmpegTimeResolution(base::Time t) { | |
| 101 base::Time::Exploded exploded_time; | |
| 102 t.UTCExplode(&exploded_time); | |
| 103 exploded_time.millisecond = 0; | |
| 104 | |
| 105 return base::Time::FromUTCExploded(exploded_time); | |
| 106 } | |
| 107 | |
| 76 // Note: Tests using this class only exercise the DecryptingDemuxerStream path. | 108 // Note: Tests using this class only exercise the DecryptingDemuxerStream path. |
| 77 // They do not exercise the Decrypting{Audio|Video}Decoder path. | 109 // They do not exercise the Decrypting{Audio|Video}Decoder path. |
| 78 class FakeEncryptedMedia { | 110 class FakeEncryptedMedia { |
| 79 public: | 111 public: |
| 80 // Defines the behavior of the "app" that responds to EME events. | 112 // Defines the behavior of the "app" that responds to EME events. |
| 81 class AppBase { | 113 class AppBase { |
| 82 public: | 114 public: |
| 83 virtual ~AppBase() {} | 115 virtual ~AppBase() {} |
| 84 | 116 |
| 85 virtual void OnSessionCreated(uint32 session_id, | 117 virtual void OnSessionCreated(uint32 session_id, |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 402 // (Mock)MediaSource (which are TEST_P, not TEST_F). If true, | 434 // (Mock)MediaSource (which are TEST_P, not TEST_F). If true, |
| 403 // LegacyFrameProcessor is used. Otherwise, (not yet supported), a more | 435 // LegacyFrameProcessor is used. Otherwise, (not yet supported), a more |
| 404 // compliant frame processor is used. | 436 // compliant frame processor is used. |
| 405 // TODO(wolenetz): Enable usage of new frame processor based on this flag. | 437 // TODO(wolenetz): Enable usage of new frame processor based on this flag. |
| 406 // See http://crbug.com/249422. | 438 // See http://crbug.com/249422. |
| 407 class PipelineIntegrationTest | 439 class PipelineIntegrationTest |
| 408 : public testing::TestWithParam<bool>, | 440 : public testing::TestWithParam<bool>, |
| 409 public PipelineIntegrationTestBase { | 441 public PipelineIntegrationTestBase { |
| 410 public: | 442 public: |
| 411 void StartPipelineWithMediaSource(MockMediaSource* source) { | 443 void StartPipelineWithMediaSource(MockMediaSource* source) { |
| 412 EXPECT_CALL(*this, OnMetadata(_)).Times(AtMost(1)); | 444 EXPECT_CALL(*this, OnMetadata(_)).Times(AtMost(1)) |
| 445 .WillRepeatedly(SaveArg<0>(&metadata_)); | |
| 413 EXPECT_CALL(*this, OnPrerollCompleted()).Times(AtMost(1)); | 446 EXPECT_CALL(*this, OnPrerollCompleted()).Times(AtMost(1)); |
| 414 pipeline_->Start( | 447 pipeline_->Start( |
| 415 CreateFilterCollection(source->GetDemuxer(), NULL), | 448 CreateFilterCollection(source->GetDemuxer(), NULL), |
| 416 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)), | 449 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)), |
| 417 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)), | 450 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)), |
| 418 QuitOnStatusCB(PIPELINE_OK), | 451 QuitOnStatusCB(PIPELINE_OK), |
| 419 base::Bind(&PipelineIntegrationTest::OnMetadata, | 452 base::Bind(&PipelineIntegrationTest::OnMetadata, |
| 420 base::Unretained(this)), | 453 base::Unretained(this)), |
| 421 base::Bind(&PipelineIntegrationTest::OnPrerollCompleted, | 454 base::Bind(&PipelineIntegrationTest::OnPrerollCompleted, |
| 422 base::Unretained(this)), | 455 base::Unretained(this)), |
| 423 base::Closure()); | 456 base::Closure()); |
| 424 | 457 |
| 425 message_loop_.Run(); | 458 message_loop_.Run(); |
| 426 } | 459 } |
| 427 | 460 |
| 428 void StartHashedPipelineWithMediaSource(MockMediaSource* source) { | 461 void StartHashedPipelineWithMediaSource(MockMediaSource* source) { |
| 429 hashing_enabled_ = true; | 462 hashing_enabled_ = true; |
| 430 StartPipelineWithMediaSource(source); | 463 StartPipelineWithMediaSource(source); |
| 431 } | 464 } |
| 432 | 465 |
| 433 void StartPipelineWithEncryptedMedia( | 466 void StartPipelineWithEncryptedMedia( |
| 434 MockMediaSource* source, | 467 MockMediaSource* source, |
| 435 FakeEncryptedMedia* encrypted_media) { | 468 FakeEncryptedMedia* encrypted_media) { |
| 436 EXPECT_CALL(*this, OnMetadata(_)).Times(AtMost(1)); | 469 EXPECT_CALL(*this, OnMetadata(_)).Times(AtMost(1)) |
| 470 .WillRepeatedly(SaveArg<0>(&metadata_)); | |
| 437 EXPECT_CALL(*this, OnPrerollCompleted()).Times(AtMost(1)); | 471 EXPECT_CALL(*this, OnPrerollCompleted()).Times(AtMost(1)); |
| 438 pipeline_->Start( | 472 pipeline_->Start( |
| 439 CreateFilterCollection(source->GetDemuxer(), | 473 CreateFilterCollection(source->GetDemuxer(), |
| 440 encrypted_media->decryptor()), | 474 encrypted_media->decryptor()), |
| 441 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)), | 475 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)), |
| 442 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)), | 476 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)), |
| 443 QuitOnStatusCB(PIPELINE_OK), | 477 QuitOnStatusCB(PIPELINE_OK), |
| 444 base::Bind(&PipelineIntegrationTest::OnMetadata, | 478 base::Bind(&PipelineIntegrationTest::OnMetadata, |
| 445 base::Unretained(this)), | 479 base::Unretained(this)), |
| 446 base::Bind(&PipelineIntegrationTest::OnPrerollCompleted, | 480 base::Bind(&PipelineIntegrationTest::OnPrerollCompleted, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 497 TEST_F(PipelineIntegrationTest, BasicPlaybackHashed) { | 531 TEST_F(PipelineIntegrationTest, BasicPlaybackHashed) { |
| 498 ASSERT_TRUE(Start( | 532 ASSERT_TRUE(Start( |
| 499 GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK, kHashed)); | 533 GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK, kHashed)); |
| 500 | 534 |
| 501 Play(); | 535 Play(); |
| 502 | 536 |
| 503 ASSERT_TRUE(WaitUntilOnEnded()); | 537 ASSERT_TRUE(WaitUntilOnEnded()); |
| 504 | 538 |
| 505 EXPECT_EQ("f0be120a90a811506777c99a2cdf7cc1", GetVideoHash()); | 539 EXPECT_EQ("f0be120a90a811506777c99a2cdf7cc1", GetVideoHash()); |
| 506 EXPECT_EQ("-3.59,-2.06,-0.43,2.15,0.77,-0.95,", GetAudioHash()); | 540 EXPECT_EQ("-3.59,-2.06,-0.43,2.15,0.77,-0.95,", GetAudioHash()); |
| 541 EXPECT_TRUE(demuxer_->GetWallclockTimelineOffset().is_null()); | |
| 542 } | |
| 543 | |
| 544 TEST_F(PipelineIntegrationTest, BasicPlaybackLive) { | |
| 545 ASSERT_TRUE(Start( | |
| 546 GetTestDataFilePath("bear-320x240-live.webm"), PIPELINE_OK, kHashed)); | |
| 547 | |
| 548 Play(); | |
| 549 | |
| 550 ASSERT_TRUE(WaitUntilOnEnded()); | |
| 551 | |
| 552 EXPECT_EQ("f0be120a90a811506777c99a2cdf7cc1", GetVideoHash()); | |
| 553 EXPECT_EQ("-3.59,-2.06,-0.43,2.15,0.77,-0.95,", GetAudioHash()); | |
| 554 | |
| 555 // TODO: Fix FFmpeg code to return higher resolution time values so | |
| 556 // we don't have to truncate our expectations here. | |
| 557 EXPECT_EQ(TruncateToFFmpegTimeResolution(kLiveWallclockTimelineOffset()), | |
| 558 demuxer_->GetWallclockTimelineOffset()); | |
| 507 } | 559 } |
| 508 | 560 |
| 509 TEST_F(PipelineIntegrationTest, F32PlaybackHashed) { | 561 TEST_F(PipelineIntegrationTest, F32PlaybackHashed) { |
| 510 ASSERT_TRUE( | 562 ASSERT_TRUE( |
| 511 Start(GetTestDataFilePath("sfx_f32le.wav"), PIPELINE_OK, kHashed)); | 563 Start(GetTestDataFilePath("sfx_f32le.wav"), PIPELINE_OK, kHashed)); |
| 512 Play(); | 564 Play(); |
| 513 ASSERT_TRUE(WaitUntilOnEnded()); | 565 ASSERT_TRUE(WaitUntilOnEnded()); |
| 514 EXPECT_EQ(std::string(kNullVideoHash), GetVideoHash()); | 566 EXPECT_EQ(std::string(kNullVideoHash), GetVideoHash()); |
| 515 EXPECT_EQ("3.03,2.86,2.99,3.31,3.57,4.06,", GetAudioHash()); | 567 EXPECT_EQ("3.03,2.86,2.99,3.31,3.57,4.06,", GetAudioHash()); |
| 516 } | 568 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 535 source.EndOfStream(); | 587 source.EndOfStream(); |
| 536 | 588 |
| 537 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); | 589 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); |
| 538 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); | 590 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); |
| 539 EXPECT_EQ(k320WebMFileDurationMs, | 591 EXPECT_EQ(k320WebMFileDurationMs, |
| 540 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); | 592 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); |
| 541 | 593 |
| 542 Play(); | 594 Play(); |
| 543 | 595 |
| 544 ASSERT_TRUE(WaitUntilOnEnded()); | 596 ASSERT_TRUE(WaitUntilOnEnded()); |
| 597 | |
| 598 EXPECT_TRUE(demuxer_->GetWallclockTimelineOffset().is_null()); | |
| 545 source.Abort(); | 599 source.Abort(); |
| 546 Stop(); | 600 Stop(); |
| 547 } | 601 } |
| 548 | 602 |
| 603 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_Live) { | |
| 604 MockMediaSource source("bear-320x240-live.webm", kWebM, 219221, GetParam()); | |
| 605 StartPipelineWithMediaSource(&source); | |
| 606 source.EndOfStream(); | |
| 607 | |
| 608 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); | |
| 609 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); | |
| 610 EXPECT_EQ(k320WebMFileDurationMs, | |
| 611 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); | |
| 612 | |
| 613 Play(); | |
| 614 | |
| 615 ASSERT_TRUE(WaitUntilOnEnded()); | |
| 616 | |
| 617 EXPECT_EQ(kLiveWallclockTimelineOffset(), | |
| 618 demuxer_->GetWallclockTimelineOffset()); | |
| 619 source.Abort(); | |
| 620 Stop(); | |
| 621 } | |
| 622 | |
| 623 | |
|
scherkus (not reviewing)
2014/04/15 00:53:40
remove extra blink
acolwell GONE FROM CHROMIUM
2014/04/16 01:01:08
Done.
| |
| 549 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_VP9_WebM) { | 624 TEST_P(PipelineIntegrationTest, BasicPlayback_MediaSource_VP9_WebM) { |
| 550 MockMediaSource source("bear-vp9.webm", kWebMVP9, 67504, GetParam()); | 625 MockMediaSource source("bear-vp9.webm", kWebMVP9, 67504, GetParam()); |
| 551 StartPipelineWithMediaSource(&source); | 626 StartPipelineWithMediaSource(&source); |
| 552 source.EndOfStream(); | 627 source.EndOfStream(); |
| 553 | 628 |
| 554 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); | 629 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); |
| 555 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); | 630 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); |
| 556 EXPECT_EQ(kVP9WebMFileDurationMs, | 631 EXPECT_EQ(kVP9WebMFileDurationMs, |
| 557 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); | 632 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); |
| 558 | 633 |
| (...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1215 Play(); | 1290 Play(); |
| 1216 ASSERT_TRUE(WaitUntilOnEnded()); | 1291 ASSERT_TRUE(WaitUntilOnEnded()); |
| 1217 } | 1292 } |
| 1218 | 1293 |
| 1219 // TODO(wolenetz): Enable MSE testing of new frame processor based on this flag, | 1294 // TODO(wolenetz): Enable MSE testing of new frame processor based on this flag, |
| 1220 // once the new processor has landed. See http://crbug.com/249422. | 1295 // once the new processor has landed. See http://crbug.com/249422. |
| 1221 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, PipelineIntegrationTest, | 1296 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, PipelineIntegrationTest, |
| 1222 Values(true)); | 1297 Values(true)); |
| 1223 | 1298 |
| 1224 } // namespace media | 1299 } // namespace media |
| OLD | NEW |