| 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 |