OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/cdm/ppapi/external_clear_key/clear_key_cdm.h" | 5 #include "media/cdm/ppapi/external_clear_key/clear_key_cdm.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cstring> | 8 #include <cstring> |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/time/time.h" | 13 #include "base/time/time.h" |
14 #include "base/trace_event/trace_event.h" | 14 #include "base/trace_event/trace_event.h" |
15 #include "media/base/cdm_callback_promise.h" | 15 #include "media/base/cdm_callback_promise.h" |
16 #include "media/base/cdm_key_information.h" | 16 #include "media/base/cdm_key_information.h" |
17 #include "media/base/decoder_buffer.h" | 17 #include "media/base/decoder_buffer.h" |
18 #include "media/base/decrypt_config.h" | 18 #include "media/base/decrypt_config.h" |
19 #include "media/base/key_systems.h" | 19 #include "media/base/key_systems.h" |
20 #include "media/cdm/json_web_key.h" | 20 #include "media/cdm/json_web_key.h" |
21 #include "media/cdm/ppapi/cdm_file_io_test.h" | 21 #include "media/cdm/ppapi/cdm_file_io_test.h" |
22 #include "media/cdm/ppapi/external_clear_key/cdm_video_decoder.h" | 22 #include "media/cdm/ppapi/external_clear_key/cdm_video_decoder.h" |
23 #include "url/gurl.h" | 23 #include "url/gurl.h" |
24 | 24 |
25 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) | 25 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) |
26 #include "base/basictypes.h" | 26 const int64_t kNoTimestamp = INT64_MIN; |
27 const int64 kNoTimestamp = kint64min; | |
28 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER | 27 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER |
29 | 28 |
30 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) | 29 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) |
31 #include "base/at_exit.h" | 30 #include "base/at_exit.h" |
32 #include "base/files/file_path.h" | 31 #include "base/files/file_path.h" |
33 #include "base/path_service.h" | 32 #include "base/path_service.h" |
34 #include "media/base/media.h" | 33 #include "media/base/media.h" |
35 #include "media/cdm/ppapi/external_clear_key/ffmpeg_cdm_audio_decoder.h" | 34 #include "media/cdm/ppapi/external_clear_key/ffmpeg_cdm_audio_decoder.h" |
36 #include "media/cdm/ppapi/external_clear_key/ffmpeg_cdm_video_decoder.h" | 35 #include "media/cdm/ppapi/external_clear_key/ffmpeg_cdm_video_decoder.h" |
37 | 36 |
(...skipping 24 matching lines...) Expand all Loading... |
62 "org.chromium.externalclearkey.decryptonly"; | 61 "org.chromium.externalclearkey.decryptonly"; |
63 const char kExternalClearKeyFileIOTestKeySystem[] = | 62 const char kExternalClearKeyFileIOTestKeySystem[] = |
64 "org.chromium.externalclearkey.fileiotest"; | 63 "org.chromium.externalclearkey.fileiotest"; |
65 const char kExternalClearKeyCrashKeySystem[] = | 64 const char kExternalClearKeyCrashKeySystem[] = |
66 "org.chromium.externalclearkey.crash"; | 65 "org.chromium.externalclearkey.crash"; |
67 | 66 |
68 // Constants for the enumalted session that can be loaded by LoadSession(). | 67 // Constants for the enumalted session that can be loaded by LoadSession(). |
69 // These constants need to be in sync with | 68 // These constants need to be in sync with |
70 // chrome/test/data/media/encrypted_media_utils.js | 69 // chrome/test/data/media/encrypted_media_utils.js |
71 const char kLoadableSessionId[] = "LoadableSession"; | 70 const char kLoadableSessionId[] = "LoadableSession"; |
72 const uint8 kLoadableSessionKeyId[] = "0123456789012345"; | 71 const uint8_t kLoadableSessionKeyId[] = "0123456789012345"; |
73 const uint8 kLoadableSessionKey[] = | 72 const uint8_t kLoadableSessionKey[] = {0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, |
74 {0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b, | 73 0xd2, 0x7b, 0x68, 0xef, 0x12, 0x2a, |
75 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c}; | 74 0xfc, 0xe4, 0xae, 0x3c}; |
76 | 75 |
77 const int64 kSecondsPerMinute = 60; | 76 const int64_t kSecondsPerMinute = 60; |
78 const int64 kMsPerSecond = 1000; | 77 const int64_t kMsPerSecond = 1000; |
79 const int64 kInitialTimerDelayMs = 200; | 78 const int64_t kInitialTimerDelayMs = 200; |
80 const int64 kMaxTimerDelayMs = 1 * kSecondsPerMinute * kMsPerSecond; | 79 const int64_t kMaxTimerDelayMs = 1 * kSecondsPerMinute * kMsPerSecond; |
81 // Renewal message header. For prefixed EME, if a key message starts with | 80 // Renewal message header. For prefixed EME, if a key message starts with |
82 // |kRenewalHeader|, it's a renewal message. Otherwise, it's a key request. | 81 // |kRenewalHeader|, it's a renewal message. Otherwise, it's a key request. |
83 // FIXME(jrummell): Remove this once prefixed EME goes away. | 82 // FIXME(jrummell): Remove this once prefixed EME goes away. |
84 const char kRenewalHeader[] = "RENEWAL"; | 83 const char kRenewalHeader[] = "RENEWAL"; |
85 // CDM file IO test result header. | 84 // CDM file IO test result header. |
86 const char kFileIOTestResultHeader[] = "FILEIOTESTRESULT"; | 85 const char kFileIOTestResultHeader[] = "FILEIOTESTRESULT"; |
87 | 86 |
88 // Copies |input_buffer| into a media::DecoderBuffer. If the |input_buffer| is | 87 // Copies |input_buffer| into a media::DecoderBuffer. If the |input_buffer| is |
89 // empty, an empty (end-of-stream) media::DecoderBuffer is returned. | 88 // empty, an empty (end-of-stream) media::DecoderBuffer is returned. |
90 static scoped_refptr<media::DecoderBuffer> CopyDecoderBufferFrom( | 89 static scoped_refptr<media::DecoderBuffer> CopyDecoderBufferFrom( |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 | 280 |
282 ClearKeyCdm::~ClearKeyCdm() {} | 281 ClearKeyCdm::~ClearKeyCdm() {} |
283 | 282 |
284 void ClearKeyCdm::Initialize(bool /* allow_distinctive_identifier */, | 283 void ClearKeyCdm::Initialize(bool /* allow_distinctive_identifier */, |
285 bool /* allow_persistent_state */) { | 284 bool /* allow_persistent_state */) { |
286 // Implementation doesn't use distinctive identifier nor save persistent data, | 285 // Implementation doesn't use distinctive identifier nor save persistent data, |
287 // so nothing to do with these values. | 286 // so nothing to do with these values. |
288 } | 287 } |
289 | 288 |
290 void ClearKeyCdm::CreateSessionAndGenerateRequest( | 289 void ClearKeyCdm::CreateSessionAndGenerateRequest( |
291 uint32 promise_id, | 290 uint32_t promise_id, |
292 cdm::SessionType session_type, | 291 cdm::SessionType session_type, |
293 cdm::InitDataType init_data_type, | 292 cdm::InitDataType init_data_type, |
294 const uint8* init_data, | 293 const uint8_t* init_data, |
295 uint32 init_data_size) { | 294 uint32_t init_data_size) { |
296 DVLOG(1) << __FUNCTION__; | 295 DVLOG(1) << __FUNCTION__; |
297 | 296 |
298 scoped_ptr<media::NewSessionCdmPromise> promise( | 297 scoped_ptr<media::NewSessionCdmPromise> promise( |
299 new media::CdmCallbackPromise<std::string>( | 298 new media::CdmCallbackPromise<std::string>( |
300 base::Bind(&ClearKeyCdm::OnSessionCreated, | 299 base::Bind(&ClearKeyCdm::OnSessionCreated, |
301 base::Unretained(this), | 300 base::Unretained(this), |
302 promise_id), | 301 promise_id), |
303 base::Bind(&ClearKeyCdm::OnPromiseFailed, | 302 base::Bind(&ClearKeyCdm::OnPromiseFailed, |
304 base::Unretained(this), | 303 base::Unretained(this), |
305 promise_id))); | 304 promise_id))); |
306 decryptor_->CreateSessionAndGenerateRequest( | 305 decryptor_->CreateSessionAndGenerateRequest( |
307 ConvertSessionType(session_type), ConvertInitDataType(init_data_type), | 306 ConvertSessionType(session_type), ConvertInitDataType(init_data_type), |
308 std::vector<uint8_t>(init_data, init_data + init_data_size), | 307 std::vector<uint8_t>(init_data, init_data + init_data_size), |
309 promise.Pass()); | 308 promise.Pass()); |
310 | 309 |
311 if (key_system_ == kExternalClearKeyFileIOTestKeySystem) | 310 if (key_system_ == kExternalClearKeyFileIOTestKeySystem) |
312 StartFileIOTest(); | 311 StartFileIOTest(); |
313 } | 312 } |
314 | 313 |
315 // Loads a emulated stored session. Currently only |kLoadableSessionId| | 314 // Loads a emulated stored session. Currently only |kLoadableSessionId| |
316 // (containing a |kLoadableSessionKey| for |kLoadableSessionKeyId|) is | 315 // (containing a |kLoadableSessionKey| for |kLoadableSessionKeyId|) is |
317 // supported. | 316 // supported. |
318 void ClearKeyCdm::LoadSession(uint32 promise_id, | 317 void ClearKeyCdm::LoadSession(uint32_t promise_id, |
319 cdm::SessionType session_type, | 318 cdm::SessionType session_type, |
320 const char* session_id, | 319 const char* session_id, |
321 uint32_t session_id_length) { | 320 uint32_t session_id_length) { |
322 DVLOG(1) << __FUNCTION__; | 321 DVLOG(1) << __FUNCTION__; |
323 DCHECK_EQ(session_type, cdm::kPersistentLicense); | 322 DCHECK_EQ(session_type, cdm::kPersistentLicense); |
324 | 323 |
325 if (std::string(kLoadableSessionId) != | 324 if (std::string(kLoadableSessionId) != |
326 std::string(session_id, session_id_length)) { | 325 std::string(session_id, session_id_length)) { |
327 host_->OnResolveNewSessionPromise(promise_id, nullptr, 0); | 326 host_->OnResolveNewSessionPromise(promise_id, nullptr, 0); |
328 return; | 327 return; |
329 } | 328 } |
330 | 329 |
331 // Only allowed to successfully load this session once. | 330 // Only allowed to successfully load this session once. |
332 DCHECK(session_id_for_emulated_loadsession_.empty()); | 331 DCHECK(session_id_for_emulated_loadsession_.empty()); |
333 | 332 |
334 scoped_ptr<media::NewSessionCdmPromise> promise( | 333 scoped_ptr<media::NewSessionCdmPromise> promise( |
335 new media::CdmCallbackPromise<std::string>( | 334 new media::CdmCallbackPromise<std::string>( |
336 base::Bind(&ClearKeyCdm::OnSessionLoaded, | 335 base::Bind(&ClearKeyCdm::OnSessionLoaded, |
337 base::Unretained(this), | 336 base::Unretained(this), |
338 promise_id), | 337 promise_id), |
339 base::Bind(&ClearKeyCdm::OnPromiseFailed, | 338 base::Bind(&ClearKeyCdm::OnPromiseFailed, |
340 base::Unretained(this), | 339 base::Unretained(this), |
341 promise_id))); | 340 promise_id))); |
342 decryptor_->CreateSessionAndGenerateRequest( | 341 decryptor_->CreateSessionAndGenerateRequest( |
343 MediaKeys::TEMPORARY_SESSION, EmeInitDataType::WEBM, | 342 MediaKeys::TEMPORARY_SESSION, EmeInitDataType::WEBM, |
344 std::vector<uint8_t>(), promise.Pass()); | 343 std::vector<uint8_t>(), promise.Pass()); |
345 } | 344 } |
346 | 345 |
347 void ClearKeyCdm::UpdateSession(uint32 promise_id, | 346 void ClearKeyCdm::UpdateSession(uint32_t promise_id, |
348 const char* session_id, | 347 const char* session_id, |
349 uint32_t session_id_length, | 348 uint32_t session_id_length, |
350 const uint8* response, | 349 const uint8_t* response, |
351 uint32 response_size) { | 350 uint32_t response_size) { |
352 DVLOG(1) << __FUNCTION__; | 351 DVLOG(1) << __FUNCTION__; |
353 std::string web_session_str(session_id, session_id_length); | 352 std::string web_session_str(session_id, session_id_length); |
354 | 353 |
355 // If updating the loadable session, use the actual session id generated. | 354 // If updating the loadable session, use the actual session id generated. |
356 if (web_session_str == std::string(kLoadableSessionId)) | 355 if (web_session_str == std::string(kLoadableSessionId)) |
357 web_session_str = session_id_for_emulated_loadsession_; | 356 web_session_str = session_id_for_emulated_loadsession_; |
358 | 357 |
359 scoped_ptr<media::SimpleCdmPromise> promise(new media::CdmCallbackPromise<>( | 358 scoped_ptr<media::SimpleCdmPromise> promise(new media::CdmCallbackPromise<>( |
360 base::Bind(&ClearKeyCdm::OnPromiseResolved, base::Unretained(this), | 359 base::Bind(&ClearKeyCdm::OnPromiseResolved, base::Unretained(this), |
361 promise_id), | 360 promise_id), |
362 base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), | 361 base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), |
363 promise_id))); | 362 promise_id))); |
364 decryptor_->UpdateSession( | 363 decryptor_->UpdateSession( |
365 web_session_str, std::vector<uint8_t>(response, response + response_size), | 364 web_session_str, std::vector<uint8_t>(response, response + response_size), |
366 promise.Pass()); | 365 promise.Pass()); |
367 | 366 |
368 if (!renewal_timer_set_) { | 367 if (!renewal_timer_set_) { |
369 ScheduleNextRenewal(); | 368 ScheduleNextRenewal(); |
370 renewal_timer_set_ = true; | 369 renewal_timer_set_ = true; |
371 } | 370 } |
372 } | 371 } |
373 | 372 |
374 void ClearKeyCdm::CloseSession(uint32 promise_id, | 373 void ClearKeyCdm::CloseSession(uint32_t promise_id, |
375 const char* session_id, | 374 const char* session_id, |
376 uint32_t session_id_length) { | 375 uint32_t session_id_length) { |
377 DVLOG(1) << __FUNCTION__; | 376 DVLOG(1) << __FUNCTION__; |
378 std::string web_session_str(session_id, session_id_length); | 377 std::string web_session_str(session_id, session_id_length); |
379 | 378 |
380 // If closing the loadable session, use the actual session id generated. | 379 // If closing the loadable session, use the actual session id generated. |
381 if (web_session_str == std::string(kLoadableSessionId)) | 380 if (web_session_str == std::string(kLoadableSessionId)) |
382 web_session_str = session_id_for_emulated_loadsession_; | 381 web_session_str = session_id_for_emulated_loadsession_; |
383 | 382 |
384 scoped_ptr<media::SimpleCdmPromise> promise(new media::CdmCallbackPromise<>( | 383 scoped_ptr<media::SimpleCdmPromise> promise(new media::CdmCallbackPromise<>( |
385 base::Bind( | 384 base::Bind( |
386 &ClearKeyCdm::OnPromiseResolved, base::Unretained(this), promise_id), | 385 &ClearKeyCdm::OnPromiseResolved, base::Unretained(this), promise_id), |
387 base::Bind( | 386 base::Bind( |
388 &ClearKeyCdm::OnPromiseFailed, base::Unretained(this), promise_id))); | 387 &ClearKeyCdm::OnPromiseFailed, base::Unretained(this), promise_id))); |
389 decryptor_->CloseSession(web_session_str, promise.Pass()); | 388 decryptor_->CloseSession(web_session_str, promise.Pass()); |
390 } | 389 } |
391 | 390 |
392 void ClearKeyCdm::RemoveSession(uint32 promise_id, | 391 void ClearKeyCdm::RemoveSession(uint32_t promise_id, |
393 const char* session_id, | 392 const char* session_id, |
394 uint32_t session_id_length) { | 393 uint32_t session_id_length) { |
395 DVLOG(1) << __FUNCTION__; | 394 DVLOG(1) << __FUNCTION__; |
396 std::string web_session_str(session_id, session_id_length); | 395 std::string web_session_str(session_id, session_id_length); |
397 | 396 |
398 // RemoveSession only allowed for the loadable session. | 397 // RemoveSession only allowed for the loadable session. |
399 if (web_session_str == std::string(kLoadableSessionId)) { | 398 if (web_session_str == std::string(kLoadableSessionId)) { |
400 web_session_str = session_id_for_emulated_loadsession_; | 399 web_session_str = session_id_for_emulated_loadsession_; |
401 } else { | 400 } else { |
402 // TODO(jrummell): This should be a DCHECK once blink does the proper | 401 // TODO(jrummell): This should be a DCHECK once blink does the proper |
403 // checks. | 402 // checks. |
404 std::string message("Not supported for non-persistent sessions."); | 403 std::string message("Not supported for non-persistent sessions."); |
405 host_->OnRejectPromise(promise_id, | 404 host_->OnRejectPromise(promise_id, |
406 cdm::kInvalidAccessError, | 405 cdm::kInvalidAccessError, |
407 0, | 406 0, |
408 message.data(), | 407 message.data(), |
409 message.length()); | 408 message.length()); |
410 return; | 409 return; |
411 } | 410 } |
412 | 411 |
413 scoped_ptr<media::SimpleCdmPromise> promise(new media::CdmCallbackPromise<>( | 412 scoped_ptr<media::SimpleCdmPromise> promise(new media::CdmCallbackPromise<>( |
414 base::Bind(&ClearKeyCdm::OnPromiseResolved, base::Unretained(this), | 413 base::Bind(&ClearKeyCdm::OnPromiseResolved, base::Unretained(this), |
415 promise_id), | 414 promise_id), |
416 base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), | 415 base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), |
417 promise_id))); | 416 promise_id))); |
418 decryptor_->RemoveSession(web_session_str, promise.Pass()); | 417 decryptor_->RemoveSession(web_session_str, promise.Pass()); |
419 } | 418 } |
420 | 419 |
421 void ClearKeyCdm::SetServerCertificate(uint32 promise_id, | 420 void ClearKeyCdm::SetServerCertificate(uint32_t promise_id, |
422 const uint8_t* server_certificate_data, | 421 const uint8_t* server_certificate_data, |
423 uint32_t server_certificate_data_size) { | 422 uint32_t server_certificate_data_size) { |
424 // ClearKey doesn't use a server certificate. | 423 // ClearKey doesn't use a server certificate. |
425 host_->OnResolvePromise(promise_id); | 424 host_->OnResolvePromise(promise_id); |
426 } | 425 } |
427 | 426 |
428 void ClearKeyCdm::TimerExpired(void* context) { | 427 void ClearKeyCdm::TimerExpired(void* context) { |
429 if (context == &session_id_for_emulated_loadsession_) { | 428 if (context == &session_id_for_emulated_loadsession_) { |
430 LoadLoadableSession(); | 429 LoadLoadableSession(); |
431 return; | 430 return; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 int32_t size = 0; | 608 int32_t size = 0; |
610 int64_t timestamp = 0; | 609 int64_t timestamp = 0; |
611 if (!buffer->end_of_stream()) { | 610 if (!buffer->end_of_stream()) { |
612 data = buffer->data(); | 611 data = buffer->data(); |
613 size = buffer->data_size(); | 612 size = buffer->data_size(); |
614 timestamp = encrypted_buffer.timestamp; | 613 timestamp = encrypted_buffer.timestamp; |
615 } | 614 } |
616 | 615 |
617 return audio_decoder_->DecodeBuffer(data, size, timestamp, audio_frames); | 616 return audio_decoder_->DecodeBuffer(data, size, timestamp, audio_frames); |
618 #elif defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) | 617 #elif defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) |
619 int64 timestamp_in_microseconds = kNoTimestamp; | 618 int64_t timestamp_in_microseconds = kNoTimestamp; |
620 if (!buffer->end_of_stream()) { | 619 if (!buffer->end_of_stream()) { |
621 timestamp_in_microseconds = buffer->GetTimestamp().InMicroseconds(); | 620 timestamp_in_microseconds = buffer->GetTimestamp().InMicroseconds(); |
622 DCHECK(timestamp_in_microseconds != kNoTimestamp); | 621 DCHECK(timestamp_in_microseconds != kNoTimestamp); |
623 } | 622 } |
624 return GenerateFakeAudioFrames(timestamp_in_microseconds, audio_frames); | 623 return GenerateFakeAudioFrames(timestamp_in_microseconds, audio_frames); |
625 #else | 624 #else |
626 return cdm::kSuccess; | 625 return cdm::kSuccess; |
627 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER | 626 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER |
628 } | 627 } |
629 | 628 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 base::Bind(&ClearKeyCdm::OnLoadSessionUpdated, base::Unretained(this)), | 697 base::Bind(&ClearKeyCdm::OnLoadSessionUpdated, base::Unretained(this)), |
699 base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), | 698 base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), |
700 promise_id_for_emulated_loadsession_))); | 699 promise_id_for_emulated_loadsession_))); |
701 decryptor_->UpdateSession( | 700 decryptor_->UpdateSession( |
702 session_id_for_emulated_loadsession_, | 701 session_id_for_emulated_loadsession_, |
703 std::vector<uint8_t>(jwk_set.begin(), jwk_set.end()), promise.Pass()); | 702 std::vector<uint8_t>(jwk_set.begin(), jwk_set.end()), promise.Pass()); |
704 } | 703 } |
705 | 704 |
706 void ClearKeyCdm::OnSessionMessage(const std::string& session_id, | 705 void ClearKeyCdm::OnSessionMessage(const std::string& session_id, |
707 MediaKeys::MessageType message_type, | 706 MediaKeys::MessageType message_type, |
708 const std::vector<uint8>& message, | 707 const std::vector<uint8_t>& message, |
709 const GURL& legacy_destination_url) { | 708 const GURL& legacy_destination_url) { |
710 DVLOG(1) << "OnSessionMessage: " << message.size(); | 709 DVLOG(1) << "OnSessionMessage: " << message.size(); |
711 | 710 |
712 // Ignore the message when we are waiting to update the loadable session. | 711 // Ignore the message when we are waiting to update the loadable session. |
713 if (session_id == session_id_for_emulated_loadsession_) | 712 if (session_id == session_id_for_emulated_loadsession_) |
714 return; | 713 return; |
715 | 714 |
716 // OnSessionMessage() only called during CreateSession(), so no promise | 715 // OnSessionMessage() only called during CreateSession(), so no promise |
717 // involved (OnSessionCreated() called to resolve the CreateSession() | 716 // involved (OnSessionCreated() called to resolve the CreateSession() |
718 // promise). | 717 // promise). |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 keys_vector.size()); | 749 keys_vector.size()); |
751 } | 750 } |
752 | 751 |
753 void ClearKeyCdm::OnSessionClosed(const std::string& session_id) { | 752 void ClearKeyCdm::OnSessionClosed(const std::string& session_id) { |
754 std::string new_session_id = session_id; | 753 std::string new_session_id = session_id; |
755 if (new_session_id == session_id_for_emulated_loadsession_) | 754 if (new_session_id == session_id_for_emulated_loadsession_) |
756 new_session_id = std::string(kLoadableSessionId); | 755 new_session_id = std::string(kLoadableSessionId); |
757 host_->OnSessionClosed(new_session_id.data(), new_session_id.length()); | 756 host_->OnSessionClosed(new_session_id.data(), new_session_id.length()); |
758 } | 757 } |
759 | 758 |
760 void ClearKeyCdm::OnSessionCreated(uint32 promise_id, | 759 void ClearKeyCdm::OnSessionCreated(uint32_t promise_id, |
761 const std::string& session_id) { | 760 const std::string& session_id) { |
762 // Save the latest session ID for renewal and file IO test messages. | 761 // Save the latest session ID for renewal and file IO test messages. |
763 last_session_id_ = session_id; | 762 last_session_id_ = session_id; |
764 | 763 |
765 host_->OnResolveNewSessionPromise(promise_id, session_id.data(), | 764 host_->OnResolveNewSessionPromise(promise_id, session_id.data(), |
766 session_id.length()); | 765 session_id.length()); |
767 } | 766 } |
768 | 767 |
769 void ClearKeyCdm::OnSessionLoaded(uint32 promise_id, | 768 void ClearKeyCdm::OnSessionLoaded(uint32_t promise_id, |
770 const std::string& session_id) { | 769 const std::string& session_id) { |
771 // Save the latest session ID for renewal and file IO test messages. | 770 // Save the latest session ID for renewal and file IO test messages. |
772 last_session_id_ = session_id; | 771 last_session_id_ = session_id; |
773 | 772 |
774 // |decryptor_| created some session as |session_id|, but going forward | 773 // |decryptor_| created some session as |session_id|, but going forward |
775 // we need to map that to |kLoadableSessionId|, as that is what callers | 774 // we need to map that to |kLoadableSessionId|, as that is what callers |
776 // expect. | 775 // expect. |
777 session_id_for_emulated_loadsession_ = session_id; | 776 session_id_for_emulated_loadsession_ = session_id; |
778 | 777 |
779 // Delay LoadLoadableSession() to test the case where Decrypt*() calls are | 778 // Delay LoadLoadableSession() to test the case where Decrypt*() calls are |
780 // made before the session is fully loaded. | 779 // made before the session is fully loaded. |
781 const int64 kDelayToLoadSessionMs = 500; | 780 const int64_t kDelayToLoadSessionMs = 500; |
782 | 781 |
783 // Defer resolving the promise until the session is loaded. | 782 // Defer resolving the promise until the session is loaded. |
784 promise_id_for_emulated_loadsession_ = promise_id; | 783 promise_id_for_emulated_loadsession_ = promise_id; |
785 | 784 |
786 // Use the address of |session_id_for_emulated_loadsession_| as the timer | 785 // Use the address of |session_id_for_emulated_loadsession_| as the timer |
787 // context so that we can call LoadLoadableSession() when the timer expires. | 786 // context so that we can call LoadLoadableSession() when the timer expires. |
788 host_->SetTimer(kDelayToLoadSessionMs, &session_id_for_emulated_loadsession_); | 787 host_->SetTimer(kDelayToLoadSessionMs, &session_id_for_emulated_loadsession_); |
789 } | 788 } |
790 | 789 |
791 void ClearKeyCdm::OnLoadSessionUpdated() { | 790 void ClearKeyCdm::OnLoadSessionUpdated() { |
(...skipping 18 matching lines...) Expand all Loading... |
810 keys_info.swap(keys_info_for_emulated_loadsession_); | 809 keys_info.swap(keys_info_for_emulated_loadsession_); |
811 has_received_keys_change_event_for_emulated_loadsession_ = false; | 810 has_received_keys_change_event_for_emulated_loadsession_ = false; |
812 DCHECK(!keys_vector.empty()); | 811 DCHECK(!keys_vector.empty()); |
813 ConvertCdmKeysInfo(keys_info.get(), &keys_vector); | 812 ConvertCdmKeysInfo(keys_info.get(), &keys_vector); |
814 host_->OnSessionKeysChange(kLoadableSessionId, strlen(kLoadableSessionId), | 813 host_->OnSessionKeysChange(kLoadableSessionId, strlen(kLoadableSessionId), |
815 !keys_vector.empty(), keys_vector.data(), | 814 !keys_vector.empty(), keys_vector.data(), |
816 keys_vector.size()); | 815 keys_vector.size()); |
817 } | 816 } |
818 } | 817 } |
819 | 818 |
820 void ClearKeyCdm::OnPromiseResolved(uint32 promise_id) { | 819 void ClearKeyCdm::OnPromiseResolved(uint32_t promise_id) { |
821 host_->OnResolvePromise(promise_id); | 820 host_->OnResolvePromise(promise_id); |
822 } | 821 } |
823 | 822 |
824 void ClearKeyCdm::OnPromiseFailed(uint32 promise_id, | 823 void ClearKeyCdm::OnPromiseFailed(uint32_t promise_id, |
825 MediaKeys::Exception exception_code, | 824 MediaKeys::Exception exception_code, |
826 uint32 system_code, | 825 uint32_t system_code, |
827 const std::string& error_message) { | 826 const std::string& error_message) { |
828 host_->OnRejectPromise(promise_id, | 827 host_->OnRejectPromise(promise_id, |
829 ConvertException(exception_code), | 828 ConvertException(exception_code), |
830 system_code, | 829 system_code, |
831 error_message.data(), | 830 error_message.data(), |
832 error_message.length()); | 831 error_message.length()); |
833 } | 832 } |
834 | 833 |
835 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) | 834 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) |
836 int64 ClearKeyCdm::CurrentTimeStampInMicroseconds() const { | 835 int64_t ClearKeyCdm::CurrentTimeStampInMicroseconds() const { |
837 return output_timestamp_base_in_microseconds_ + | 836 return output_timestamp_base_in_microseconds_ + |
838 base::Time::kMicrosecondsPerSecond * | 837 base::Time::kMicrosecondsPerSecond * |
839 total_samples_generated_ / samples_per_second_; | 838 total_samples_generated_ / samples_per_second_; |
840 } | 839 } |
841 | 840 |
842 int ClearKeyCdm::GenerateFakeAudioFramesFromDuration( | 841 int ClearKeyCdm::GenerateFakeAudioFramesFromDuration( |
843 int64 duration_in_microseconds, | 842 int64_t duration_in_microseconds, |
844 cdm::AudioFrames* audio_frames) const { | 843 cdm::AudioFrames* audio_frames) const { |
845 int64 samples_to_generate = static_cast<double>(samples_per_second_) * | 844 int64_t samples_to_generate = static_cast<double>(samples_per_second_) * |
846 duration_in_microseconds / base::Time::kMicrosecondsPerSecond + 0.5; | 845 duration_in_microseconds / |
| 846 base::Time::kMicrosecondsPerSecond + |
| 847 0.5; |
847 if (samples_to_generate <= 0) | 848 if (samples_to_generate <= 0) |
848 return 0; | 849 return 0; |
849 | 850 |
850 int64 bytes_per_sample = channel_count_ * bits_per_channel_ / 8; | 851 int64_t bytes_per_sample = channel_count_ * bits_per_channel_ / 8; |
851 // |frame_size| must be a multiple of |bytes_per_sample|. | 852 // |frame_size| must be a multiple of |bytes_per_sample|. |
852 int64 frame_size = bytes_per_sample * samples_to_generate; | 853 int64_t frame_size = bytes_per_sample * samples_to_generate; |
853 | 854 |
854 int64 timestamp = CurrentTimeStampInMicroseconds(); | 855 int64_t timestamp = CurrentTimeStampInMicroseconds(); |
855 | 856 |
856 const int kHeaderSize = sizeof(timestamp) + sizeof(frame_size); | 857 const int kHeaderSize = sizeof(timestamp) + sizeof(frame_size); |
857 audio_frames->SetFrameBuffer(host_->Allocate(kHeaderSize + frame_size)); | 858 audio_frames->SetFrameBuffer(host_->Allocate(kHeaderSize + frame_size)); |
858 uint8_t* data = audio_frames->FrameBuffer()->Data(); | 859 uint8_t* data = audio_frames->FrameBuffer()->Data(); |
859 | 860 |
860 memcpy(data, ×tamp, sizeof(timestamp)); | 861 memcpy(data, ×tamp, sizeof(timestamp)); |
861 data += sizeof(timestamp); | 862 data += sizeof(timestamp); |
862 memcpy(data, &frame_size, sizeof(frame_size)); | 863 memcpy(data, &frame_size, sizeof(frame_size)); |
863 data += sizeof(frame_size); | 864 data += sizeof(frame_size); |
864 // You won't hear anything because we have all zeros here. But the video | 865 // You won't hear anything because we have all zeros here. But the video |
865 // should play just fine! | 866 // should play just fine! |
866 memset(data, 0, frame_size); | 867 memset(data, 0, frame_size); |
867 | 868 |
868 audio_frames->FrameBuffer()->SetSize(kHeaderSize + frame_size); | 869 audio_frames->FrameBuffer()->SetSize(kHeaderSize + frame_size); |
869 | 870 |
870 return samples_to_generate; | 871 return samples_to_generate; |
871 } | 872 } |
872 | 873 |
873 cdm::Status ClearKeyCdm::GenerateFakeAudioFrames( | 874 cdm::Status ClearKeyCdm::GenerateFakeAudioFrames( |
874 int64 timestamp_in_microseconds, | 875 int64_t timestamp_in_microseconds, |
875 cdm::AudioFrames* audio_frames) { | 876 cdm::AudioFrames* audio_frames) { |
876 if (timestamp_in_microseconds == kNoTimestamp) | 877 if (timestamp_in_microseconds == kNoTimestamp) |
877 return cdm::kNeedMoreData; | 878 return cdm::kNeedMoreData; |
878 | 879 |
879 // Return kNeedMoreData for the first frame because duration is unknown. | 880 // Return kNeedMoreData for the first frame because duration is unknown. |
880 if (output_timestamp_base_in_microseconds_ == kNoTimestamp) { | 881 if (output_timestamp_base_in_microseconds_ == kNoTimestamp) { |
881 output_timestamp_base_in_microseconds_ = timestamp_in_microseconds; | 882 output_timestamp_base_in_microseconds_ = timestamp_in_microseconds; |
882 return cdm::kNeedMoreData; | 883 return cdm::kNeedMoreData; |
883 } | 884 } |
884 | 885 |
(...skipping 16 matching lines...) Expand all Loading... |
901 void ClearKeyCdm::OnFileIOTestComplete(bool success) { | 902 void ClearKeyCdm::OnFileIOTestComplete(bool success) { |
902 DVLOG(1) << __FUNCTION__ << ": " << success; | 903 DVLOG(1) << __FUNCTION__ << ": " << success; |
903 std::string message = GetFileIOTestResultMessage(success); | 904 std::string message = GetFileIOTestResultMessage(success); |
904 host_->OnSessionMessage(last_session_id_.data(), last_session_id_.length(), | 905 host_->OnSessionMessage(last_session_id_.data(), last_session_id_.length(), |
905 cdm::kLicenseRequest, message.data(), | 906 cdm::kLicenseRequest, message.data(), |
906 message.length(), NULL, 0); | 907 message.length(), NULL, 0); |
907 file_io_test_runner_.reset(); | 908 file_io_test_runner_.reset(); |
908 } | 909 } |
909 | 910 |
910 } // namespace media | 911 } // namespace media |
OLD | NEW |