| 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/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
| 11 #include "media/base/decoder_buffer.h" | 11 #include "media/base/decoder_buffer.h" |
| 12 #include "media/base/test_data_util.h" | 12 #include "media/base/test_data_util.h" |
| 13 #include "media/crypto/aes_decryptor.h" | 13 #include "media/crypto/aes_decryptor.h" |
| 14 | 14 |
| 15 using testing::AtMost; | 15 using testing::AtMost; |
| 16 | 16 |
| 17 namespace media { | 17 namespace media { |
| 18 | 18 |
| 19 static const char kSourceId[] = "SourceId"; | 19 static const char kSourceId[] = "SourceId"; |
| 20 static const char kClearKeySystem[] = "org.w3.clearkey"; | 20 static const char kClearKeySystem[] = "org.w3.clearkey"; |
| 21 static const uint8 kInitData[] = { 0x69, 0x6e, 0x69, 0x74 }; | 21 static const uint8 kInitData[] = { 0x69, 0x6e, 0x69, 0x74 }; |
| 22 | 22 |
| 23 static const char kWebM[] = "video/webm; codecs=\"vp8,vorbis\""; | 23 static const char kWebM[] = "video/webm; codecs=\"vp8,vorbis\""; |
| 24 static const char kAudioOnlyWebM[] = "video/webm; codecs=\"vorbis\""; | 24 static const char kAudioOnlyWebM[] = "video/webm; codecs=\"vorbis\""; |
| 25 static const char kVideoOnlyWebM[] = "video/webm; codecs=\"vp8\""; | 25 static const char kVideoOnlyWebM[] = "video/webm; codecs=\"vp8\""; |
| 26 static const char kMP4[] = "video/mp4; codecs=\"avc1.4D4041,mp4a.40.2\""; | 26 static const char kMP4[] = "video/mp4; codecs=\"avc1.4D4041,mp4a.40.2\""; |
| 27 static const char kMP4Video[] = "video/mp4; codecs=\"avc1.4D4041\""; |
| 28 static const char kMP4Audio[] = "audio/mp4; codecs=\"mp4a.40.2\""; |
| 29 static const char kMP4AudioType[] = "audio/mp4"; |
| 30 static const char kMP4VideoType[] = "video/mp4"; |
| 27 | 31 |
| 28 // Key used to encrypt test files. | 32 // Key used to encrypt test files. |
| 29 static const uint8 kSecretKey[] = { | 33 static const uint8 kSecretKey[] = { |
| 30 0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b, | 34 0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b, |
| 31 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c | 35 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c |
| 32 }; | 36 }; |
| 33 | 37 |
| 34 // The key ID for all encrypted files. | 38 // The key ID for all encrypted files. |
| 35 static const uint8 kKeyId[] = { | 39 static const uint8 kKeyId[] = { |
| 36 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, | 40 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, |
| 37 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35 | 41 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35 |
| 38 }; | 42 }; |
| 39 | 43 |
| 40 static const int kAppendWholeFile = -1; | 44 static const int kAppendWholeFile = -1; |
| 41 | 45 |
| 42 // Constants for the Media Source config change tests. | 46 // Constants for the Media Source config change tests. |
| 43 static const int kAppendTimeSec = 1; | 47 static const int kAppendTimeSec = 1; |
| 44 static const int kAppendTimeMs = kAppendTimeSec * 1000; | 48 static const int kAppendTimeMs = kAppendTimeSec * 1000; |
| 45 static const int k320WebMFileDurationMs = 2737; | 49 static const int k320WebMFileDurationMs = 2737; |
| 46 static const int k640WebMFileDurationMs = 2763; | 50 static const int k640WebMFileDurationMs = 2763; |
| 51 static const int k640IsoFileDurationMs = 2737; |
| 52 static const int k640IsoCencFileDurationMs = 2736; |
| 47 static const int k1280IsoFileDurationMs = 2736; | 53 static const int k1280IsoFileDurationMs = 2736; |
| 48 | 54 |
| 49 // Note: Tests using this class only exercise the DecryptingDemuxerStream path. | 55 // Note: Tests using this class only exercise the DecryptingDemuxerStream path. |
| 50 // They do not exercise the Decrypting{Audio|Video}Decoder path. | 56 // They do not exercise the Decrypting{Audio|Video}Decoder path. |
| 51 class FakeEncryptedMedia { | 57 class FakeEncryptedMedia { |
| 52 public: | 58 public: |
| 53 // Defines the behavior of the "app" that responds to EME events. | 59 // Defines the behavior of the "app" that responds to EME events. |
| 54 class AppBase { | 60 class AppBase { |
| 55 public: | 61 public: |
| 56 virtual ~AppBase() {} | 62 virtual ~AppBase() {} |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 // In this case, we need to call GenerateKeyRequest() to initialize a | 165 // In this case, we need to call GenerateKeyRequest() to initialize a |
| 160 // session (which will call KeyMessage). | 166 // session (which will call KeyMessage). |
| 161 if (current_key_system_.empty()) { | 167 if (current_key_system_.empty()) { |
| 162 EXPECT_TRUE(current_session_id_.empty()); | 168 EXPECT_TRUE(current_session_id_.empty()); |
| 163 EXPECT_TRUE(decryptor->GenerateKeyRequest( | 169 EXPECT_TRUE(decryptor->GenerateKeyRequest( |
| 164 kClearKeySystem, type, kInitData, arraysize(kInitData))); | 170 kClearKeySystem, type, kInitData, arraysize(kInitData))); |
| 165 } | 171 } |
| 166 | 172 |
| 167 EXPECT_FALSE(current_key_system_.empty()); | 173 EXPECT_FALSE(current_key_system_.empty()); |
| 168 EXPECT_FALSE(current_session_id_.empty()); | 174 EXPECT_FALSE(current_session_id_.empty()); |
| 175 |
| 176 // Clear Key really needs the key ID in |init_data|. For WebM, they are the |
| 177 // same, but this is not the case for ISO CENC. Therefore, provide the |
| 178 // correct key ID. |
| 179 const uint8* key_id = init_data.get(); |
| 180 int key_id_length = init_data_length; |
| 181 if (type == kMP4AudioType || type == kMP4VideoType) { |
| 182 key_id = kKeyId; |
| 183 key_id_length = arraysize(kKeyId); |
| 184 } |
| 185 |
| 169 decryptor->AddKey(current_key_system_, kSecretKey, arraysize(kSecretKey), | 186 decryptor->AddKey(current_key_system_, kSecretKey, arraysize(kSecretKey), |
| 170 init_data.get(), init_data_length, current_session_id_); | 187 key_id, key_id_length, current_session_id_); |
| 171 } | 188 } |
| 172 | 189 |
| 173 std::string current_key_system_; | 190 std::string current_key_system_; |
| 174 std::string current_session_id_; | 191 std::string current_session_id_; |
| 175 }; | 192 }; |
| 176 | 193 |
| 177 // Ignores needkey and does not perform a license request | 194 // Ignores needkey and does not perform a license request |
| 178 class NoResponseApp : public FakeEncryptedMedia::AppBase { | 195 class NoResponseApp : public FakeEncryptedMedia::AppBase { |
| 179 public: | 196 public: |
| 180 virtual void KeyAdded(const std::string& key_system, | 197 virtual void KeyAdded(const std::string& key_system, |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); | 566 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); |
| 550 EXPECT_EQ(kAppendTimeMs + k1280IsoFileDurationMs, | 567 EXPECT_EQ(kAppendTimeMs + k1280IsoFileDurationMs, |
| 551 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); | 568 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); |
| 552 | 569 |
| 553 Play(); | 570 Play(); |
| 554 | 571 |
| 555 EXPECT_TRUE(WaitUntilOnEnded()); | 572 EXPECT_TRUE(WaitUntilOnEnded()); |
| 556 source.Abort(); | 573 source.Abort(); |
| 557 Stop(); | 574 Stop(); |
| 558 } | 575 } |
| 576 |
| 577 TEST_F(PipelineIntegrationTest, |
| 578 MediaSource_ConfigChange_Encrypted_MP4_CENC_VideoOnly) { |
| 579 MockMediaSource source("bear-640x360-v_frag-cenc.mp4", |
| 580 kMP4Video, kAppendWholeFile); |
| 581 FakeEncryptedMedia encrypted_media(new KeyProvidingApp()); |
| 582 StartPipelineWithEncryptedMedia(&source, &encrypted_media); |
| 583 |
| 584 scoped_refptr<DecoderBuffer> second_file = |
| 585 ReadTestDataFile("bear-1280x720-v_frag-cenc.mp4"); |
| 586 |
| 587 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec), |
| 588 second_file->GetData(), second_file->GetDataSize()); |
| 589 |
| 590 source.EndOfStream(); |
| 591 |
| 592 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); |
| 593 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); |
| 594 EXPECT_EQ(kAppendTimeMs + k1280IsoFileDurationMs, |
| 595 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); |
| 596 |
| 597 Play(); |
| 598 |
| 599 EXPECT_TRUE(WaitUntilOnEnded()); |
| 600 source.Abort(); |
| 601 Stop(); |
| 602 } |
| 603 |
| 604 // Config changes from clear to encrypted are not currently supported. |
| 605 // TODO(ddorwin): Figure out why this CHECKs in AppendAtTime(). |
| 606 TEST_F(PipelineIntegrationTest, |
| 607 DISABLED_MediaSource_ConfigChange_ClearThenEncrypted_MP4_CENC) { |
| 608 MockMediaSource source("bear-640x360-av_frag.mp4", kMP4Video, |
| 609 kAppendWholeFile); |
| 610 FakeEncryptedMedia encrypted_media(new KeyProvidingApp()); |
| 611 StartPipelineWithEncryptedMedia(&source, &encrypted_media); |
| 612 |
| 613 scoped_refptr<DecoderBuffer> second_file = |
| 614 ReadTestDataFile("bear-1280x720-v_frag-cenc.mp4"); |
| 615 |
| 616 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec), |
| 617 second_file->GetData(), second_file->GetDataSize()); |
| 618 |
| 619 source.EndOfStream(); |
| 620 |
| 621 message_loop_.Run(); |
| 622 EXPECT_EQ(PIPELINE_ERROR_DECODE, pipeline_status_); |
| 623 |
| 624 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); |
| 625 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); |
| 626 // The second video was not added, so its time has not been added. |
| 627 EXPECT_EQ(k640IsoFileDurationMs, |
| 628 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); |
| 629 |
| 630 Play(); |
| 631 |
| 632 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError()); |
| 633 source.Abort(); |
| 634 } |
| 635 |
| 636 // Config changes from encrypted to clear are not currently supported. |
| 637 TEST_F(PipelineIntegrationTest, |
| 638 MediaSource_ConfigChange_EncryptedThenClear_MP4_CENC) { |
| 639 MockMediaSource source("bear-640x360-v_frag-cenc.mp4", |
| 640 kMP4Video, kAppendWholeFile); |
| 641 FakeEncryptedMedia encrypted_media(new KeyProvidingApp()); |
| 642 StartPipelineWithEncryptedMedia(&source, &encrypted_media); |
| 643 |
| 644 scoped_refptr<DecoderBuffer> second_file = |
| 645 ReadTestDataFile("bear-1280x720-av_frag.mp4"); |
| 646 |
| 647 source.AppendAtTime(base::TimeDelta::FromSeconds(kAppendTimeSec), |
| 648 second_file->GetData(), second_file->GetDataSize()); |
| 649 |
| 650 source.EndOfStream(); |
| 651 |
| 652 EXPECT_EQ(1u, pipeline_->GetBufferedTimeRanges().size()); |
| 653 EXPECT_EQ(0, pipeline_->GetBufferedTimeRanges().start(0).InMilliseconds()); |
| 654 // The second video was not added, so its time has not been added. |
| 655 EXPECT_EQ(k640IsoCencFileDurationMs, |
| 656 pipeline_->GetBufferedTimeRanges().end(0).InMilliseconds()); |
| 657 |
| 658 Play(); |
| 659 |
| 660 EXPECT_EQ(PIPELINE_ERROR_DECODE, WaitUntilEndedOrError()); |
| 661 source.Abort(); |
| 662 } |
| 559 #endif | 663 #endif |
| 560 | 664 |
| 561 TEST_F(PipelineIntegrationTest, BasicPlayback_16x9AspectRatio) { | 665 TEST_F(PipelineIntegrationTest, BasicPlayback_16x9AspectRatio) { |
| 562 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240-16x9-aspect.webm"), | 666 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240-16x9-aspect.webm"), |
| 563 PIPELINE_OK)); | 667 PIPELINE_OK)); |
| 564 Play(); | 668 Play(); |
| 565 ASSERT_TRUE(WaitUntilOnEnded()); | 669 ASSERT_TRUE(WaitUntilOnEnded()); |
| 566 } | 670 } |
| 567 | 671 |
| 568 TEST_F(PipelineIntegrationTest, EncryptedPlayback_WebM) { | 672 TEST_F(PipelineIntegrationTest, EncryptedPlayback_WebM) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 source.EndOfStream(); | 709 source.EndOfStream(); |
| 606 ASSERT_EQ(PIPELINE_OK, pipeline_status_); | 710 ASSERT_EQ(PIPELINE_OK, pipeline_status_); |
| 607 | 711 |
| 608 Play(); | 712 Play(); |
| 609 | 713 |
| 610 ASSERT_TRUE(WaitUntilOnEnded()); | 714 ASSERT_TRUE(WaitUntilOnEnded()); |
| 611 source.Abort(); | 715 source.Abort(); |
| 612 Stop(); | 716 Stop(); |
| 613 } | 717 } |
| 614 | 718 |
| 719 #if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS) |
| 720 TEST_F(PipelineIntegrationTest, EncryptedPlayback_MP4_CENC_VideoOnly) { |
| 721 MockMediaSource source("bear-1280x720-v_frag-cenc.mp4", |
| 722 kMP4Video, kAppendWholeFile); |
| 723 FakeEncryptedMedia encrypted_media(new KeyProvidingApp()); |
| 724 StartPipelineWithEncryptedMedia(&source, &encrypted_media); |
| 725 |
| 726 source.EndOfStream(); |
| 727 ASSERT_EQ(PIPELINE_OK, pipeline_status_); |
| 728 |
| 729 Play(); |
| 730 |
| 731 ASSERT_TRUE(WaitUntilOnEnded()); |
| 732 source.Abort(); |
| 733 Stop(); |
| 734 } |
| 735 |
| 736 TEST_F(PipelineIntegrationTest, EncryptedPlayback_MP4_CENC_AudioOnly) { |
| 737 MockMediaSource source("bear-1280x720-a_frag-cenc.mp4", |
| 738 kMP4Audio, kAppendWholeFile); |
| 739 FakeEncryptedMedia encrypted_media(new KeyProvidingApp()); |
| 740 StartPipelineWithEncryptedMedia(&source, &encrypted_media); |
| 741 |
| 742 source.EndOfStream(); |
| 743 ASSERT_EQ(PIPELINE_OK, pipeline_status_); |
| 744 |
| 745 Play(); |
| 746 |
| 747 ASSERT_TRUE(WaitUntilOnEnded()); |
| 748 source.Abort(); |
| 749 Stop(); |
| 750 } |
| 751 |
| 752 TEST_F(PipelineIntegrationTest, |
| 753 EncryptedPlayback_NoEncryptedFrames_MP4_CENC_VideoOnly) { |
| 754 MockMediaSource source("bear-1280x720-v_frag-cenc_clear-all.mp4", |
| 755 kMP4Video, kAppendWholeFile); |
| 756 FakeEncryptedMedia encrypted_media(new NoResponseApp()); |
| 757 StartPipelineWithEncryptedMedia(&source, &encrypted_media); |
| 758 |
| 759 source.EndOfStream(); |
| 760 ASSERT_EQ(PIPELINE_OK, pipeline_status_); |
| 761 |
| 762 Play(); |
| 763 |
| 764 ASSERT_TRUE(WaitUntilOnEnded()); |
| 765 source.Abort(); |
| 766 Stop(); |
| 767 } |
| 768 |
| 769 TEST_F(PipelineIntegrationTest, |
| 770 EncryptedPlayback_NoEncryptedFrames_MP4_CENC_AudioOnly) { |
| 771 MockMediaSource source("bear-1280x720-a_frag-cenc_clear-all.mp4", |
| 772 kMP4Audio, kAppendWholeFile); |
| 773 FakeEncryptedMedia encrypted_media(new NoResponseApp()); |
| 774 StartPipelineWithEncryptedMedia(&source, &encrypted_media); |
| 775 |
| 776 source.EndOfStream(); |
| 777 ASSERT_EQ(PIPELINE_OK, pipeline_status_); |
| 778 |
| 779 Play(); |
| 780 |
| 781 ASSERT_TRUE(WaitUntilOnEnded()); |
| 782 source.Abort(); |
| 783 Stop(); |
| 784 } |
| 785 #endif |
| 786 |
| 615 // TODO(acolwell): Fix flakiness http://crbug.com/117921 | 787 // TODO(acolwell): Fix flakiness http://crbug.com/117921 |
| 616 TEST_F(PipelineIntegrationTest, DISABLED_SeekWhilePaused) { | 788 TEST_F(PipelineIntegrationTest, DISABLED_SeekWhilePaused) { |
| 617 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK)); | 789 ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK)); |
| 618 | 790 |
| 619 base::TimeDelta duration(pipeline_->GetMediaDuration()); | 791 base::TimeDelta duration(pipeline_->GetMediaDuration()); |
| 620 base::TimeDelta start_seek_time(duration / 4); | 792 base::TimeDelta start_seek_time(duration / 4); |
| 621 base::TimeDelta seek_time(duration * 3 / 4); | 793 base::TimeDelta seek_time(duration * 3 / 4); |
| 622 | 794 |
| 623 Play(); | 795 Play(); |
| 624 ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time)); | 796 ASSERT_TRUE(WaitUntilCurrentTimeIsAfter(start_seek_time)); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 // Verify video decoder & renderer can handle aborted demuxer reads. | 840 // Verify video decoder & renderer can handle aborted demuxer reads. |
| 669 TEST_F(PipelineIntegrationTest, ChunkDemuxerAbortRead_VideoOnly) { | 841 TEST_F(PipelineIntegrationTest, ChunkDemuxerAbortRead_VideoOnly) { |
| 670 ASSERT_TRUE(TestSeekDuringRead("bear-320x240-video-only.webm", kVideoOnlyWebM, | 842 ASSERT_TRUE(TestSeekDuringRead("bear-320x240-video-only.webm", kVideoOnlyWebM, |
| 671 32768, | 843 32768, |
| 672 base::TimeDelta::FromMilliseconds(200), | 844 base::TimeDelta::FromMilliseconds(200), |
| 673 base::TimeDelta::FromMilliseconds(1668), | 845 base::TimeDelta::FromMilliseconds(1668), |
| 674 0x1C896, 65536)); | 846 0x1C896, 65536)); |
| 675 } | 847 } |
| 676 | 848 |
| 677 } // namespace media | 849 } // namespace media |
| OLD | NEW |