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

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

Issue 10534096: Generalize AesDecryptor to make it more spec compliant. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 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 "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 "media/base/decoder_buffer.h" 8 #include "media/base/decoder_buffer.h"
9 #include "media/base/mock_filters.h"
9 #include "media/base/test_data_util.h" 10 #include "media/base/test_data_util.h"
11 #include "media/crypto/aes_decryptor.h"
12 #include "media/crypto/decryptor_client.h"
10 #include "media/filters/chunk_demuxer_client.h" 13 #include "media/filters/chunk_demuxer_client.h"
11 14
12 namespace media { 15 namespace media {
13 16
14 // Key ID of the video track in test file "bear-320x240-encrypted.webm".
15 static const unsigned char kKeyId[] =
16 "\x11\xa5\x18\x37\xc4\x73\x84\x03\xe5\xe6\x57\xed\x8e\x06\xd9\x7c";
17
18 static const char* kSourceId = "SourceId"; 17 static const char* kSourceId = "SourceId";
19 18
20 // Helper class that emulates calls made on the ChunkDemuxer by the 19 // Helper class that emulates calls made on the ChunkDemuxer by the
21 // Media Source API. 20 // Media Source API.
22 class MockMediaSource : public ChunkDemuxerClient { 21 class MockMediaSource : public ChunkDemuxerClient {
23 public: 22 public:
24 MockMediaSource(const std::string& filename, int initial_append_size) 23 MockMediaSource(const std::string& filename, int initial_append_size)
25 : url_(GetTestDataURL(filename)), 24 : url_(GetTestDataURL(filename)),
26 current_position_(0), 25 current_position_(0),
27 initial_append_size_(initial_append_size) { 26 initial_append_size_(initial_append_size) {
28 file_data_ = ReadTestDataFile(filename); 27 file_data_ = ReadTestDataFile(filename);
29 28
30 DCHECK_GT(initial_append_size_, 0); 29 DCHECK_GT(initial_append_size_, 0);
31 DCHECK_LE(initial_append_size_, file_data_->GetDataSize()); 30 DCHECK_LE(initial_append_size_, file_data_->GetDataSize());
32 } 31 }
33 32
34 virtual ~MockMediaSource() {} 33 virtual ~MockMediaSource() {}
35 34
36 void set_decryptor(AesDecryptor* decryptor) { 35 void set_decryptor_client(DecryptorClient* decryptor_client) {
37 decryptor_ = decryptor; 36 decryptor_client_ = decryptor_client;
38 }
39 AesDecryptor* decryptor() const {
40 return decryptor_;
41 } 37 }
42 38
43 const std::string& url() const { return url_; } 39 const std::string& url() const { return url_; }
44 40
45 void Seek(int new_position, int seek_append_size) { 41 void Seek(int new_position, int seek_append_size) {
46 chunk_demuxer_->StartWaitingForSeek(); 42 chunk_demuxer_->StartWaitingForSeek();
47 43
48 chunk_demuxer_->Abort(kSourceId); 44 chunk_demuxer_->Abort(kSourceId);
49 45
50 DCHECK_GE(new_position, 0); 46 DCHECK_GE(new_position, 0);
(...skipping 30 matching lines...) Expand all
81 codecs[0] = "vp8"; 77 codecs[0] = "vp8";
82 codecs[1] = "vorbis"; 78 codecs[1] = "vorbis";
83 chunk_demuxer_->AddId(kSourceId, "video/webm", codecs); 79 chunk_demuxer_->AddId(kSourceId, "video/webm", codecs);
84 AppendData(initial_append_size_); 80 AppendData(initial_append_size_);
85 } 81 }
86 82
87 virtual void DemuxerClosed() { 83 virtual void DemuxerClosed() {
88 chunk_demuxer_ = NULL; 84 chunk_demuxer_ = NULL;
89 } 85 }
90 86
91 virtual void KeyNeeded(scoped_array<uint8> init_data, int init_data_size) { 87 virtual void DemuxerKeyNeeded(scoped_array<uint8> init_data,
88 int init_data_size) {
92 DCHECK(init_data.get()); 89 DCHECK(init_data.get());
93 DCHECK_EQ(init_data_size, 16); 90 DCHECK_EQ(init_data_size, 16);
94 DCHECK(decryptor()); 91 DCHECK(decryptor_client_);
95 // In test file bear-320x240-encrypted.webm, the decryption key is equal to 92 decryptor_client_->KeyNeeded("", "", init_data.Pass(), init_data_size);
96 // |init_data|.
97 decryptor()->AddKey(init_data.get(), init_data_size,
98 init_data.get(), init_data_size);
99 } 93 }
100 94
101 private: 95 private:
102 std::string url_; 96 std::string url_;
103 scoped_refptr<DecoderBuffer> file_data_; 97 scoped_refptr<DecoderBuffer> file_data_;
104 int current_position_; 98 int current_position_;
105 int initial_append_size_; 99 int initial_append_size_;
106 scoped_refptr<ChunkDemuxer> chunk_demuxer_; 100 scoped_refptr<ChunkDemuxer> chunk_demuxer_;
101 DecryptorClient* decryptor_client_;
102 };
103
104 class MockEncryptedMedia : public MockDecryptorClient {
ddorwin 2012/06/11 21:02:40 The class name is not very descriptive.
xhwang 2012/06/12 19:01:15 Agreed, but I haven't found a good name for this.
105 public:
106 MockEncryptedMedia() {}
107 virtual ~MockEncryptedMedia() {}
108
109 void set_decryptor(AesDecryptor* decryptor) {
110 decryptor_ = decryptor;
111 }
112
113 // DecryptorClient implementation.
114 virtual void KeyNeeded(const std::string& key_system,
115 const std::string& session_id,
116 scoped_array<uint8> init_data,
117 int init_data_length) {
118 // In test file bear-320x240-encrypted.webm, the decryption key is equal to
119 // |init_data|.
120 DCHECK(decryptor_);
121 decryptor_->AddKey(key_system, init_data.get(), init_data_length,
ddorwin 2012/06/11 21:02:40 key_system and session_id will be empty on keyneed
xhwang 2012/06/12 19:01:15 Done.
122 init_data.get(), init_data_length, session_id);
123 }
124
125 private:
107 AesDecryptor* decryptor_; 126 AesDecryptor* decryptor_;
108 }; 127 };
109 128
110 class PipelineIntegrationTest 129 class PipelineIntegrationTest
111 : public testing::Test, 130 : public testing::Test,
112 public PipelineIntegrationTestBase { 131 public PipelineIntegrationTestBase {
113 public: 132 public:
114 void StartPipelineWithMediaSource(MockMediaSource& source) { 133 void StartPipelineWithMediaSource(MockMediaSource* source) {
115 pipeline_->Start( 134 pipeline_->Start(
116 CreateFilterCollection(&source), 135 CreateFilterCollection(source),
117 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)), 136 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)),
118 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)), 137 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)),
119 NetworkEventCB(), QuitOnStatusCB(PIPELINE_OK)); 138 NetworkEventCB(), QuitOnStatusCB(PIPELINE_OK));
120 139
121 ASSERT_TRUE(decoder_.get()); 140 ASSERT_TRUE(decoder_.get());
122 source.set_decryptor(decryptor_.get());
123 141
124 message_loop_.Run(); 142 message_loop_.Run();
125 } 143 }
144
145 void StartPipelineWithEncryptedMedia(MockMediaSource* source,
146 MockEncryptedMedia* encrypted_media) {
147 pipeline_->Start(
148 CreateFilterCollection(source),
149 base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)),
150 base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)),
151 NetworkEventCB(), QuitOnStatusCB(PIPELINE_OK));
152
153 ASSERT_TRUE(decoder_.get());
154 ASSERT_TRUE(decryptor_.get());
155 encrypted_media->set_decryptor(decryptor_.get());
156 decryptor_->Init(encrypted_media);
157 source->set_decryptor_client(encrypted_media);
158
159 EXPECT_CALL(*encrypted_media, KeyAdded("", ""));
160
161 message_loop_.Run();
162 }
126 163
127 // Verifies that seeking works properly for ChunkDemuxer when the 164 // Verifies that seeking works properly for ChunkDemuxer when the
128 // seek happens while there is a pending read on the ChunkDemuxer 165 // seek happens while there is a pending read on the ChunkDemuxer
129 // and no data is available. 166 // and no data is available.
130 bool TestSeekDuringRead(const std::string& filename, 167 bool TestSeekDuringRead(const std::string& filename,
131 int initial_append_size, 168 int initial_append_size,
132 base::TimeDelta start_seek_time, 169 base::TimeDelta start_seek_time,
133 base::TimeDelta seek_time, 170 base::TimeDelta seek_time,
134 int seek_file_position, 171 int seek_file_position,
135 int seek_append_size) { 172 int seek_append_size) {
136 MockMediaSource source(filename, initial_append_size); 173 MockMediaSource source(filename, initial_append_size);
137 StartPipelineWithMediaSource(source); 174 StartPipelineWithMediaSource(&source);
138 175
139 if (pipeline_status_ != PIPELINE_OK) 176 if (pipeline_status_ != PIPELINE_OK)
140 return false; 177 return false;
141 178
142 Play(); 179 Play();
143 if (!WaitUntilCurrentTimeIsAfter(start_seek_time)) 180 if (!WaitUntilCurrentTimeIsAfter(start_seek_time))
144 return false; 181 return false;
145 182
146 source.Seek(seek_file_position, seek_append_size); 183 source.Seek(seek_file_position, seek_append_size);
147 if (!Seek(seek_time)) 184 if (!Seek(seek_time))
(...skipping 22 matching lines...) Expand all
170 Play(); 207 Play();
171 208
172 ASSERT_TRUE(WaitUntilOnEnded()); 209 ASSERT_TRUE(WaitUntilOnEnded());
173 210
174 EXPECT_EQ(GetVideoHash(), "f0be120a90a811506777c99a2cdf7cc1"); 211 EXPECT_EQ(GetVideoHash(), "f0be120a90a811506777c99a2cdf7cc1");
175 EXPECT_EQ(GetAudioHash(), "6138555be3389e6aba4c8e6f70195d50"); 212 EXPECT_EQ(GetAudioHash(), "6138555be3389e6aba4c8e6f70195d50");
176 } 213 }
177 214
178 TEST_F(PipelineIntegrationTest, EncryptedPlayback) { 215 TEST_F(PipelineIntegrationTest, EncryptedPlayback) {
179 MockMediaSource source("bear-320x240-encrypted.webm", 219726); 216 MockMediaSource source("bear-320x240-encrypted.webm", 219726);
180 StartPipelineWithMediaSource(source); 217 MockEncryptedMedia encrypted_media;
218 StartPipelineWithEncryptedMedia(&source, &encrypted_media);
181 219
182 source.EndOfStream(); 220 source.EndOfStream();
183 ASSERT_EQ(PIPELINE_OK, pipeline_status_); 221 ASSERT_EQ(PIPELINE_OK, pipeline_status_);
184 222
185 Play(); 223 Play();
186 224
187 ASSERT_TRUE(WaitUntilOnEnded()); 225 ASSERT_TRUE(WaitUntilOnEnded());
188 source.Abort(); 226 source.Abort();
189 Stop(); 227 Stop();
190 } 228 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 281
244 // Verify video decoder & renderer can handle aborted demuxer reads. 282 // Verify video decoder & renderer can handle aborted demuxer reads.
245 TEST_F(PipelineIntegrationTest, ChunkDemuxerAbortRead_VideoOnly) { 283 TEST_F(PipelineIntegrationTest, ChunkDemuxerAbortRead_VideoOnly) {
246 ASSERT_TRUE(TestSeekDuringRead("bear-320x240-video-only.webm", 32768, 284 ASSERT_TRUE(TestSeekDuringRead("bear-320x240-video-only.webm", 32768,
247 base::TimeDelta::FromMilliseconds(200), 285 base::TimeDelta::FromMilliseconds(200),
248 base::TimeDelta::FromMilliseconds(1668), 286 base::TimeDelta::FromMilliseconds(1668),
249 0x1C896, 65536)); 287 0x1C896, 65536));
250 } 288 }
251 289
252 } // namespace media 290 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698