OLD | NEW |
---|---|
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 "content/renderer/pepper/content_decryptor_delegate.h" | 5 #include "content/renderer/pepper/content_decryptor_delegate.h" |
6 | 6 |
7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/message_loop/message_loop_proxy.h" | 9 #include "base/message_loop/message_loop_proxy.h" |
10 #include "base/safe_numerics.h" | 10 #include "base/safe_numerics.h" |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
243 } // namespace | 243 } // namespace |
244 | 244 |
245 ContentDecryptorDelegate::ContentDecryptorDelegate( | 245 ContentDecryptorDelegate::ContentDecryptorDelegate( |
246 PP_Instance pp_instance, | 246 PP_Instance pp_instance, |
247 const PPP_ContentDecryptor_Private* plugin_decryption_interface) | 247 const PPP_ContentDecryptor_Private* plugin_decryption_interface) |
248 : pp_instance_(pp_instance), | 248 : pp_instance_(pp_instance), |
249 plugin_decryption_interface_(plugin_decryption_interface), | 249 plugin_decryption_interface_(plugin_decryption_interface), |
250 next_decryption_request_id_(1), | 250 next_decryption_request_id_(1), |
251 audio_samples_per_second_(0), | 251 audio_samples_per_second_(0), |
252 audio_channel_count_(0), | 252 audio_channel_count_(0), |
253 weak_ptr_factory_(this) { | 253 weak_ptr_factory_(this), |
254 is_valid_(true) { | |
254 weak_this_ = weak_ptr_factory_.GetWeakPtr(); | 255 weak_this_ = weak_ptr_factory_.GetWeakPtr(); |
255 } | 256 } |
256 | 257 |
257 ContentDecryptorDelegate::~ContentDecryptorDelegate() { | 258 ContentDecryptorDelegate::~ContentDecryptorDelegate() { |
259 CancelAllPendingCallbacks(); | |
258 } | 260 } |
259 | 261 |
260 void ContentDecryptorDelegate::Initialize(const std::string& key_system) { | 262 void ContentDecryptorDelegate::Initialize(const std::string& key_system) { |
261 DCHECK(!key_system.empty()); | 263 DCHECK(!key_system.empty()); |
262 DCHECK(key_system_.empty()); | 264 DCHECK(key_system_.empty()); |
263 key_system_ = key_system; | 265 key_system_ = key_system; |
264 | 266 |
265 plugin_decryption_interface_->Initialize( | 267 plugin_decryption_interface_->Initialize( |
266 pp_instance_, | 268 pp_instance_, |
267 StringVar::StringToPPVar(key_system_)); | 269 StringVar::StringToPPVar(key_system_)); |
268 } | 270 } |
269 | 271 |
270 void ContentDecryptorDelegate::SetSessionEventCallbacks( | 272 void ContentDecryptorDelegate::SetSessionEventCallbacks( |
271 const media::SessionCreatedCB& session_created_cb, | 273 const media::SessionCreatedCB& session_created_cb, |
272 const media::SessionMessageCB& session_message_cb, | 274 const media::SessionMessageCB& session_message_cb, |
273 const media::SessionReadyCB& session_ready_cb, | 275 const media::SessionReadyCB& session_ready_cb, |
274 const media::SessionClosedCB& session_closed_cb, | 276 const media::SessionClosedCB& session_closed_cb, |
275 const media::SessionErrorCB& session_error_cb) { | 277 const media::SessionErrorCB& session_error_cb) { |
276 session_created_cb_ = session_created_cb; | 278 session_created_cb_ = session_created_cb; |
277 session_message_cb_ = session_message_cb; | 279 session_message_cb_ = session_message_cb; |
278 session_ready_cb_ = session_ready_cb; | 280 session_ready_cb_ = session_ready_cb; |
279 session_closed_cb_ = session_closed_cb; | 281 session_closed_cb_ = session_closed_cb; |
280 session_error_cb_ = session_error_cb; | 282 session_error_cb_ = session_error_cb; |
281 } | 283 } |
282 | 284 |
285 void ContentDecryptorDelegate::InstanceCrashed() { | |
286 CancelAllPendingCallbacks(); | |
287 is_valid_ = false; | |
288 } | |
289 | |
283 bool ContentDecryptorDelegate::CreateSession(uint32 session_id, | 290 bool ContentDecryptorDelegate::CreateSession(uint32 session_id, |
284 const std::string& type, | 291 const std::string& type, |
285 const uint8* init_data, | 292 const uint8* init_data, |
286 int init_data_length) { | 293 int init_data_length) { |
294 if (!is_valid_) | |
295 return false; | |
296 | |
287 PP_Var init_data_array = | 297 PP_Var init_data_array = |
288 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( | 298 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( |
289 init_data_length, init_data); | 299 init_data_length, init_data); |
290 | 300 |
291 plugin_decryption_interface_->CreateSession(pp_instance_, | 301 plugin_decryption_interface_->CreateSession(pp_instance_, |
292 session_id, | 302 session_id, |
293 StringVar::StringToPPVar(type), | 303 StringVar::StringToPPVar(type), |
294 init_data_array); | 304 init_data_array); |
295 return true; | 305 return true; |
296 } | 306 } |
297 | 307 |
298 bool ContentDecryptorDelegate::UpdateSession(uint32 session_id, | 308 bool ContentDecryptorDelegate::UpdateSession(uint32 session_id, |
299 const uint8* response, | 309 const uint8* response, |
300 int response_length) { | 310 int response_length) { |
311 if (!is_valid_) | |
312 return false; | |
313 | |
301 PP_Var response_array = | 314 PP_Var response_array = |
302 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( | 315 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( |
303 response_length, response); | 316 response_length, response); |
304 plugin_decryption_interface_->UpdateSession( | 317 plugin_decryption_interface_->UpdateSession( |
305 pp_instance_, session_id, response_array); | 318 pp_instance_, session_id, response_array); |
306 return true; | 319 return true; |
307 } | 320 } |
308 | 321 |
309 bool ContentDecryptorDelegate::ReleaseSession(uint32 session_id) { | 322 bool ContentDecryptorDelegate::ReleaseSession(uint32 session_id) { |
323 if (!is_valid_) | |
324 return false; | |
325 | |
310 plugin_decryption_interface_->ReleaseSession(pp_instance_, session_id); | 326 plugin_decryption_interface_->ReleaseSession(pp_instance_, session_id); |
311 return true; | 327 return true; |
312 } | 328 } |
313 | 329 |
314 // TODO(xhwang): Remove duplication of code in Decrypt(), | 330 // TODO(xhwang): Remove duplication of code in Decrypt(), |
315 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). | 331 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). |
316 bool ContentDecryptorDelegate::Decrypt( | 332 bool ContentDecryptorDelegate::Decrypt( |
317 Decryptor::StreamType stream_type, | 333 Decryptor::StreamType stream_type, |
318 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 334 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
319 const Decryptor::DecryptCB& decrypt_cb) { | 335 const Decryptor::DecryptCB& decrypt_cb) { |
320 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; | 336 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; |
337 | |
338 if (!is_valid_) | |
339 return false; | |
340 | |
321 // |{audio|video}_input_resource_| is not being used by the plugin | 341 // |{audio|video}_input_resource_| is not being used by the plugin |
322 // now because there is only one pending audio/video decrypt request at any | 342 // now because there is only one pending audio/video decrypt request at any |
323 // time. This is enforced by the media pipeline. | 343 // time. This is enforced by the media pipeline. |
324 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; | 344 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; |
325 if (!MakeMediaBufferResource( | 345 if (!MakeMediaBufferResource( |
326 stream_type, encrypted_buffer, &encrypted_resource) || | 346 stream_type, encrypted_buffer, &encrypted_resource) || |
327 !encrypted_resource.get()) { | 347 !encrypted_resource.get()) { |
328 return false; | 348 return false; |
329 } | 349 } |
330 ScopedPPResource pp_resource(encrypted_resource.get()); | 350 ScopedPPResource pp_resource(encrypted_resource.get()); |
(...skipping 26 matching lines...) Expand all Loading... | |
357 plugin_decryption_interface_->Decrypt(pp_instance_, | 377 plugin_decryption_interface_->Decrypt(pp_instance_, |
358 pp_resource, | 378 pp_resource, |
359 &block_info); | 379 &block_info); |
360 return true; | 380 return true; |
361 } | 381 } |
362 | 382 |
363 bool ContentDecryptorDelegate::CancelDecrypt( | 383 bool ContentDecryptorDelegate::CancelDecrypt( |
364 Decryptor::StreamType stream_type) { | 384 Decryptor::StreamType stream_type) { |
365 DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type; | 385 DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type; |
366 | 386 |
387 if (!is_valid_) | |
388 return false; | |
389 | |
367 Decryptor::DecryptCB decrypt_cb; | 390 Decryptor::DecryptCB decrypt_cb; |
368 switch (stream_type) { | 391 switch (stream_type) { |
369 case Decryptor::kAudio: | 392 case Decryptor::kAudio: |
370 // Release the shared memory as it can still be in use by the plugin. | 393 // Release the shared memory as it can still be in use by the plugin. |
371 // The next Decrypt() call will need to allocate a new shared memory | 394 // The next Decrypt() call will need to allocate a new shared memory |
372 // buffer. | 395 // buffer. |
373 audio_input_resource_ = NULL; | 396 audio_input_resource_ = NULL; |
374 decrypt_cb = audio_decrypt_cb_.ResetAndReturn(); | 397 decrypt_cb = audio_decrypt_cb_.ResetAndReturn(); |
375 break; | 398 break; |
376 case Decryptor::kVideo: | 399 case Decryptor::kVideo: |
(...skipping 10 matching lines...) Expand all Loading... | |
387 | 410 |
388 if (!decrypt_cb.is_null()) | 411 if (!decrypt_cb.is_null()) |
389 decrypt_cb.Run(Decryptor::kSuccess, NULL); | 412 decrypt_cb.Run(Decryptor::kSuccess, NULL); |
390 | 413 |
391 return true; | 414 return true; |
392 } | 415 } |
393 | 416 |
394 bool ContentDecryptorDelegate::InitializeAudioDecoder( | 417 bool ContentDecryptorDelegate::InitializeAudioDecoder( |
395 const media::AudioDecoderConfig& decoder_config, | 418 const media::AudioDecoderConfig& decoder_config, |
396 const Decryptor::DecoderInitCB& init_cb) { | 419 const Decryptor::DecoderInitCB& init_cb) { |
420 if (!is_valid_) | |
421 return false; | |
422 | |
397 PP_AudioDecoderConfig pp_decoder_config; | 423 PP_AudioDecoderConfig pp_decoder_config; |
398 pp_decoder_config.codec = | 424 pp_decoder_config.codec = |
399 MediaAudioCodecToPpAudioCodec(decoder_config.codec()); | 425 MediaAudioCodecToPpAudioCodec(decoder_config.codec()); |
400 pp_decoder_config.channel_count = | 426 pp_decoder_config.channel_count = |
401 media::ChannelLayoutToChannelCount(decoder_config.channel_layout()); | 427 media::ChannelLayoutToChannelCount(decoder_config.channel_layout()); |
402 pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel(); | 428 pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel(); |
403 pp_decoder_config.samples_per_second = decoder_config.samples_per_second(); | 429 pp_decoder_config.samples_per_second = decoder_config.samples_per_second(); |
404 pp_decoder_config.request_id = next_decryption_request_id_++; | 430 pp_decoder_config.request_id = next_decryption_request_id_++; |
405 | 431 |
406 audio_samples_per_second_ = pp_decoder_config.samples_per_second; | 432 audio_samples_per_second_ = pp_decoder_config.samples_per_second; |
(...skipping 11 matching lines...) Expand all Loading... | |
418 audio_decoder_init_cb_.Set(pp_decoder_config.request_id, init_cb); | 444 audio_decoder_init_cb_.Set(pp_decoder_config.request_id, init_cb); |
419 plugin_decryption_interface_->InitializeAudioDecoder(pp_instance_, | 445 plugin_decryption_interface_->InitializeAudioDecoder(pp_instance_, |
420 &pp_decoder_config, | 446 &pp_decoder_config, |
421 pp_resource); | 447 pp_resource); |
422 return true; | 448 return true; |
423 } | 449 } |
424 | 450 |
425 bool ContentDecryptorDelegate::InitializeVideoDecoder( | 451 bool ContentDecryptorDelegate::InitializeVideoDecoder( |
426 const media::VideoDecoderConfig& decoder_config, | 452 const media::VideoDecoderConfig& decoder_config, |
427 const Decryptor::DecoderInitCB& init_cb) { | 453 const Decryptor::DecoderInitCB& init_cb) { |
454 if (!is_valid_) | |
455 return false; | |
456 | |
428 PP_VideoDecoderConfig pp_decoder_config; | 457 PP_VideoDecoderConfig pp_decoder_config; |
429 pp_decoder_config.codec = | 458 pp_decoder_config.codec = |
430 MediaVideoCodecToPpVideoCodec(decoder_config.codec()); | 459 MediaVideoCodecToPpVideoCodec(decoder_config.codec()); |
431 pp_decoder_config.profile = | 460 pp_decoder_config.profile = |
432 MediaVideoCodecProfileToPpVideoCodecProfile(decoder_config.profile()); | 461 MediaVideoCodecProfileToPpVideoCodecProfile(decoder_config.profile()); |
433 pp_decoder_config.format = | 462 pp_decoder_config.format = |
434 MediaVideoFormatToPpDecryptedFrameFormat(decoder_config.format()); | 463 MediaVideoFormatToPpDecryptedFrameFormat(decoder_config.format()); |
435 pp_decoder_config.width = decoder_config.coded_size().width(); | 464 pp_decoder_config.width = decoder_config.coded_size().width(); |
436 pp_decoder_config.height = decoder_config.coded_size().height(); | 465 pp_decoder_config.height = decoder_config.coded_size().height(); |
437 pp_decoder_config.request_id = next_decryption_request_id_++; | 466 pp_decoder_config.request_id = next_decryption_request_id_++; |
(...skipping 11 matching lines...) Expand all Loading... | |
449 natural_size_ = decoder_config.natural_size(); | 478 natural_size_ = decoder_config.natural_size(); |
450 | 479 |
451 plugin_decryption_interface_->InitializeVideoDecoder(pp_instance_, | 480 plugin_decryption_interface_->InitializeVideoDecoder(pp_instance_, |
452 &pp_decoder_config, | 481 &pp_decoder_config, |
453 pp_resource); | 482 pp_resource); |
454 return true; | 483 return true; |
455 } | 484 } |
456 | 485 |
457 bool ContentDecryptorDelegate::DeinitializeDecoder( | 486 bool ContentDecryptorDelegate::DeinitializeDecoder( |
458 Decryptor::StreamType stream_type) { | 487 Decryptor::StreamType stream_type) { |
488 if (!is_valid_) | |
489 return false; | |
490 | |
459 CancelDecode(stream_type); | 491 CancelDecode(stream_type); |
460 | 492 |
461 natural_size_ = gfx::Size(); | 493 natural_size_ = gfx::Size(); |
462 | 494 |
463 // TODO(tomfinegan): Add decoder deinitialize request tracking, and get | 495 // TODO(tomfinegan): Add decoder deinitialize request tracking, and get |
464 // stream type from media stack. | 496 // stream type from media stack. |
465 plugin_decryption_interface_->DeinitializeDecoder( | 497 plugin_decryption_interface_->DeinitializeDecoder( |
466 pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0); | 498 pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0); |
467 return true; | 499 return true; |
468 } | 500 } |
469 | 501 |
470 bool ContentDecryptorDelegate::ResetDecoder(Decryptor::StreamType stream_type) { | 502 bool ContentDecryptorDelegate::ResetDecoder(Decryptor::StreamType stream_type) { |
503 if (!is_valid_) | |
504 return false; | |
505 | |
471 CancelDecode(stream_type); | 506 CancelDecode(stream_type); |
472 | 507 |
473 // TODO(tomfinegan): Add decoder reset request tracking. | 508 // TODO(tomfinegan): Add decoder reset request tracking. |
474 plugin_decryption_interface_->ResetDecoder( | 509 plugin_decryption_interface_->ResetDecoder( |
475 pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0); | 510 pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0); |
476 return true; | 511 return true; |
477 } | 512 } |
478 | 513 |
479 bool ContentDecryptorDelegate::DecryptAndDecodeAudio( | 514 bool ContentDecryptorDelegate::DecryptAndDecodeAudio( |
480 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 515 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
481 const Decryptor::AudioDecodeCB& audio_decode_cb) { | 516 const Decryptor::AudioDecodeCB& audio_decode_cb) { |
517 if (!is_valid_) | |
518 return false; | |
519 | |
482 // |audio_input_resource_| is not being used by the plugin now | 520 // |audio_input_resource_| is not being used by the plugin now |
483 // because there is only one pending audio decode request at any time. | 521 // because there is only one pending audio decode request at any time. |
484 // This is enforced by the media pipeline. | 522 // This is enforced by the media pipeline. |
485 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; | 523 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; |
486 if (!MakeMediaBufferResource( | 524 if (!MakeMediaBufferResource( |
487 Decryptor::kAudio, encrypted_buffer, &encrypted_resource)) { | 525 Decryptor::kAudio, encrypted_buffer, &encrypted_resource)) { |
488 return false; | 526 return false; |
489 } | 527 } |
490 | 528 |
491 // The resource should not be NULL for non-EOS buffer. | 529 // The resource should not be NULL for non-EOS buffer. |
(...skipping 20 matching lines...) Expand all Loading... | |
512 plugin_decryption_interface_->DecryptAndDecode(pp_instance_, | 550 plugin_decryption_interface_->DecryptAndDecode(pp_instance_, |
513 PP_DECRYPTORSTREAMTYPE_AUDIO, | 551 PP_DECRYPTORSTREAMTYPE_AUDIO, |
514 pp_resource, | 552 pp_resource, |
515 &block_info); | 553 &block_info); |
516 return true; | 554 return true; |
517 } | 555 } |
518 | 556 |
519 bool ContentDecryptorDelegate::DecryptAndDecodeVideo( | 557 bool ContentDecryptorDelegate::DecryptAndDecodeVideo( |
520 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 558 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
521 const Decryptor::VideoDecodeCB& video_decode_cb) { | 559 const Decryptor::VideoDecodeCB& video_decode_cb) { |
560 if (!is_valid_) | |
561 return false; | |
562 | |
522 // |video_input_resource_| is not being used by the plugin now | 563 // |video_input_resource_| is not being used by the plugin now |
523 // because there is only one pending video decode request at any time. | 564 // because there is only one pending video decode request at any time. |
524 // This is enforced by the media pipeline. | 565 // This is enforced by the media pipeline. |
525 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; | 566 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; |
526 if (!MakeMediaBufferResource( | 567 if (!MakeMediaBufferResource( |
527 Decryptor::kVideo, encrypted_buffer, &encrypted_resource)) { | 568 Decryptor::kVideo, encrypted_buffer, &encrypted_resource)) { |
528 return false; | 569 return false; |
529 } | 570 } |
530 | 571 |
531 // The resource should not be 0 for non-EOS buffer. | 572 // The resource should not be 0 for non-EOS buffer. |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1014 frame_count)); | 1055 frame_count)); |
1015 frames->push_back(frame); | 1056 frames->push_back(frame); |
1016 | 1057 |
1017 cur += frame_size; | 1058 cur += frame_size; |
1018 bytes_left -= frame_size; | 1059 bytes_left -= frame_size; |
1019 } while (bytes_left > 0); | 1060 } while (bytes_left > 0); |
1020 | 1061 |
1021 return true; | 1062 return true; |
1022 } | 1063 } |
1023 | 1064 |
1065 void ContentDecryptorDelegate::CancelAllPendingCallbacks() { | |
dmichael (off chromium)
2014/01/08 20:15:59
The meaning here is a little different from what I
xhwang
2014/01/08 23:19:14
Done.
| |
1066 if (!audio_decoder_init_cb_.is_null()) | |
1067 audio_decoder_init_cb_.ResetAndReturn().Run(false); | |
1068 | |
1069 if (!video_decoder_init_cb_.is_null()) | |
1070 video_decoder_init_cb_.ResetAndReturn().Run(false); | |
1071 | |
1072 audio_input_resource_ = NULL; | |
1073 video_input_resource_ = NULL; | |
1074 | |
1075 if (!audio_decrypt_cb_.is_null()) | |
1076 audio_decrypt_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL); | |
1077 | |
1078 if (!video_decrypt_cb_.is_null()) | |
1079 video_decrypt_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL); | |
1080 | |
1081 if (!audio_decode_cb_.is_null()) { | |
1082 const media::Decryptor::AudioBuffers empty_frames; | |
1083 audio_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, | |
1084 empty_frames); | |
1085 } | |
1086 | |
1087 if (!video_decode_cb_.is_null()) | |
1088 video_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL); | |
1089 } | |
1090 | |
1024 } // namespace content | 1091 } // namespace content |
OLD | NEW |