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

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

Issue 1163713007: Use 'pssh' data to determine key_id properly (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: change comment Created 5 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
« no previous file with comments | « media/test/data/bear-640x360-v_frag-cenc-key_rotation.mp4 ('k') | 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 "base/bind.h" 5 #include "base/bind.h"
6 #include "base/command_line.h" 6 #include "base/command_line.h"
7 #include "base/memory/scoped_ptr.h" 7 #include "base/memory/scoped_ptr.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "build/build_config.h" 10 #include "build/build_config.h"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 const char kMP4[] = "video/mp4; codecs=\"avc1.4D4041,mp4a.40.2\""; 68 const char kMP4[] = "video/mp4; codecs=\"avc1.4D4041,mp4a.40.2\"";
69 const char kMP4VideoAVC3[] = "video/mp4; codecs=\"avc3.64001f\""; 69 const char kMP4VideoAVC3[] = "video/mp4; codecs=\"avc3.64001f\"";
70 #if !defined(DISABLE_EME_TESTS) 70 #if !defined(DISABLE_EME_TESTS)
71 const char kMP4Video[] = "video/mp4; codecs=\"avc1.4D4041\""; 71 const char kMP4Video[] = "video/mp4; codecs=\"avc1.4D4041\"";
72 const char kMP4Audio[] = "audio/mp4; codecs=\"mp4a.40.2\""; 72 const char kMP4Audio[] = "audio/mp4; codecs=\"mp4a.40.2\"";
73 #endif // !defined(DISABLE_EME_TESTS) 73 #endif // !defined(DISABLE_EME_TESTS)
74 const char kMP3[] = "audio/mpeg"; 74 const char kMP3[] = "audio/mpeg";
75 #endif // defined(USE_PROPRIETARY_CODECS) 75 #endif // defined(USE_PROPRIETARY_CODECS)
76 76
77 // Key used to encrypt test files. 77 // Key used to encrypt test files.
78 const uint8 kSecretKey[] = { 78 const uint8_t kSecretKey[] = {
79 0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b, 79 0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
80 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c 80 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c
81 }; 81 };
82 82
83 // The key ID for all encrypted files. 83 // The key ID for all encrypted files.
84 const uint8 kKeyId[] = { 84 const uint8_t kKeyId[] = {
85 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 85 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
86 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35 86 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35
87 }; 87 };
88 88
89 const int kAppendWholeFile = -1; 89 const int kAppendWholeFile = -1;
90 90
91 // Constants for the Media Source config change tests. 91 // Constants for the Media Source config change tests.
92 const int kAppendTimeSec = 1; 92 const int kAppendTimeSec = 1;
93 const int kAppendTimeMs = kAppendTimeSec * 1000; 93 const int kAppendTimeMs = kAppendTimeSec * 1000;
94 const int k320WebMFileDurationMs = 2736; 94 const int k320WebMFileDurationMs = 2736;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 // They do not exercise the Decrypting{Audio|Video}Decoder path. 144 // They do not exercise the Decrypting{Audio|Video}Decoder path.
145 class FakeEncryptedMedia { 145 class FakeEncryptedMedia {
146 public: 146 public:
147 // Defines the behavior of the "app" that responds to EME events. 147 // Defines the behavior of the "app" that responds to EME events.
148 class AppBase { 148 class AppBase {
149 public: 149 public:
150 virtual ~AppBase() {} 150 virtual ~AppBase() {}
151 151
152 virtual void OnSessionMessage(const std::string& session_id, 152 virtual void OnSessionMessage(const std::string& session_id,
153 MediaKeys::MessageType message_type, 153 MediaKeys::MessageType message_type,
154 const std::vector<uint8>& message, 154 const std::vector<uint8_t>& message,
155 const GURL& legacy_destination_url) = 0; 155 const GURL& legacy_destination_url,
156 AesDecryptor* decryptor) = 0;
156 157
157 virtual void OnSessionClosed(const std::string& session_id) = 0; 158 virtual void OnSessionClosed(const std::string& session_id) = 0;
158 159
159 virtual void OnSessionKeysChange(const std::string& session_id, 160 virtual void OnSessionKeysChange(const std::string& session_id,
160 bool has_additional_usable_key, 161 bool has_additional_usable_key,
161 CdmKeysInfo keys_info) = 0; 162 CdmKeysInfo keys_info) = 0;
162 163
163 // Errors are not expected unless overridden. 164 // Errors are not expected unless overridden.
164 virtual void OnLegacySessionError(const std::string& session_id, 165 virtual void OnLegacySessionError(const std::string& session_id,
165 const std::string& error_name, 166 const std::string& error_name,
166 uint32 system_code, 167 uint32_t system_code,
167 const std::string& error_message) { 168 const std::string& error_message) {
168 FAIL() << "Unexpected Key Error"; 169 FAIL() << "Unexpected Key Error";
169 } 170 }
170 171
171 virtual void OnEncryptedMediaInitData(EmeInitDataType init_data_type, 172 virtual void OnEncryptedMediaInitData(EmeInitDataType init_data_type,
172 const std::vector<uint8>& init_data, 173 const std::vector<uint8_t>& init_data,
173 AesDecryptor* decryptor) = 0; 174 AesDecryptor* decryptor) = 0;
174 }; 175 };
175 176
176 FakeEncryptedMedia(AppBase* app) 177 FakeEncryptedMedia(AppBase* app)
177 : decryptor_(GURL::EmptyGURL(), 178 : decryptor_(GURL::EmptyGURL(),
178 base::Bind(&FakeEncryptedMedia::OnSessionMessage, 179 base::Bind(&FakeEncryptedMedia::OnSessionMessage,
179 base::Unretained(this)), 180 base::Unretained(this)),
180 base::Bind(&FakeEncryptedMedia::OnSessionClosed, 181 base::Bind(&FakeEncryptedMedia::OnSessionClosed,
181 base::Unretained(this)), 182 base::Unretained(this)),
182 base::Bind(&FakeEncryptedMedia::OnSessionKeysChange, 183 base::Bind(&FakeEncryptedMedia::OnSessionKeysChange,
183 base::Unretained(this))), 184 base::Unretained(this))),
184 cdm_context_(&decryptor_), 185 cdm_context_(&decryptor_),
185 app_(app) {} 186 app_(app) {}
186 187
187 CdmContext* GetCdmContext() { return &cdm_context_; } 188 CdmContext* GetCdmContext() { return &cdm_context_; }
188 189
189 // Callbacks for firing session events. Delegate to |app_|. 190 // Callbacks for firing session events. Delegate to |app_|.
190 void OnSessionMessage(const std::string& session_id, 191 void OnSessionMessage(const std::string& session_id,
191 MediaKeys::MessageType message_type, 192 MediaKeys::MessageType message_type,
192 const std::vector<uint8>& message, 193 const std::vector<uint8_t>& message,
193 const GURL& legacy_destination_url) { 194 const GURL& legacy_destination_url) {
194 app_->OnSessionMessage(session_id, message_type, message, 195 app_->OnSessionMessage(session_id, message_type, message,
195 legacy_destination_url); 196 legacy_destination_url, &decryptor_);
196 } 197 }
197 198
198 void OnSessionClosed(const std::string& session_id) { 199 void OnSessionClosed(const std::string& session_id) {
199 app_->OnSessionClosed(session_id); 200 app_->OnSessionClosed(session_id);
200 } 201 }
201 202
202 void OnSessionKeysChange(const std::string& session_id, 203 void OnSessionKeysChange(const std::string& session_id,
203 bool has_additional_usable_key, 204 bool has_additional_usable_key,
204 CdmKeysInfo keys_info) { 205 CdmKeysInfo keys_info) {
205 app_->OnSessionKeysChange(session_id, has_additional_usable_key, 206 app_->OnSessionKeysChange(session_id, has_additional_usable_key,
206 keys_info.Pass()); 207 keys_info.Pass());
207 } 208 }
208 209
209 void OnLegacySessionError(const std::string& session_id, 210 void OnLegacySessionError(const std::string& session_id,
210 const std::string& error_name, 211 const std::string& error_name,
211 uint32 system_code, 212 uint32_t system_code,
212 const std::string& error_message) { 213 const std::string& error_message) {
213 app_->OnLegacySessionError(session_id, error_name, system_code, 214 app_->OnLegacySessionError(session_id, error_name, system_code,
214 error_message); 215 error_message);
215 } 216 }
216 217
217 void OnEncryptedMediaInitData(EmeInitDataType init_data_type, 218 void OnEncryptedMediaInitData(EmeInitDataType init_data_type,
218 const std::vector<uint8>& init_data) { 219 const std::vector<uint8_t>& init_data) {
219 app_->OnEncryptedMediaInitData(init_data_type, init_data, &decryptor_); 220 app_->OnEncryptedMediaInitData(init_data_type, init_data, &decryptor_);
220 } 221 }
221 222
222 private: 223 private:
223 class TestCdmContext : public CdmContext { 224 class TestCdmContext : public CdmContext {
224 public: 225 public:
225 TestCdmContext(Decryptor* decryptor) : decryptor_(decryptor) {} 226 TestCdmContext(Decryptor* decryptor) : decryptor_(decryptor) {}
226 227
227 Decryptor* GetDecryptor() final { return decryptor_; } 228 Decryptor* GetDecryptor() final { return decryptor_; }
228 int GetCdmId() const final { return kInvalidCdmId; } 229 int GetCdmId() const final { return kInvalidCdmId; }
(...skipping 20 matching lines...) Expand all
249 EXPECT_GT(session_id.length(), 0ul); 250 EXPECT_GT(session_id.length(), 0ul);
250 current_session_id_ = session_id; 251 current_session_id_ = session_id;
251 } 252 }
252 253
253 void OnResolve(PromiseResult expected) { 254 void OnResolve(PromiseResult expected) {
254 EXPECT_EQ(expected, RESOLVED); 255 EXPECT_EQ(expected, RESOLVED);
255 } 256 }
256 257
257 void OnReject(PromiseResult expected, 258 void OnReject(PromiseResult expected,
258 media::MediaKeys::Exception exception_code, 259 media::MediaKeys::Exception exception_code,
259 uint32 system_code, 260 uint32_t system_code,
260 const std::string& error_message) { 261 const std::string& error_message) {
261 EXPECT_EQ(expected, REJECTED) << error_message; 262 EXPECT_EQ(expected, REJECTED) << error_message;
262 } 263 }
263 264
264 scoped_ptr<SimpleCdmPromise> CreatePromise(PromiseResult expected) { 265 scoped_ptr<SimpleCdmPromise> CreatePromise(PromiseResult expected) {
265 scoped_ptr<media::SimpleCdmPromise> promise(new media::CdmCallbackPromise<>( 266 scoped_ptr<media::SimpleCdmPromise> promise(new media::CdmCallbackPromise<>(
266 base::Bind( 267 base::Bind(
267 &KeyProvidingApp::OnResolve, base::Unretained(this), expected), 268 &KeyProvidingApp::OnResolve, base::Unretained(this), expected),
268 base::Bind( 269 base::Bind(
269 &KeyProvidingApp::OnReject, base::Unretained(this), expected))); 270 &KeyProvidingApp::OnReject, base::Unretained(this), expected)));
270 return promise.Pass(); 271 return promise.Pass();
271 } 272 }
272 273
273 scoped_ptr<NewSessionCdmPromise> CreateSessionPromise( 274 scoped_ptr<NewSessionCdmPromise> CreateSessionPromise(
274 PromiseResult expected) { 275 PromiseResult expected) {
275 scoped_ptr<media::NewSessionCdmPromise> promise( 276 scoped_ptr<media::NewSessionCdmPromise> promise(
276 new media::CdmCallbackPromise<std::string>( 277 new media::CdmCallbackPromise<std::string>(
277 base::Bind(&KeyProvidingApp::OnResolveWithSession, 278 base::Bind(&KeyProvidingApp::OnResolveWithSession,
278 base::Unretained(this), 279 base::Unretained(this),
279 expected), 280 expected),
280 base::Bind( 281 base::Bind(
281 &KeyProvidingApp::OnReject, base::Unretained(this), expected))); 282 &KeyProvidingApp::OnReject, base::Unretained(this), expected)));
282 return promise.Pass(); 283 return promise.Pass();
283 } 284 }
284 285
285 void OnSessionMessage(const std::string& session_id, 286 void OnSessionMessage(const std::string& session_id,
286 MediaKeys::MessageType message_type, 287 MediaKeys::MessageType message_type,
287 const std::vector<uint8>& message, 288 const std::vector<uint8_t>& message,
288 const GURL& legacy_destination_url) override { 289 const GURL& legacy_destination_url,
290 AesDecryptor* decryptor) override {
289 EXPECT_FALSE(session_id.empty()); 291 EXPECT_FALSE(session_id.empty());
290 EXPECT_FALSE(message.empty()); 292 EXPECT_FALSE(message.empty());
291 EXPECT_EQ(current_session_id_, session_id); 293 EXPECT_EQ(current_session_id_, session_id);
294 EXPECT_EQ(MediaKeys::MessageType::LICENSE_REQUEST, message_type);
295
296 // Extract the key ID from |message|. For Clear Key this is a JSON object
297 // containing a set of "kids". There should only be 1 key ID in |message|.
298 std::string message_string(message.begin(), message.end());
299 KeyIdList key_ids;
300 std::string error_message;
301 EXPECT_TRUE(ExtractKeyIdsFromKeyIdsInitData(message_string, &key_ids,
302 &error_message))
303 << error_message;
304 EXPECT_EQ(1u, key_ids.size());
305
306 // Determine the key that matches the key ID |key_ids[0]|.
307 std::vector<uint8_t> key;
308 EXPECT_TRUE(LookupKey(key_ids[0], &key));
309
310 // Update the session with the key ID and key.
311 std::string jwk =
312 GenerateJWKSet(vector_as_array(&key), key.size(),
313 vector_as_array(&key_ids[0]), key_ids[0].size());
314 decryptor->UpdateSession(session_id,
315 std::vector<uint8_t>(jwk.begin(), jwk.end()),
316 CreatePromise(RESOLVED));
292 } 317 }
293 318
294 void OnSessionClosed(const std::string& session_id) override { 319 void OnSessionClosed(const std::string& session_id) override {
295 EXPECT_EQ(current_session_id_, session_id); 320 EXPECT_EQ(current_session_id_, session_id);
296 } 321 }
297 322
298 void OnSessionKeysChange(const std::string& session_id, 323 void OnSessionKeysChange(const std::string& session_id,
299 bool has_additional_usable_key, 324 bool has_additional_usable_key,
300 CdmKeysInfo keys_info) override { 325 CdmKeysInfo keys_info) override {
301 EXPECT_EQ(current_session_id_, session_id); 326 EXPECT_EQ(current_session_id_, session_id);
302 EXPECT_EQ(has_additional_usable_key, true); 327 EXPECT_EQ(has_additional_usable_key, true);
303 } 328 }
304 329
305 void OnEncryptedMediaInitData(EmeInitDataType init_data_type, 330 void OnEncryptedMediaInitData(EmeInitDataType init_data_type,
306 const std::vector<uint8>& init_data, 331 const std::vector<uint8_t>& init_data,
307 AesDecryptor* decryptor) override { 332 AesDecryptor* decryptor) override {
308 // Since only 1 session is created, skip the request if the |init_data| 333 // Since only 1 session is created, skip the request if the |init_data|
309 // has been seen before (no need to add the same key again). 334 // has been seen before (no need to add the same key again).
310 if (init_data == prev_init_data_) 335 if (init_data == prev_init_data_)
311 return; 336 return;
312 prev_init_data_ = init_data; 337 prev_init_data_ = init_data;
313 338
314 if (current_session_id_.empty()) { 339 if (current_session_id_.empty()) {
315 if (init_data_type == EmeInitDataType::CENC) { 340 decryptor->CreateSessionAndGenerateRequest(
316 // Since the 'cenc' files are not created with proper 'pssh' boxes, 341 MediaKeys::TEMPORARY_SESSION, init_data_type, init_data,
317 // simply pretend that this is a webm file and pass the expected 342 CreateSessionPromise(RESOLVED));
318 // key ID as the init_data.
319 // http://crbug.com/460308
320 decryptor->CreateSessionAndGenerateRequest(
321 MediaKeys::TEMPORARY_SESSION, EmeInitDataType::WEBM,
322 std::vector<uint8>(kKeyId, kKeyId + arraysize(kKeyId)),
323 CreateSessionPromise(RESOLVED));
324 } else {
325 decryptor->CreateSessionAndGenerateRequest(
326 MediaKeys::TEMPORARY_SESSION, init_data_type, init_data,
327 CreateSessionPromise(RESOLVED));
328 }
329 EXPECT_FALSE(current_session_id_.empty()); 343 EXPECT_FALSE(current_session_id_.empty());
330 } 344 }
345 }
331 346
332 // Clear Key really needs the key ID from |init_data|. For WebM, they are 347 virtual bool LookupKey(const std::vector<uint8_t>& key_id,
333 // the same, but this is not the case for ISO CENC (key ID embedded in a 348 std::vector<uint8_t>* key) {
334 // 'pssh' box). Therefore, provide the correct key ID. 349 // As there is no key rotation, the key ID provided should be |kKeyId|
335 const uint8* key_id = vector_as_array(&init_data); 350 // which uses |kSecretKey| as the key.
336 size_t key_id_length = init_data.size(); 351 EXPECT_EQ(std::vector<uint8_t>(kKeyId, kKeyId + arraysize(kKeyId)), key_id);
337 if (init_data_type == EmeInitDataType::CENC) { 352 key->assign(kSecretKey, kSecretKey + arraysize(kSecretKey));
338 key_id = kKeyId; 353 return true;
339 key_id_length = arraysize(kKeyId);
340 }
341
342 // Convert key into a JSON structure and then add it.
343 std::string jwk = GenerateJWKSet(
344 kSecretKey, arraysize(kSecretKey), key_id, key_id_length);
345 decryptor->UpdateSession(current_session_id_,
346 std::vector<uint8>(jwk.begin(), jwk.end()),
347 CreatePromise(RESOLVED));
348 } 354 }
349 355
350 std::string current_session_id_; 356 std::string current_session_id_;
351 std::vector<uint8> prev_init_data_; 357 std::vector<uint8_t> prev_init_data_;
352 }; 358 };
353 359
354 class RotatingKeyProvidingApp : public KeyProvidingApp { 360 class RotatingKeyProvidingApp : public KeyProvidingApp {
355 public: 361 public:
356 RotatingKeyProvidingApp() : num_distint_need_key_calls_(0) {} 362 RotatingKeyProvidingApp() : num_distinct_need_key_calls_(0) {}
357 ~RotatingKeyProvidingApp() override { 363 ~RotatingKeyProvidingApp() override {
358 // Expect that OnEncryptedMediaInitData is fired multiple times with 364 // Expect that OnEncryptedMediaInitData is fired multiple times with
359 // different |init_data|. 365 // different |init_data|.
360 EXPECT_GT(num_distint_need_key_calls_, 1u); 366 EXPECT_GT(num_distinct_need_key_calls_, 1u);
361 } 367 }
362 368
363 void OnEncryptedMediaInitData(EmeInitDataType init_data_type, 369 void OnEncryptedMediaInitData(EmeInitDataType init_data_type,
364 const std::vector<uint8>& init_data, 370 const std::vector<uint8_t>& init_data,
365 AesDecryptor* decryptor) override { 371 AesDecryptor* decryptor) override {
366 // Skip the request if the |init_data| has been seen. 372 // Skip the request if the |init_data| has been seen.
367 if (init_data == prev_init_data_) 373 if (init_data == prev_init_data_)
368 return; 374 return;
369 prev_init_data_ = init_data; 375 prev_init_data_ = init_data;
370 ++num_distint_need_key_calls_; 376 ++num_distinct_need_key_calls_;
371 377
372 std::vector<uint8> key_id; 378 decryptor->CreateSessionAndGenerateRequest(MediaKeys::TEMPORARY_SESSION,
373 std::vector<uint8> key; 379 init_data_type, init_data,
374 EXPECT_TRUE(GetKeyAndKeyId(init_data, &key, &key_id)); 380 CreateSessionPromise(RESOLVED));
375
376 if (init_data_type == EmeInitDataType::CENC) {
377 // Since the 'cenc' files are not created with proper 'pssh' boxes,
378 // simply pretend that this is a webm file and pass the expected
379 // key ID as the init_data.
380 // http://crbug.com/460308
381 decryptor->CreateSessionAndGenerateRequest(
382 MediaKeys::TEMPORARY_SESSION, EmeInitDataType::WEBM, key_id,
383 CreateSessionPromise(RESOLVED));
384 } else {
385 decryptor->CreateSessionAndGenerateRequest(
386 MediaKeys::TEMPORARY_SESSION, init_data_type, init_data,
387 CreateSessionPromise(RESOLVED));
388 }
389
390 // Convert key into a JSON structure and then add it.
391 std::string jwk = GenerateJWKSet(vector_as_array(&key),
392 key.size(),
393 vector_as_array(&key_id),
394 key_id.size());
395 decryptor->UpdateSession(current_session_id_,
396 std::vector<uint8>(jwk.begin(), jwk.end()),
397 CreatePromise(RESOLVED));
398 } 381 }
399 382
400 private: 383 bool LookupKey(const std::vector<uint8_t>& key_id,
401 bool GetKeyAndKeyId(std::vector<uint8> init_data, 384 std::vector<uint8_t>* key) override {
402 std::vector<uint8>* key,
403 std::vector<uint8>* key_id) {
404 // For WebM, init_data is key_id; for ISO CENC, init_data should contain
405 // the key_id. We assume key_id is in the end of init_data here (that is
406 // only a reasonable assumption for WebM and clear key ISO CENC).
407 DCHECK_GE(init_data.size(), arraysize(kKeyId));
408 std::vector<uint8> key_id_from_init_data(
409 init_data.end() - arraysize(kKeyId), init_data.end());
410
411 key->assign(kSecretKey, kSecretKey + arraysize(kSecretKey));
412 key_id->assign(kKeyId, kKeyId + arraysize(kKeyId));
413
414 // The Key and KeyId for this testing key provider are created by left 385 // The Key and KeyId for this testing key provider are created by left
415 // rotating kSecretKey and kKeyId. Note that this implementation is only 386 // rotating |kSecretKey| and |kKeyId|. Note that this implementation is
416 // intended for testing purpose. The actual key rotation algorithm can be 387 // only intended for testing purpose. The actual key rotation algorithm
417 // much more complicated. 388 // can be much more complicated.
418 // Find out the rotating position from |key_id_from_init_data| and apply on 389 // Find out the rotating position from |starting_key_id| and apply on |key|.
419 // |key|. 390 std::vector<uint8_t> starting_key_id(kKeyId, kKeyId + arraysize(kKeyId));
420 for (size_t pos = 0; pos < arraysize(kKeyId); ++pos) { 391 for (size_t pos = 0; pos < starting_key_id.size(); ++pos) {
421 std::rotate(key_id->begin(), key_id->begin() + pos, key_id->end()); 392 std::rotate(starting_key_id.begin(), starting_key_id.begin() + pos,
422 if (*key_id == key_id_from_init_data) { 393 starting_key_id.end());
394 if (key_id == starting_key_id) {
395 key->assign(kSecretKey, kSecretKey + arraysize(kSecretKey));
423 std::rotate(key->begin(), key->begin() + pos, key->end()); 396 std::rotate(key->begin(), key->begin() + pos, key->end());
424 return true; 397 return true;
425 } 398 }
426 } 399 }
427 return false; 400 return false;
428 } 401 }
429 402
430 std::vector<uint8> prev_init_data_; 403 uint32_t num_distinct_need_key_calls_;
431 uint32 num_distint_need_key_calls_;
432 }; 404 };
433 405
434 // Ignores needkey and does not perform a license request 406 // Ignores needkey and does not perform a license request
435 class NoResponseApp : public FakeEncryptedMedia::AppBase { 407 class NoResponseApp : public FakeEncryptedMedia::AppBase {
436 public: 408 public:
437 void OnSessionMessage(const std::string& session_id, 409 void OnSessionMessage(const std::string& session_id,
438 MediaKeys::MessageType message_type, 410 MediaKeys::MessageType message_type,
439 const std::vector<uint8>& message, 411 const std::vector<uint8_t>& message,
440 const GURL& legacy_destination_url) override { 412 const GURL& legacy_destination_url,
413 AesDecryptor* decryptor) override {
441 EXPECT_FALSE(session_id.empty()); 414 EXPECT_FALSE(session_id.empty());
442 EXPECT_FALSE(message.empty()); 415 EXPECT_FALSE(message.empty());
443 FAIL() << "Unexpected Message"; 416 FAIL() << "Unexpected Message";
444 } 417 }
445 418
446 void OnSessionClosed(const std::string& session_id) override { 419 void OnSessionClosed(const std::string& session_id) override {
447 EXPECT_FALSE(session_id.empty()); 420 EXPECT_FALSE(session_id.empty());
448 FAIL() << "Unexpected Closed"; 421 FAIL() << "Unexpected Closed";
449 } 422 }
450 423
451 void OnSessionKeysChange(const std::string& session_id, 424 void OnSessionKeysChange(const std::string& session_id,
452 bool has_additional_usable_key, 425 bool has_additional_usable_key,
453 CdmKeysInfo keys_info) override { 426 CdmKeysInfo keys_info) override {
454 EXPECT_FALSE(session_id.empty()); 427 EXPECT_FALSE(session_id.empty());
455 EXPECT_EQ(has_additional_usable_key, true); 428 EXPECT_EQ(has_additional_usable_key, true);
456 } 429 }
457 430
458 void OnEncryptedMediaInitData(EmeInitDataType init_data_type, 431 void OnEncryptedMediaInitData(EmeInitDataType init_data_type,
459 const std::vector<uint8>& init_data, 432 const std::vector<uint8_t>& init_data,
460 AesDecryptor* decryptor) override {} 433 AesDecryptor* decryptor) override {}
461 }; 434 };
462 435
463 // Helper class that emulates calls made on the ChunkDemuxer by the 436 // Helper class that emulates calls made on the ChunkDemuxer by the
464 // Media Source API. 437 // Media Source API.
465 class MockMediaSource { 438 class MockMediaSource {
466 public: 439 public:
467 MockMediaSource(const std::string& filename, 440 MockMediaSource(const std::string& filename,
468 const std::string& mimetype, 441 const std::string& mimetype,
469 int initial_append_size) 442 int initial_append_size)
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 490
518 chunk_demuxer_->AppendData( 491 chunk_demuxer_->AppendData(
519 kSourceId, file_data_->data() + current_position_, size, 492 kSourceId, file_data_->data() + current_position_, size,
520 base::TimeDelta(), kInfiniteDuration(), &last_timestamp_offset_, 493 base::TimeDelta(), kInfiniteDuration(), &last_timestamp_offset_,
521 base::Bind(&MockMediaSource::InitSegmentReceived, 494 base::Bind(&MockMediaSource::InitSegmentReceived,
522 base::Unretained(this))); 495 base::Unretained(this)));
523 current_position_ += size; 496 current_position_ += size;
524 } 497 }
525 498
526 void AppendAtTime(base::TimeDelta timestamp_offset, 499 void AppendAtTime(base::TimeDelta timestamp_offset,
527 const uint8* pData, 500 const uint8_t* pData,
528 int size) { 501 int size) {
529 CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId)); 502 CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId));
530 chunk_demuxer_->AppendData(kSourceId, pData, size, 503 chunk_demuxer_->AppendData(kSourceId, pData, size,
531 base::TimeDelta(), kInfiniteDuration(), 504 base::TimeDelta(), kInfiniteDuration(),
532 &timestamp_offset, 505 &timestamp_offset,
533 base::Bind(&MockMediaSource::InitSegmentReceived, 506 base::Bind(&MockMediaSource::InitSegmentReceived,
534 base::Unretained(this))); 507 base::Unretained(this)));
535 last_timestamp_offset_ = timestamp_offset; 508 last_timestamp_offset_ = timestamp_offset;
536 } 509 }
537 510
538 void AppendAtTimeWithWindow(base::TimeDelta timestamp_offset, 511 void AppendAtTimeWithWindow(base::TimeDelta timestamp_offset,
539 base::TimeDelta append_window_start, 512 base::TimeDelta append_window_start,
540 base::TimeDelta append_window_end, 513 base::TimeDelta append_window_end,
541 const uint8* pData, 514 const uint8_t* pData,
542 int size) { 515 int size) {
543 CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId)); 516 CHECK(!chunk_demuxer_->IsParsingMediaSegment(kSourceId));
544 chunk_demuxer_->AppendData(kSourceId, 517 chunk_demuxer_->AppendData(kSourceId,
545 pData, 518 pData,
546 size, 519 size,
547 append_window_start, 520 append_window_start,
548 append_window_end, 521 append_window_end,
549 &timestamp_offset, 522 &timestamp_offset,
550 base::Bind(&MockMediaSource::InitSegmentReceived, 523 base::Bind(&MockMediaSource::InitSegmentReceived,
551 base::Unretained(this))); 524 base::Unretained(this)));
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 codecs_param_end - codecs_param_start); 566 codecs_param_end - codecs_param_start);
594 Tokenize(codecs_param, ",", &codecs); 567 Tokenize(codecs_param, ",", &codecs);
595 } 568 }
596 569
597 CHECK_EQ(chunk_demuxer_->AddId(kSourceId, type, codecs), ChunkDemuxer::kOk); 570 CHECK_EQ(chunk_demuxer_->AddId(kSourceId, type, codecs), ChunkDemuxer::kOk);
598 571
599 AppendData(initial_append_size_); 572 AppendData(initial_append_size_);
600 } 573 }
601 574
602 void OnEncryptedMediaInitData(EmeInitDataType init_data_type, 575 void OnEncryptedMediaInitData(EmeInitDataType init_data_type,
603 const std::vector<uint8>& init_data) { 576 const std::vector<uint8_t>& init_data) {
604 DCHECK(!init_data.empty()); 577 DCHECK(!init_data.empty());
605 CHECK(!encrypted_media_init_data_cb_.is_null()); 578 CHECK(!encrypted_media_init_data_cb_.is_null());
606 encrypted_media_init_data_cb_.Run(init_data_type, init_data); 579 encrypted_media_init_data_cb_.Run(init_data_type, init_data);
607 } 580 }
608 581
609 base::TimeDelta last_timestamp_offset() const { 582 base::TimeDelta last_timestamp_offset() const {
610 return last_timestamp_offset_; 583 return last_timestamp_offset_;
611 } 584 }
612 585
613 MOCK_METHOD0(InitSegmentReceived, void(void)); 586 MOCK_METHOD0(InitSegmentReceived, void(void));
(...skipping 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1740 1713
1741 TEST_F(PipelineIntegrationTest, BasicPlaybackPositiveStartTime) { 1714 TEST_F(PipelineIntegrationTest, BasicPlaybackPositiveStartTime) {
1742 ASSERT_EQ(PIPELINE_OK, Start("nonzero-start-time.webm")); 1715 ASSERT_EQ(PIPELINE_OK, Start("nonzero-start-time.webm"));
1743 Play(); 1716 Play();
1744 ASSERT_TRUE(WaitUntilOnEnded()); 1717 ASSERT_TRUE(WaitUntilOnEnded());
1745 ASSERT_EQ(base::TimeDelta::FromMicroseconds(396000), 1718 ASSERT_EQ(base::TimeDelta::FromMicroseconds(396000),
1746 demuxer_->GetStartTime()); 1719 demuxer_->GetStartTime());
1747 } 1720 }
1748 1721
1749 } // namespace media 1722 } // namespace media
OLDNEW
« no previous file with comments | « media/test/data/bear-640x360-v_frag-cenc-key_rotation.mp4 ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698