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 "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 5 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/memory/linked_ptr.h" | 11 #include "base/memory/linked_ptr.h" |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
14 #include "base/stringprintf.h" | 14 #include "base/stringprintf.h" |
15 #include "base/time.h" | 15 #include "base/time.h" |
16 #include "base/utf_offset_string_conversions.h" | 16 #include "base/utf_offset_string_conversions.h" |
17 #include "base/utf_string_conversions.h" | 17 #include "base/utf_string_conversions.h" |
18 // TODO(xhwang): Move media specific code out of this class. | 18 // TODO(xhwang): Move media specific code out of this class. |
19 #include "media/base/audio_decoder_config.h" | 19 #include "media/base/audio_decoder_config.h" |
| 20 #include "media/base/channel_layout.h" |
| 21 #include "media/base/data_buffer.h" |
20 #include "media/base/decoder_buffer.h" | 22 #include "media/base/decoder_buffer.h" |
21 #include "media/base/decryptor_client.h" | 23 #include "media/base/decryptor_client.h" |
22 #include "media/base/video_decoder_config.h" | 24 #include "media/base/video_decoder_config.h" |
23 #include "media/base/video_frame.h" | 25 #include "media/base/video_frame.h" |
24 #include "media/base/video_util.h" | 26 #include "media/base/video_util.h" |
25 #include "ppapi/c/dev/ppb_find_dev.h" | 27 #include "ppapi/c/dev/ppb_find_dev.h" |
26 #include "ppapi/c/dev/ppb_zoom_dev.h" | 28 #include "ppapi/c/dev/ppb_zoom_dev.h" |
27 #include "ppapi/c/dev/ppp_find_dev.h" | 29 #include "ppapi/c/dev/ppp_find_dev.h" |
28 #include "ppapi/c/dev/ppp_selection_dev.h" | 30 #include "ppapi/c/dev/ppp_selection_dev.h" |
29 #include "ppapi/c/dev/ppp_text_input_dev.h" | 31 #include "ppapi/c/dev/ppp_text_input_dev.h" |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 for (uint32_t i = 0; i < block_info->num_subsamples; ++i) { | 387 for (uint32_t i = 0; i < block_info->num_subsamples; ++i) { |
386 block_info->subsamples[i].clear_bytes = | 388 block_info->subsamples[i].clear_bytes = |
387 decrypt_config->subsamples()[i].clear_bytes; | 389 decrypt_config->subsamples()[i].clear_bytes; |
388 block_info->subsamples[i].cipher_bytes = | 390 block_info->subsamples[i].cipher_bytes = |
389 decrypt_config->subsamples()[i].cypher_bytes; | 391 decrypt_config->subsamples()[i].cypher_bytes; |
390 } | 392 } |
391 | 393 |
392 return true; | 394 return true; |
393 } | 395 } |
394 | 396 |
| 397 // Deserializes audio data stored in |audio_frames| into individual audio |
| 398 // buffers in |frames|. Returns true upon success. |
| 399 bool DeserializeAudioFrames(PP_Resource audio_frames, |
| 400 media::Decryptor::AudioBuffers* frames) { |
| 401 DCHECK(frames); |
| 402 EnterResourceNoLock<PPB_Buffer_API> enter(audio_frames, true); |
| 403 if (!enter.succeeded()) |
| 404 return false; |
| 405 |
| 406 BufferAutoMapper mapper(enter.object()); |
| 407 if (!mapper.data() || !mapper.size()) |
| 408 return false; |
| 409 |
| 410 const uint8* cur = static_cast<uint8*>(mapper.data()); |
| 411 int bytes_left = mapper.size(); |
| 412 |
| 413 do { |
| 414 int64 timestamp = 0; |
| 415 int64 frame_size = -1; |
| 416 const int kHeaderSize = sizeof(timestamp) + sizeof(frame_size); |
| 417 |
| 418 if (bytes_left < kHeaderSize) |
| 419 return false; |
| 420 |
| 421 timestamp = *(reinterpret_cast<const int64*>(cur)); |
| 422 cur += sizeof(timestamp); |
| 423 bytes_left -= sizeof(timestamp); |
| 424 |
| 425 frame_size = *(reinterpret_cast<const int64*>(cur)); |
| 426 cur += sizeof(frame_size); |
| 427 bytes_left -= sizeof(frame_size); |
| 428 |
| 429 // We should *not* have empty frame in the list. |
| 430 if (frame_size <= 0 || bytes_left < frame_size) |
| 431 return false; |
| 432 |
| 433 scoped_refptr<media::DataBuffer> frame(new media::DataBuffer(frame_size)); |
| 434 frame->SetDataSize(frame_size); |
| 435 memcpy(frame->GetWritableData(), cur, frame_size); |
| 436 frame->SetTimestamp(base::TimeDelta::FromMicroseconds(timestamp)); |
| 437 frames->push_back(frame); |
| 438 |
| 439 cur += frame_size; |
| 440 bytes_left -= frame_size; |
| 441 } while (bytes_left > 0); |
| 442 |
| 443 return true; |
| 444 } |
| 445 |
395 PP_AudioCodec MediaAudioCodecToPpAudioCodec(media::AudioCodec codec) { | 446 PP_AudioCodec MediaAudioCodecToPpAudioCodec(media::AudioCodec codec) { |
396 switch (codec) { | 447 switch (codec) { |
397 case media::kCodecVorbis: | 448 case media::kCodecVorbis: |
398 return PP_AUDIOCODEC_VORBIS; | 449 return PP_AUDIOCODEC_VORBIS; |
399 default: | 450 default: |
400 return PP_AUDIOCODEC_UNKNOWN; | 451 return PP_AUDIOCODEC_UNKNOWN; |
401 } | 452 } |
402 } | 453 } |
403 | 454 |
404 PP_VideoCodec MediaVideoCodecToPpVideoCodec(media::VideoCodec codec) { | 455 PP_VideoCodec MediaVideoCodecToPpVideoCodec(media::VideoCodec codec) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 case PP_DECRYPTRESULT_DECRYPT_ERROR: | 495 case PP_DECRYPTRESULT_DECRYPT_ERROR: |
445 return media::Decryptor::kError; | 496 return media::Decryptor::kError; |
446 case PP_DECRYPTRESULT_DECODE_ERROR: | 497 case PP_DECRYPTRESULT_DECODE_ERROR: |
447 return media::Decryptor::kError; | 498 return media::Decryptor::kError; |
448 default: | 499 default: |
449 NOTREACHED(); | 500 NOTREACHED(); |
450 return media::Decryptor::kError; | 501 return media::Decryptor::kError; |
451 } | 502 } |
452 } | 503 } |
453 | 504 |
| 505 PP_DecryptorStreamType MediaDecryptorStreamTypeToPpStreamType( |
| 506 media::Decryptor::StreamType stream_type) { |
| 507 switch (stream_type) { |
| 508 case media::Decryptor::kAudio: |
| 509 return PP_DECRYPTORSTREAMTYPE_AUDIO; |
| 510 case media::Decryptor::kVideo: |
| 511 return PP_DECRYPTORSTREAMTYPE_VIDEO; |
| 512 default: |
| 513 NOTREACHED(); |
| 514 return PP_DECRYPTORSTREAMTYPE_VIDEO; |
| 515 } |
| 516 } |
| 517 |
454 } // namespace | 518 } // namespace |
455 | 519 |
456 // static | 520 // static |
457 PluginInstance* PluginInstance::Create(PluginDelegate* delegate, | 521 PluginInstance* PluginInstance::Create(PluginDelegate* delegate, |
458 PluginModule* module) { | 522 PluginModule* module) { |
459 base::Callback<const void*(const char*)> get_plugin_interface_func = | 523 base::Callback<const void*(const char*)> get_plugin_interface_func = |
460 base::Bind(&PluginModule::GetPluginInterface, module); | 524 base::Bind(&PluginModule::GetPluginInterface, module); |
461 PPP_Instance_Combined* ppp_instance_combined = | 525 PPP_Instance_Combined* ppp_instance_combined = |
462 PPP_Instance_Combined::Create(get_plugin_interface_func); | 526 PPP_Instance_Combined::Create(get_plugin_interface_func); |
463 if (!ppp_instance_combined) | 527 if (!ppp_instance_combined) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 text_input_type_(kPluginDefaultTextInputType), | 582 text_input_type_(kPluginDefaultTextInputType), |
519 text_input_caret_(0, 0, 0, 0), | 583 text_input_caret_(0, 0, 0, 0), |
520 text_input_caret_bounds_(0, 0, 0, 0), | 584 text_input_caret_bounds_(0, 0, 0, 0), |
521 text_input_caret_set_(false), | 585 text_input_caret_set_(false), |
522 selection_caret_(0), | 586 selection_caret_(0), |
523 selection_anchor_(0), | 587 selection_anchor_(0), |
524 pending_user_gesture_(0.0), | 588 pending_user_gesture_(0.0), |
525 flash_impl_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 589 flash_impl_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
526 decryptor_client_(NULL), | 590 decryptor_client_(NULL), |
527 next_decryption_request_id_(1), | 591 next_decryption_request_id_(1), |
| 592 pending_audio_decrypt_request_id_(0), |
| 593 pending_video_decrypt_request_id_(0), |
528 pending_audio_decoder_init_request_id_(0), | 594 pending_audio_decoder_init_request_id_(0), |
529 pending_video_decoder_init_request_id_(0), | 595 pending_video_decoder_init_request_id_(0), |
| 596 pending_audio_decode_request_id_(0), |
530 pending_video_decode_request_id_(0) { | 597 pending_video_decode_request_id_(0) { |
531 pp_instance_ = HostGlobals::Get()->AddInstance(this); | 598 pp_instance_ = HostGlobals::Get()->AddInstance(this); |
532 | 599 |
533 memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); | 600 memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); |
534 DCHECK(delegate); | 601 DCHECK(delegate); |
535 module_->InstanceCreated(this); | 602 module_->InstanceCreated(this); |
536 delegate_->InstanceCreated(this); | 603 delegate_->InstanceCreated(this); |
537 message_channel_.reset(new MessageChannel(this)); | 604 message_channel_.reset(new MessageChannel(this)); |
538 | 605 |
539 view_data_.is_page_visible = delegate->IsPageVisible(); | 606 view_data_.is_page_visible = delegate->IsPageVisible(); |
(...skipping 989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1529 PP_PrivatePageTransformType transform_type = | 1596 PP_PrivatePageTransformType transform_type = |
1530 type == WebPlugin::RotationType90Clockwise ? | 1597 type == WebPlugin::RotationType90Clockwise ? |
1531 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CW : | 1598 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CW : |
1532 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CCW; | 1599 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CCW; |
1533 plugin_pdf_interface_->Transform(pp_instance(), transform_type); | 1600 plugin_pdf_interface_->Transform(pp_instance(), transform_type); |
1534 // NOTE: plugin instance may have been deleted. | 1601 // NOTE: plugin instance may have been deleted. |
1535 } | 1602 } |
1536 | 1603 |
1537 void PluginInstance::set_decrypt_client( | 1604 void PluginInstance::set_decrypt_client( |
1538 media::DecryptorClient* decryptor_client) { | 1605 media::DecryptorClient* decryptor_client) { |
1539 DCHECK(decryptor_client); | |
1540 decryptor_client_ = decryptor_client; | 1606 decryptor_client_ = decryptor_client; |
1541 } | 1607 } |
1542 | 1608 |
1543 bool PluginInstance::GenerateKeyRequest(const std::string& key_system, | 1609 bool PluginInstance::GenerateKeyRequest(const std::string& key_system, |
1544 const std::string& init_data) { | 1610 const std::string& init_data) { |
1545 if (!LoadContentDecryptorInterface()) | 1611 if (!LoadContentDecryptorInterface()) |
1546 return false; | 1612 return false; |
1547 if (key_system.empty()) | 1613 if (key_system.empty()) |
1548 return false; | 1614 return false; |
1549 | 1615 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1581 | 1647 |
1582 bool PluginInstance::CancelKeyRequest(const std::string& session_id) { | 1648 bool PluginInstance::CancelKeyRequest(const std::string& session_id) { |
1583 if (!LoadContentDecryptorInterface()) | 1649 if (!LoadContentDecryptorInterface()) |
1584 return false; | 1650 return false; |
1585 plugin_decryption_interface_->CancelKeyRequest( | 1651 plugin_decryption_interface_->CancelKeyRequest( |
1586 pp_instance(), | 1652 pp_instance(), |
1587 StringVar::StringToPPVar(session_id)); | 1653 StringVar::StringToPPVar(session_id)); |
1588 return true; | 1654 return true; |
1589 } | 1655 } |
1590 | 1656 |
| 1657 // TODO(xhwang): Remove duplication of code in Decrypt(), |
| 1658 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). |
1591 bool PluginInstance::Decrypt( | 1659 bool PluginInstance::Decrypt( |
| 1660 media::Decryptor::StreamType stream_type, |
1592 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 1661 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
1593 const media::Decryptor::DecryptCB& decrypt_cb) { | 1662 const media::Decryptor::DecryptCB& decrypt_cb) { |
1594 DVLOG(3) << "Decrypt()"; | 1663 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; |
1595 if (!LoadContentDecryptorInterface()) | 1664 if (!LoadContentDecryptorInterface()) |
1596 return false; | 1665 return false; |
1597 | 1666 |
1598 ScopedPPResource encrypted_resource( | 1667 ScopedPPResource encrypted_resource( |
1599 ScopedPPResource::PassRef(), | 1668 ScopedPPResource::PassRef(), |
1600 MakeBufferResource(pp_instance(), | 1669 MakeBufferResource(pp_instance(), |
1601 encrypted_buffer->GetData(), | 1670 encrypted_buffer->GetData(), |
1602 encrypted_buffer->GetDataSize())); | 1671 encrypted_buffer->GetDataSize())); |
1603 if (!encrypted_resource.get()) | 1672 if (!encrypted_resource.get()) |
1604 return false; | 1673 return false; |
1605 | 1674 |
1606 const uint32_t request_id = next_decryption_request_id_++; | 1675 const uint32_t request_id = next_decryption_request_id_++; |
1607 DVLOG(2) << "Decrypt() - request_id " << request_id; | 1676 DVLOG(2) << "Decrypt() - request_id " << request_id; |
1608 | 1677 |
1609 PP_EncryptedBlockInfo block_info; | 1678 PP_EncryptedBlockInfo block_info; |
1610 DCHECK(encrypted_buffer->GetDecryptConfig()); | 1679 DCHECK(encrypted_buffer->GetDecryptConfig()); |
1611 if (!MakeEncryptedBlockInfo(encrypted_buffer->GetDecryptConfig(), | 1680 if (!MakeEncryptedBlockInfo(encrypted_buffer->GetDecryptConfig(), |
1612 encrypted_buffer->GetTimestamp().InMicroseconds(), | 1681 encrypted_buffer->GetTimestamp().InMicroseconds(), |
1613 request_id, | 1682 request_id, |
1614 &block_info)) { | 1683 &block_info)) { |
1615 return false; | 1684 return false; |
1616 } | 1685 } |
1617 | 1686 |
1618 DCHECK(!ContainsKey(pending_decryption_cbs_, request_id)); | 1687 // There is only one pending decrypt request at any time per stream. This is |
1619 pending_decryption_cbs_.insert(std::make_pair(request_id, decrypt_cb)); | 1688 // enforced by the media pipeline. |
| 1689 switch (stream_type) { |
| 1690 case media::Decryptor::kAudio: |
| 1691 DCHECK_EQ(pending_audio_decrypt_request_id_, 0u); |
| 1692 DCHECK(pending_audio_decrypt_cb_.is_null()); |
| 1693 pending_audio_decrypt_request_id_ = request_id; |
| 1694 pending_audio_decrypt_cb_ = decrypt_cb; |
| 1695 break; |
| 1696 case media::Decryptor::kVideo: |
| 1697 DCHECK_EQ(pending_video_decrypt_request_id_, 0u); |
| 1698 DCHECK(pending_video_decrypt_cb_.is_null()); |
| 1699 pending_video_decrypt_request_id_ = request_id; |
| 1700 pending_video_decrypt_cb_ = decrypt_cb; |
| 1701 break; |
| 1702 default: |
| 1703 NOTREACHED(); |
| 1704 return false; |
| 1705 } |
1620 | 1706 |
1621 plugin_decryption_interface_->Decrypt(pp_instance(), | 1707 plugin_decryption_interface_->Decrypt(pp_instance(), |
1622 encrypted_resource, | 1708 encrypted_resource, |
1623 &block_info); | 1709 &block_info); |
1624 return true; | 1710 return true; |
1625 } | 1711 } |
1626 | 1712 |
| 1713 bool PluginInstance::CancelDecrypt(media::Decryptor::StreamType stream_type) { |
| 1714 DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type; |
| 1715 |
| 1716 media::Decryptor::DecryptCB decrypt_cb; |
| 1717 switch (stream_type) { |
| 1718 case media::Decryptor::kAudio: |
| 1719 pending_audio_decrypt_request_id_ = 0; |
| 1720 decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_); |
| 1721 break; |
| 1722 case media::Decryptor::kVideo: |
| 1723 pending_video_decrypt_request_id_ = 0; |
| 1724 decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_); |
| 1725 break; |
| 1726 default: |
| 1727 NOTREACHED(); |
| 1728 return false; |
| 1729 } |
| 1730 |
| 1731 if (!decrypt_cb.is_null()) |
| 1732 decrypt_cb.Run(media::Decryptor::kSuccess, NULL); |
| 1733 |
| 1734 return true; |
| 1735 } |
| 1736 |
1627 bool PluginInstance::InitializeAudioDecoder( | 1737 bool PluginInstance::InitializeAudioDecoder( |
1628 const media::AudioDecoderConfig& decoder_config, | 1738 const media::AudioDecoderConfig& decoder_config, |
1629 const media::Decryptor::DecoderInitCB& init_cb) { | 1739 const media::Decryptor::DecoderInitCB& init_cb) { |
1630 PP_AudioDecoderConfig pp_decoder_config; | 1740 PP_AudioDecoderConfig pp_decoder_config; |
1631 pp_decoder_config.codec = | 1741 pp_decoder_config.codec = |
1632 MediaAudioCodecToPpAudioCodec(decoder_config.codec()); | 1742 MediaAudioCodecToPpAudioCodec(decoder_config.codec()); |
1633 pp_decoder_config.channel_count = | 1743 pp_decoder_config.channel_count = |
1634 media::ChannelLayoutToChannelCount(decoder_config.channel_layout()); | 1744 media::ChannelLayoutToChannelCount(decoder_config.channel_layout()); |
1635 pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel(); | 1745 pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel(); |
1636 pp_decoder_config.samples_per_second = decoder_config.samples_per_second(); | 1746 pp_decoder_config.samples_per_second = decoder_config.samples_per_second(); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1677 DCHECK(pending_video_decoder_init_cb_.is_null()); | 1787 DCHECK(pending_video_decoder_init_cb_.is_null()); |
1678 pending_video_decoder_init_request_id_ = pp_decoder_config.request_id; | 1788 pending_video_decoder_init_request_id_ = pp_decoder_config.request_id; |
1679 pending_video_decoder_init_cb_ = init_cb; | 1789 pending_video_decoder_init_cb_ = init_cb; |
1680 | 1790 |
1681 plugin_decryption_interface_->InitializeVideoDecoder(pp_instance(), | 1791 plugin_decryption_interface_->InitializeVideoDecoder(pp_instance(), |
1682 &pp_decoder_config, | 1792 &pp_decoder_config, |
1683 extra_data_resource); | 1793 extra_data_resource); |
1684 return true; | 1794 return true; |
1685 } | 1795 } |
1686 | 1796 |
1687 bool PluginInstance::DeinitializeDecoder() { | 1797 // TODO(xhwang): Try to remove duplicate logic here and in CancelDecrypt(). |
| 1798 void PluginInstance::CancelDecode(media::Decryptor::StreamType stream_type) { |
| 1799 switch (stream_type) { |
| 1800 case media::Decryptor::kAudio: |
| 1801 pending_audio_decode_request_id_ = 0; |
| 1802 if (!pending_audio_decode_cb_.is_null()) |
| 1803 base::ResetAndReturn(&pending_audio_decode_cb_).Run( |
| 1804 media::Decryptor::kSuccess, media::Decryptor::AudioBuffers()); |
| 1805 break; |
| 1806 case media::Decryptor::kVideo: |
| 1807 pending_video_decode_request_id_ = 0; |
| 1808 if (!pending_video_decode_cb_.is_null()) |
| 1809 base::ResetAndReturn(&pending_video_decode_cb_).Run( |
| 1810 media::Decryptor::kSuccess, NULL); |
| 1811 break; |
| 1812 default: |
| 1813 NOTREACHED(); |
| 1814 } |
| 1815 } |
| 1816 |
| 1817 bool PluginInstance::DeinitializeDecoder( |
| 1818 media::Decryptor::StreamType stream_type) { |
1688 if (!LoadContentDecryptorInterface()) | 1819 if (!LoadContentDecryptorInterface()) |
1689 return false; | 1820 return false; |
1690 | 1821 |
| 1822 CancelDecode(stream_type); |
| 1823 |
1691 // TODO(tomfinegan): Add decoder deinitialize request tracking, and get | 1824 // TODO(tomfinegan): Add decoder deinitialize request tracking, and get |
1692 // stream type from media stack. | 1825 // stream type from media stack. |
1693 plugin_decryption_interface_->DeinitializeDecoder( | 1826 plugin_decryption_interface_->DeinitializeDecoder( |
1694 pp_instance(), | 1827 pp_instance(), MediaDecryptorStreamTypeToPpStreamType(stream_type), 0); |
1695 PP_DECRYPTORSTREAMTYPE_VIDEO, | |
1696 0); | |
1697 return true; | 1828 return true; |
1698 } | 1829 } |
1699 | 1830 |
1700 bool PluginInstance::ResetDecoder() { | 1831 bool PluginInstance::ResetDecoder(media::Decryptor::StreamType stream_type) { |
1701 if (!LoadContentDecryptorInterface()) | 1832 if (!LoadContentDecryptorInterface()) |
1702 return false; | 1833 return false; |
1703 | 1834 |
1704 // TODO(tomfinegan): Add decoder reset request tracking, and get | 1835 CancelDecode(stream_type); |
1705 // stream type from media stack. | 1836 |
1706 plugin_decryption_interface_->ResetDecoder(pp_instance(), | 1837 // TODO(tomfinegan): Add decoder reset request tracking. |
1707 PP_DECRYPTORSTREAMTYPE_VIDEO, | 1838 plugin_decryption_interface_->ResetDecoder( |
1708 0); | 1839 pp_instance(), MediaDecryptorStreamTypeToPpStreamType(stream_type), 0); |
1709 return true; | 1840 return true; |
1710 } | 1841 } |
1711 | 1842 |
1712 bool PluginInstance::DecryptAndDecode( | 1843 bool PluginInstance::DecryptAndDecodeAudio( |
| 1844 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
| 1845 const media::Decryptor::AudioDecodeCB& audio_decode_cb) { |
| 1846 if (!LoadContentDecryptorInterface()) |
| 1847 return false; |
| 1848 |
| 1849 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize() |
| 1850 // return NULL and 0 respectively. In that case, we'll just create a 0 |
| 1851 // resource. |
| 1852 ScopedPPResource encrypted_resource( |
| 1853 ScopedPPResource::PassRef(), |
| 1854 MakeBufferResource(pp_instance(), |
| 1855 encrypted_buffer->GetData(), |
| 1856 encrypted_buffer->GetDataSize())); |
| 1857 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) |
| 1858 return false; |
| 1859 |
| 1860 const uint32_t request_id = next_decryption_request_id_++; |
| 1861 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; |
| 1862 |
| 1863 PP_EncryptedBlockInfo block_info; |
| 1864 if (!MakeEncryptedBlockInfo( |
| 1865 encrypted_buffer->GetDecryptConfig(), |
| 1866 encrypted_buffer->GetTimestamp().InMicroseconds(), |
| 1867 request_id, |
| 1868 &block_info)) { |
| 1869 return false; |
| 1870 } |
| 1871 |
| 1872 // There is only one pending audio decode request at any time. This is |
| 1873 // enforced by the media pipeline. |
| 1874 DCHECK_EQ(pending_audio_decode_request_id_, 0u); |
| 1875 DCHECK(pending_audio_decode_cb_.is_null()); |
| 1876 pending_audio_decode_request_id_ = request_id; |
| 1877 pending_audio_decode_cb_ = audio_decode_cb; |
| 1878 |
| 1879 plugin_decryption_interface_->DecryptAndDecode(pp_instance(), |
| 1880 PP_DECRYPTORSTREAMTYPE_AUDIO, |
| 1881 encrypted_resource, |
| 1882 &block_info); |
| 1883 return true; |
| 1884 } |
| 1885 |
| 1886 bool PluginInstance::DecryptAndDecodeVideo( |
1713 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 1887 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
1714 const media::Decryptor::VideoDecodeCB& video_decode_cb) { | 1888 const media::Decryptor::VideoDecodeCB& video_decode_cb) { |
1715 if (!LoadContentDecryptorInterface()) | 1889 if (!LoadContentDecryptorInterface()) |
1716 return false; | 1890 return false; |
1717 | 1891 |
1718 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize() | 1892 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize() |
1719 // return NULL and 0 respectively. In that case, we'll just create a 0 | 1893 // return NULL and 0 respectively. In that case, we'll just create a 0 |
1720 // resource. | 1894 // resource. |
1721 ScopedPPResource encrypted_resource( | 1895 ScopedPPResource encrypted_resource( |
1722 ScopedPPResource::PassRef(), | 1896 ScopedPPResource::PassRef(), |
1723 MakeBufferResource(pp_instance(), | 1897 MakeBufferResource(pp_instance(), |
1724 encrypted_buffer->GetData(), | 1898 encrypted_buffer->GetData(), |
1725 encrypted_buffer->GetDataSize())); | 1899 encrypted_buffer->GetDataSize())); |
1726 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) | 1900 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) |
1727 return false; | 1901 return false; |
1728 | 1902 |
1729 const uint32_t request_id = next_decryption_request_id_++; | 1903 const uint32_t request_id = next_decryption_request_id_++; |
1730 DVLOG(2) << "DecryptAndDecode() - request_id " << request_id; | 1904 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; |
1731 | 1905 |
1732 PP_EncryptedBlockInfo block_info; | 1906 PP_EncryptedBlockInfo block_info; |
1733 if (!MakeEncryptedBlockInfo( | 1907 if (!MakeEncryptedBlockInfo( |
1734 encrypted_buffer->GetDecryptConfig(), | 1908 encrypted_buffer->GetDecryptConfig(), |
1735 encrypted_buffer->GetTimestamp().InMicroseconds(), | 1909 encrypted_buffer->GetTimestamp().InMicroseconds(), |
1736 request_id, | 1910 request_id, |
1737 &block_info)) { | 1911 &block_info)) { |
1738 return false; | 1912 return false; |
1739 } | 1913 } |
1740 | 1914 |
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2371 void PluginInstance::NeedKey(PP_Instance instance, | 2545 void PluginInstance::NeedKey(PP_Instance instance, |
2372 PP_Var key_system_var, | 2546 PP_Var key_system_var, |
2373 PP_Var session_id_var, | 2547 PP_Var session_id_var, |
2374 PP_Var init_data_var) { | 2548 PP_Var init_data_var) { |
2375 // TODO(tomfinegan): send the data to media stack. | 2549 // TODO(tomfinegan): send the data to media stack. |
2376 } | 2550 } |
2377 | 2551 |
2378 void PluginInstance::KeyAdded(PP_Instance instance, | 2552 void PluginInstance::KeyAdded(PP_Instance instance, |
2379 PP_Var key_system_var, | 2553 PP_Var key_system_var, |
2380 PP_Var session_id_var) { | 2554 PP_Var session_id_var) { |
| 2555 if (!decryptor_client_) |
| 2556 return; |
| 2557 |
2381 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); | 2558 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); |
2382 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); | 2559 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); |
2383 if (!key_system_string || !session_id_string) { | 2560 if (!key_system_string || !session_id_string) { |
2384 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); | 2561 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); |
2385 return; | 2562 return; |
2386 } | 2563 } |
2387 | 2564 |
2388 DCHECK(decryptor_client_); | |
2389 decryptor_client_->KeyAdded(key_system_string->value(), | 2565 decryptor_client_->KeyAdded(key_system_string->value(), |
2390 session_id_string->value()); | 2566 session_id_string->value()); |
2391 } | 2567 } |
2392 | 2568 |
2393 void PluginInstance::KeyMessage(PP_Instance instance, | 2569 void PluginInstance::KeyMessage(PP_Instance instance, |
2394 PP_Var key_system_var, | 2570 PP_Var key_system_var, |
2395 PP_Var session_id_var, | 2571 PP_Var session_id_var, |
2396 PP_Resource message_resource, | 2572 PP_Resource message_resource, |
2397 PP_Var default_url_var) { | 2573 PP_Var default_url_var) { |
| 2574 if (!decryptor_client_) |
| 2575 return; |
| 2576 |
2398 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); | 2577 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); |
2399 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); | 2578 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); |
2400 StringVar* default_url_string = StringVar::FromPPVar(default_url_var); | 2579 StringVar* default_url_string = StringVar::FromPPVar(default_url_var); |
2401 | 2580 |
2402 if (!key_system_string || !session_id_string || !default_url_string) { | 2581 if (!key_system_string || !session_id_string || !default_url_string) { |
2403 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); | 2582 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); |
2404 return; | 2583 return; |
2405 } | 2584 } |
2406 | 2585 |
2407 EnterResourceNoLock<PPB_Buffer_API> enter(message_resource, true); | 2586 EnterResourceNoLock<PPB_Buffer_API> enter(message_resource, true); |
2408 if (!enter.succeeded()) { | 2587 if (!enter.succeeded()) { |
2409 decryptor_client_->KeyError(key_system_string->value(), | 2588 decryptor_client_->KeyError(key_system_string->value(), |
2410 session_id_string->value(), | 2589 session_id_string->value(), |
2411 media::Decryptor::kUnknownError, | 2590 media::Decryptor::kUnknownError, |
2412 0); | 2591 0); |
2413 return; | 2592 return; |
2414 } | 2593 } |
2415 | 2594 |
2416 BufferAutoMapper mapper(enter.object()); | 2595 BufferAutoMapper mapper(enter.object()); |
2417 scoped_array<uint8> message_array(new uint8[mapper.size()]); | 2596 scoped_array<uint8> message_array(new uint8[mapper.size()]); |
2418 if (mapper.data() && mapper.size()) | 2597 if (mapper.data() && mapper.size()) |
2419 memcpy(message_array.get(), mapper.data(), mapper.size()); | 2598 memcpy(message_array.get(), mapper.data(), mapper.size()); |
2420 | 2599 |
2421 DCHECK(decryptor_client_); | |
2422 decryptor_client_->KeyMessage(key_system_string->value(), | 2600 decryptor_client_->KeyMessage(key_system_string->value(), |
2423 session_id_string->value(), | 2601 session_id_string->value(), |
2424 message_array.Pass(), | 2602 message_array.Pass(), |
2425 mapper.size(), | 2603 mapper.size(), |
2426 default_url_string->value()); | 2604 default_url_string->value()); |
2427 } | 2605 } |
2428 | 2606 |
2429 void PluginInstance::KeyError(PP_Instance instance, | 2607 void PluginInstance::KeyError(PP_Instance instance, |
2430 PP_Var key_system_var, | 2608 PP_Var key_system_var, |
2431 PP_Var session_id_var, | 2609 PP_Var session_id_var, |
2432 int32_t media_error, | 2610 int32_t media_error, |
2433 int32_t system_code) { | 2611 int32_t system_code) { |
| 2612 if (!decryptor_client_) |
| 2613 return; |
| 2614 |
2434 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); | 2615 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); |
2435 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); | 2616 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); |
2436 if (!key_system_string || !session_id_string) { | 2617 if (!key_system_string || !session_id_string) { |
2437 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); | 2618 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); |
2438 return; | 2619 return; |
2439 } | 2620 } |
2440 | 2621 |
2441 DCHECK(decryptor_client_); | |
2442 decryptor_client_->KeyError( | 2622 decryptor_client_->KeyError( |
2443 key_system_string->value(), | 2623 key_system_string->value(), |
2444 session_id_string->value(), | 2624 session_id_string->value(), |
2445 static_cast<media::Decryptor::KeyError>(media_error), | 2625 static_cast<media::Decryptor::KeyError>(media_error), |
2446 system_code); | 2626 system_code); |
2447 } | 2627 } |
2448 | 2628 |
2449 void PluginInstance::DecoderInitializeDone(PP_Instance instance, | 2629 void PluginInstance::DecoderInitializeDone(PP_Instance instance, |
2450 PP_DecryptorStreamType decoder_type, | 2630 PP_DecryptorStreamType decoder_type, |
2451 uint32_t request_id, | 2631 uint32_t request_id, |
(...skipping 30 matching lines...) Expand all Loading... |
2482 | 2662 |
2483 void PluginInstance::DecoderResetDone(PP_Instance instance, | 2663 void PluginInstance::DecoderResetDone(PP_Instance instance, |
2484 PP_DecryptorStreamType decoder_type, | 2664 PP_DecryptorStreamType decoder_type, |
2485 uint32_t request_id) { | 2665 uint32_t request_id) { |
2486 // TODO(tomfinegan): Add decoder reset completion handling. | 2666 // TODO(tomfinegan): Add decoder reset completion handling. |
2487 } | 2667 } |
2488 | 2668 |
2489 void PluginInstance::DeliverBlock(PP_Instance instance, | 2669 void PluginInstance::DeliverBlock(PP_Instance instance, |
2490 PP_Resource decrypted_block, | 2670 PP_Resource decrypted_block, |
2491 const PP_DecryptedBlockInfo* block_info) { | 2671 const PP_DecryptedBlockInfo* block_info) { |
2492 DVLOG(2) << "DeliverBlock() - request_id: " | |
2493 << block_info->tracking_info.request_id; | |
2494 DCHECK(block_info); | 2672 DCHECK(block_info); |
2495 DecryptionCBMap::iterator found = pending_decryption_cbs_.find( | 2673 const uint32_t request_id = block_info->tracking_info.request_id; |
2496 block_info->tracking_info.request_id); | 2674 DVLOG(2) << "DeliverBlock() - request_id: " << request_id; |
2497 if (found == pending_decryption_cbs_.end()) | 2675 |
| 2676 // If the request ID is not valid or does not match what's saved, do nothing. |
| 2677 if (request_id == 0) { |
| 2678 DVLOG(1) << "DeliverBlock() - invalid request_id " << request_id; |
2498 return; | 2679 return; |
2499 media::Decryptor::DecryptCB decrypt_cb = found->second; | 2680 } |
2500 pending_decryption_cbs_.erase(found); | 2681 |
| 2682 media::Decryptor::DecryptCB decrypt_cb; |
| 2683 if (request_id == pending_audio_decrypt_request_id_) { |
| 2684 DCHECK(!pending_audio_decrypt_cb_.is_null()); |
| 2685 pending_audio_decrypt_request_id_ = 0; |
| 2686 decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_); |
| 2687 } else if (request_id == pending_video_decrypt_request_id_) { |
| 2688 DCHECK(!pending_video_decrypt_cb_.is_null()); |
| 2689 pending_video_decrypt_request_id_ = 0; |
| 2690 decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_); |
| 2691 } else { |
| 2692 DVLOG(1) << "DeliverBlock() - request_id " << request_id << " not found"; |
| 2693 return; |
| 2694 } |
2501 | 2695 |
2502 media::Decryptor::Status status = | 2696 media::Decryptor::Status status = |
2503 PpDecryptResultToMediaDecryptorStatus(block_info->result); | 2697 PpDecryptResultToMediaDecryptorStatus(block_info->result); |
2504 if (status != media::Decryptor::kSuccess) { | 2698 if (status != media::Decryptor::kSuccess) { |
2505 decrypt_cb.Run(status, NULL); | 2699 decrypt_cb.Run(status, NULL); |
2506 return; | 2700 return; |
2507 } | 2701 } |
2508 | 2702 |
2509 EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true); | 2703 EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true); |
2510 if (!enter.succeeded()) { | 2704 if (!enter.succeeded()) { |
(...skipping 12 matching lines...) Expand all Loading... |
2523 media::DecoderBuffer::CopyFrom( | 2717 media::DecoderBuffer::CopyFrom( |
2524 static_cast<uint8*>(mapper.data()), mapper.size())); | 2718 static_cast<uint8*>(mapper.data()), mapper.size())); |
2525 decrypted_buffer->SetTimestamp(base::TimeDelta::FromMicroseconds( | 2719 decrypted_buffer->SetTimestamp(base::TimeDelta::FromMicroseconds( |
2526 block_info->tracking_info.timestamp)); | 2720 block_info->tracking_info.timestamp)); |
2527 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); | 2721 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); |
2528 } | 2722 } |
2529 | 2723 |
2530 void PluginInstance::DeliverFrame(PP_Instance instance, | 2724 void PluginInstance::DeliverFrame(PP_Instance instance, |
2531 PP_Resource decrypted_frame, | 2725 PP_Resource decrypted_frame, |
2532 const PP_DecryptedFrameInfo* frame_info) { | 2726 const PP_DecryptedFrameInfo* frame_info) { |
2533 DVLOG(2) << "DeliverFrame() - request_id: " | |
2534 << frame_info->tracking_info.request_id; | |
2535 DCHECK(frame_info); | 2727 DCHECK(frame_info); |
| 2728 const uint32_t request_id = frame_info->tracking_info.request_id; |
| 2729 DVLOG(2) << "DeliverFrame() - request_id: " << request_id; |
2536 | 2730 |
2537 // If the request ID is not valid or does not match what's saved, do nothing. | 2731 // If the request ID is not valid or does not match what's saved, do nothing. |
2538 if (frame_info->tracking_info.request_id == 0 || | 2732 if (request_id == 0 || request_id != pending_video_decode_request_id_) { |
2539 frame_info->tracking_info.request_id != | 2733 DVLOG(1) << "DeliverFrame() - request_id " << request_id << " not found"; |
2540 pending_video_decode_request_id_) { | |
2541 DCHECK(pending_video_decode_cb_.is_null()); | |
2542 return; | 2734 return; |
2543 } | 2735 } |
2544 | 2736 |
2545 DCHECK(!pending_video_decode_cb_.is_null()); | 2737 DCHECK(!pending_video_decode_cb_.is_null()); |
2546 pending_video_decode_request_id_ = 0; | 2738 pending_video_decode_request_id_ = 0; |
2547 media::Decryptor::VideoDecodeCB video_decode_cb = | 2739 media::Decryptor::VideoDecodeCB video_decode_cb = |
2548 base::ResetAndReturn(&pending_video_decode_cb_); | 2740 base::ResetAndReturn(&pending_video_decode_cb_); |
2549 | 2741 |
2550 media::Decryptor::Status status = | 2742 media::Decryptor::Status status = |
2551 PpDecryptResultToMediaDecryptorStatus(frame_info->result); | 2743 PpDecryptResultToMediaDecryptorStatus(frame_info->result); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2596 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_V], | 2788 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_V], |
2597 frame_info->height, | 2789 frame_info->height, |
2598 decoded_frame.get()); | 2790 decoded_frame.get()); |
2599 | 2791 |
2600 video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame); | 2792 video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame); |
2601 } | 2793 } |
2602 | 2794 |
2603 void PluginInstance::DeliverSamples(PP_Instance instance, | 2795 void PluginInstance::DeliverSamples(PP_Instance instance, |
2604 PP_Resource audio_frames, | 2796 PP_Resource audio_frames, |
2605 const PP_DecryptedBlockInfo* block_info) { | 2797 const PP_DecryptedBlockInfo* block_info) { |
2606 DVLOG(2) << "DeliverSamples() - request_id: " | 2798 DCHECK(block_info); |
2607 << block_info->tracking_info.request_id; | 2799 const uint32_t request_id = block_info->tracking_info.request_id; |
2608 // TODO(tomfinegan): To be implemented after completion of v0.1 of the | 2800 DVLOG(2) << "DeliverSamples() - request_id: " << request_id; |
2609 // EME/CDM work. | 2801 |
| 2802 // If the request ID is not valid or does not match what's saved, do nothing. |
| 2803 if (request_id == 0 || request_id != pending_audio_decode_request_id_) { |
| 2804 DVLOG(1) << "DeliverSamples() - request_id " << request_id << " not found"; |
| 2805 return; |
| 2806 } |
| 2807 |
| 2808 DCHECK(!pending_audio_decode_cb_.is_null()); |
| 2809 pending_audio_decode_request_id_ = 0; |
| 2810 media::Decryptor::AudioDecodeCB audio_decode_cb = |
| 2811 base::ResetAndReturn(&pending_audio_decode_cb_); |
| 2812 |
| 2813 const media::Decryptor::AudioBuffers empty_frames; |
| 2814 |
| 2815 media::Decryptor::Status status = |
| 2816 PpDecryptResultToMediaDecryptorStatus(block_info->result); |
| 2817 if (status != media::Decryptor::kSuccess) { |
| 2818 audio_decode_cb.Run(status, empty_frames); |
| 2819 return; |
| 2820 } |
| 2821 |
| 2822 media::Decryptor::AudioBuffers audio_frame_list; |
| 2823 if (!DeserializeAudioFrames(audio_frames, &audio_frame_list)) { |
| 2824 NOTREACHED() << "CDM did not serialize the buffer correctly."; |
| 2825 audio_decode_cb.Run(media::Decryptor::kError, empty_frames); |
| 2826 return; |
| 2827 } |
| 2828 |
| 2829 audio_decode_cb.Run(media::Decryptor::kSuccess, audio_frame_list); |
2610 } | 2830 } |
2611 | 2831 |
2612 void PluginInstance::NumberOfFindResultsChanged(PP_Instance instance, | 2832 void PluginInstance::NumberOfFindResultsChanged(PP_Instance instance, |
2613 int32_t total, | 2833 int32_t total, |
2614 PP_Bool final_result) { | 2834 PP_Bool final_result) { |
2615 DCHECK_NE(find_identifier_, -1); | 2835 DCHECK_NE(find_identifier_, -1); |
2616 delegate_->NumberOfFindResultsChanged(find_identifier_, total, | 2836 delegate_->NumberOfFindResultsChanged(find_identifier_, total, |
2617 PP_ToBool(final_result)); | 2837 PP_ToBool(final_result)); |
2618 } | 2838 } |
2619 | 2839 |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2989 screen_size_for_fullscreen_ = gfx::Size(); | 3209 screen_size_for_fullscreen_ = gfx::Size(); |
2990 WebElement element = container_->element(); | 3210 WebElement element = container_->element(); |
2991 element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_); | 3211 element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_); |
2992 element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_); | 3212 element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_); |
2993 element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_); | 3213 element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_); |
2994 element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_); | 3214 element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_); |
2995 } | 3215 } |
2996 | 3216 |
2997 } // namespace ppapi | 3217 } // namespace ppapi |
2998 } // namespace webkit | 3218 } // namespace webkit |
OLD | NEW |