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

Side by Side Diff: media/filters/pipeline_integration_test.cc

Issue 11778086: Add unit tests for ISO CENC (encrypted MP4). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review feedback Created 7 years, 11 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 | « no previous file | no next file » | 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) 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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698