| 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 if (frame_size < 0 || bytes_left < frame_size) |
| 430 return false; |
| 431 |
| 432 scoped_refptr<media::DataBuffer> frame(new media::DataBuffer(frame_size)); |
| 433 if (frame_size > 0) { |
| 434 memcpy(frame->GetWritableData(), cur, frame_size); |
| 435 frame->SetTimestamp(base::TimeDelta::FromMicroseconds(timestamp)); |
| 436 cur += frame_size; |
| 437 bytes_left -= frame_size; |
| 438 } |
| 439 frames->push_back(frame); |
| 440 } while (bytes_left > 0); |
| 441 |
| 442 return true; |
| 443 } |
| 444 |
| 395 PP_AudioCodec MediaAudioCodecToPpAudioCodec(media::AudioCodec codec) { | 445 PP_AudioCodec MediaAudioCodecToPpAudioCodec(media::AudioCodec codec) { |
| 396 switch (codec) { | 446 switch (codec) { |
| 397 case media::kCodecVorbis: | 447 case media::kCodecVorbis: |
| 398 return PP_AUDIOCODEC_VORBIS; | 448 return PP_AUDIOCODEC_VORBIS; |
| 399 default: | 449 default: |
| 400 return PP_AUDIOCODEC_UNKNOWN; | 450 return PP_AUDIOCODEC_UNKNOWN; |
| 401 } | 451 } |
| 402 } | 452 } |
| 403 | 453 |
| 404 PP_VideoCodec MediaVideoCodecToPpVideoCodec(media::VideoCodec codec) { | 454 PP_VideoCodec MediaVideoCodecToPpVideoCodec(media::VideoCodec codec) { |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 text_input_type_(kPluginDefaultTextInputType), | 568 text_input_type_(kPluginDefaultTextInputType), |
| 519 text_input_caret_(0, 0, 0, 0), | 569 text_input_caret_(0, 0, 0, 0), |
| 520 text_input_caret_bounds_(0, 0, 0, 0), | 570 text_input_caret_bounds_(0, 0, 0, 0), |
| 521 text_input_caret_set_(false), | 571 text_input_caret_set_(false), |
| 522 selection_caret_(0), | 572 selection_caret_(0), |
| 523 selection_anchor_(0), | 573 selection_anchor_(0), |
| 524 pending_user_gesture_(0.0), | 574 pending_user_gesture_(0.0), |
| 525 flash_impl_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 575 flash_impl_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 526 decryptor_client_(NULL), | 576 decryptor_client_(NULL), |
| 527 next_decryption_request_id_(1), | 577 next_decryption_request_id_(1), |
| 578 pending_audio_decrypt_request_id_(0), |
| 579 pending_video_decrypt_request_id_(0), |
| 528 pending_audio_decoder_init_request_id_(0), | 580 pending_audio_decoder_init_request_id_(0), |
| 529 pending_video_decoder_init_request_id_(0), | 581 pending_video_decoder_init_request_id_(0), |
| 582 pending_audio_decode_request_id_(0), |
| 530 pending_video_decode_request_id_(0) { | 583 pending_video_decode_request_id_(0) { |
| 531 pp_instance_ = HostGlobals::Get()->AddInstance(this); | 584 pp_instance_ = HostGlobals::Get()->AddInstance(this); |
| 532 | 585 |
| 533 memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); | 586 memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); |
| 534 DCHECK(delegate); | 587 DCHECK(delegate); |
| 535 module_->InstanceCreated(this); | 588 module_->InstanceCreated(this); |
| 536 delegate_->InstanceCreated(this); | 589 delegate_->InstanceCreated(this); |
| 537 message_channel_.reset(new MessageChannel(this)); | 590 message_channel_.reset(new MessageChannel(this)); |
| 538 | 591 |
| 539 view_data_.is_page_visible = delegate->IsPageVisible(); | 592 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 = | 1582 PP_PrivatePageTransformType transform_type = |
| 1530 type == WebPlugin::RotationType90Clockwise ? | 1583 type == WebPlugin::RotationType90Clockwise ? |
| 1531 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CW : | 1584 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CW : |
| 1532 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CCW; | 1585 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CCW; |
| 1533 plugin_pdf_interface_->Transform(pp_instance(), transform_type); | 1586 plugin_pdf_interface_->Transform(pp_instance(), transform_type); |
| 1534 // NOTE: plugin instance may have been deleted. | 1587 // NOTE: plugin instance may have been deleted. |
| 1535 } | 1588 } |
| 1536 | 1589 |
| 1537 void PluginInstance::set_decrypt_client( | 1590 void PluginInstance::set_decrypt_client( |
| 1538 media::DecryptorClient* decryptor_client) { | 1591 media::DecryptorClient* decryptor_client) { |
| 1539 DCHECK(decryptor_client); | |
| 1540 decryptor_client_ = decryptor_client; | 1592 decryptor_client_ = decryptor_client; |
| 1541 } | 1593 } |
| 1542 | 1594 |
| 1543 bool PluginInstance::GenerateKeyRequest(const std::string& key_system, | 1595 bool PluginInstance::GenerateKeyRequest(const std::string& key_system, |
| 1544 const std::string& init_data) { | 1596 const std::string& init_data) { |
| 1545 if (!LoadContentDecryptorInterface()) | 1597 if (!LoadContentDecryptorInterface()) |
| 1546 return false; | 1598 return false; |
| 1547 if (key_system.empty()) | 1599 if (key_system.empty()) |
| 1548 return false; | 1600 return false; |
| 1549 | 1601 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1581 | 1633 |
| 1582 bool PluginInstance::CancelKeyRequest(const std::string& session_id) { | 1634 bool PluginInstance::CancelKeyRequest(const std::string& session_id) { |
| 1583 if (!LoadContentDecryptorInterface()) | 1635 if (!LoadContentDecryptorInterface()) |
| 1584 return false; | 1636 return false; |
| 1585 plugin_decryption_interface_->CancelKeyRequest( | 1637 plugin_decryption_interface_->CancelKeyRequest( |
| 1586 pp_instance(), | 1638 pp_instance(), |
| 1587 StringVar::StringToPPVar(session_id)); | 1639 StringVar::StringToPPVar(session_id)); |
| 1588 return true; | 1640 return true; |
| 1589 } | 1641 } |
| 1590 | 1642 |
| 1643 // TODO(xhwang): Remove duplication of code in Decrypt(), |
| 1644 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). |
| 1591 bool PluginInstance::Decrypt( | 1645 bool PluginInstance::Decrypt( |
| 1646 media::Decryptor::StreamType stream_type, |
| 1592 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 1647 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
| 1593 const media::Decryptor::DecryptCB& decrypt_cb) { | 1648 const media::Decryptor::DecryptCB& decrypt_cb) { |
| 1594 DVLOG(3) << "Decrypt()"; | 1649 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; |
| 1595 if (!LoadContentDecryptorInterface()) | 1650 if (!LoadContentDecryptorInterface()) |
| 1596 return false; | 1651 return false; |
| 1597 | 1652 |
| 1598 ScopedPPResource encrypted_resource( | 1653 ScopedPPResource encrypted_resource( |
| 1599 ScopedPPResource::PassRef(), | 1654 ScopedPPResource::PassRef(), |
| 1600 MakeBufferResource(pp_instance(), | 1655 MakeBufferResource(pp_instance(), |
| 1601 encrypted_buffer->GetData(), | 1656 encrypted_buffer->GetData(), |
| 1602 encrypted_buffer->GetDataSize())); | 1657 encrypted_buffer->GetDataSize())); |
| 1603 if (!encrypted_resource.get()) | 1658 if (!encrypted_resource.get()) |
| 1604 return false; | 1659 return false; |
| 1605 | 1660 |
| 1606 const uint32_t request_id = next_decryption_request_id_++; | 1661 const uint32_t request_id = next_decryption_request_id_++; |
| 1607 DVLOG(2) << "Decrypt() - request_id " << request_id; | 1662 DVLOG(2) << "Decrypt() - request_id " << request_id; |
| 1608 | 1663 |
| 1609 PP_EncryptedBlockInfo block_info; | 1664 PP_EncryptedBlockInfo block_info; |
| 1610 DCHECK(encrypted_buffer->GetDecryptConfig()); | 1665 DCHECK(encrypted_buffer->GetDecryptConfig()); |
| 1611 if (!MakeEncryptedBlockInfo(encrypted_buffer->GetDecryptConfig(), | 1666 if (!MakeEncryptedBlockInfo(encrypted_buffer->GetDecryptConfig(), |
| 1612 encrypted_buffer->GetTimestamp().InMicroseconds(), | 1667 encrypted_buffer->GetTimestamp().InMicroseconds(), |
| 1613 request_id, | 1668 request_id, |
| 1614 &block_info)) { | 1669 &block_info)) { |
| 1615 return false; | 1670 return false; |
| 1616 } | 1671 } |
| 1617 | 1672 |
| 1618 DCHECK(!ContainsKey(pending_decryption_cbs_, request_id)); | 1673 // 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)); | 1674 // enforced by the media pipeline. |
| 1675 switch (stream_type) { |
| 1676 case media::Decryptor::kAudio: |
| 1677 DCHECK_EQ(pending_audio_decrypt_request_id_, 0u); |
| 1678 DCHECK(pending_audio_decrypt_cb_.is_null()); |
| 1679 pending_audio_decrypt_request_id_ = request_id; |
| 1680 pending_audio_decrypt_cb_ = decrypt_cb; |
| 1681 break; |
| 1682 case media::Decryptor::kVideo: |
| 1683 DCHECK_EQ(pending_video_decrypt_request_id_, 0u); |
| 1684 DCHECK(pending_video_decrypt_cb_.is_null()); |
| 1685 pending_video_decrypt_request_id_ = request_id; |
| 1686 pending_video_decrypt_cb_ = decrypt_cb; |
| 1687 break; |
| 1688 default: |
| 1689 NOTREACHED(); |
| 1690 return false; |
| 1691 } |
| 1620 | 1692 |
| 1621 plugin_decryption_interface_->Decrypt(pp_instance(), | 1693 plugin_decryption_interface_->Decrypt(pp_instance(), |
| 1622 encrypted_resource, | 1694 encrypted_resource, |
| 1623 &block_info); | 1695 &block_info); |
| 1624 return true; | 1696 return true; |
| 1625 } | 1697 } |
| 1626 | 1698 |
| 1699 bool PluginInstance::CancelDecrypt(media::Decryptor::StreamType stream_type) { |
| 1700 DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type; |
| 1701 |
| 1702 media::Decryptor::DecryptCB decrypt_cb; |
| 1703 switch (stream_type) { |
| 1704 case media::Decryptor::kAudio: |
| 1705 pending_audio_decrypt_request_id_ = 0; |
| 1706 decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_); |
| 1707 break; |
| 1708 case media::Decryptor::kVideo: |
| 1709 pending_video_decrypt_request_id_ = 0; |
| 1710 decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_); |
| 1711 break; |
| 1712 default: |
| 1713 NOTREACHED(); |
| 1714 return false; |
| 1715 } |
| 1716 |
| 1717 if (!decrypt_cb.is_null()) |
| 1718 decrypt_cb.Run(media::Decryptor::kSuccess, NULL); |
| 1719 |
| 1720 return true; |
| 1721 } |
| 1722 |
| 1627 bool PluginInstance::InitializeAudioDecoder( | 1723 bool PluginInstance::InitializeAudioDecoder( |
| 1628 const media::AudioDecoderConfig& decoder_config, | 1724 const media::AudioDecoderConfig& decoder_config, |
| 1629 const media::Decryptor::DecoderInitCB& init_cb) { | 1725 const media::Decryptor::DecoderInitCB& init_cb) { |
| 1630 PP_AudioDecoderConfig pp_decoder_config; | 1726 PP_AudioDecoderConfig pp_decoder_config; |
| 1631 pp_decoder_config.codec = | 1727 pp_decoder_config.codec = |
| 1632 MediaAudioCodecToPpAudioCodec(decoder_config.codec()); | 1728 MediaAudioCodecToPpAudioCodec(decoder_config.codec()); |
| 1633 pp_decoder_config.channel_count = | 1729 pp_decoder_config.channel_count = |
| 1634 media::ChannelLayoutToChannelCount(decoder_config.channel_layout()); | 1730 media::ChannelLayoutToChannelCount(decoder_config.channel_layout()); |
| 1635 pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel(); | 1731 pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel(); |
| 1636 pp_decoder_config.samples_per_second = decoder_config.samples_per_second(); | 1732 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()); | 1773 DCHECK(pending_video_decoder_init_cb_.is_null()); |
| 1678 pending_video_decoder_init_request_id_ = pp_decoder_config.request_id; | 1774 pending_video_decoder_init_request_id_ = pp_decoder_config.request_id; |
| 1679 pending_video_decoder_init_cb_ = init_cb; | 1775 pending_video_decoder_init_cb_ = init_cb; |
| 1680 | 1776 |
| 1681 plugin_decryption_interface_->InitializeVideoDecoder(pp_instance(), | 1777 plugin_decryption_interface_->InitializeVideoDecoder(pp_instance(), |
| 1682 &pp_decoder_config, | 1778 &pp_decoder_config, |
| 1683 extra_data_resource); | 1779 extra_data_resource); |
| 1684 return true; | 1780 return true; |
| 1685 } | 1781 } |
| 1686 | 1782 |
| 1687 bool PluginInstance::DeinitializeDecoder() { | 1783 void PluginInstance::CancelDecode(media::Decryptor::StreamType stream_type) { |
| 1784 switch (stream_type) { |
| 1785 case media::Decryptor::kAudio: |
| 1786 pending_audio_decode_request_id_ = 0; |
| 1787 if (!pending_audio_decode_cb_.is_null()) |
| 1788 base::ResetAndReturn(&pending_audio_decode_cb_).Run( |
| 1789 media::Decryptor::kSuccess, media::Decryptor::AudioBuffers()); |
| 1790 break; |
| 1791 case media::Decryptor::kVideo: |
| 1792 pending_video_decode_request_id_ = 0; |
| 1793 if (!pending_video_decode_cb_.is_null()) |
| 1794 base::ResetAndReturn(&pending_video_decode_cb_).Run( |
| 1795 media::Decryptor::kSuccess, NULL); |
| 1796 break; |
| 1797 default: |
| 1798 NOTREACHED(); |
| 1799 } |
| 1800 } |
| 1801 |
| 1802 bool PluginInstance::DeinitializeDecoder( |
| 1803 media::Decryptor::StreamType stream_type) { |
| 1688 if (!LoadContentDecryptorInterface()) | 1804 if (!LoadContentDecryptorInterface()) |
| 1689 return false; | 1805 return false; |
| 1690 | 1806 |
| 1807 CancelDecode(stream_type); |
| 1808 |
| 1691 // TODO(tomfinegan): Add decoder deinitialize request tracking, and get | 1809 // TODO(tomfinegan): Add decoder deinitialize request tracking, and get |
| 1692 // stream type from media stack. | 1810 // stream type from media stack. |
| 1693 plugin_decryption_interface_->DeinitializeDecoder( | 1811 plugin_decryption_interface_->DeinitializeDecoder( |
| 1694 pp_instance(), | 1812 pp_instance(), |
| 1695 PP_DECRYPTORSTREAMTYPE_VIDEO, | 1813 PP_DECRYPTORSTREAMTYPE_VIDEO, |
| 1696 0); | 1814 0); |
| 1697 return true; | 1815 return true; |
| 1698 } | 1816 } |
| 1699 | 1817 |
| 1700 bool PluginInstance::ResetDecoder() { | 1818 bool PluginInstance::ResetDecoder(media::Decryptor::StreamType stream_type) { |
| 1701 if (!LoadContentDecryptorInterface()) | 1819 if (!LoadContentDecryptorInterface()) |
| 1702 return false; | 1820 return false; |
| 1703 | 1821 |
| 1822 CancelDecode(stream_type); |
| 1823 |
| 1704 // TODO(tomfinegan): Add decoder reset request tracking, and get | 1824 // TODO(tomfinegan): Add decoder reset request tracking, and get |
| 1705 // stream type from media stack. | 1825 // stream type from media stack. |
| 1706 plugin_decryption_interface_->ResetDecoder(pp_instance(), | 1826 plugin_decryption_interface_->ResetDecoder(pp_instance(), |
| 1707 PP_DECRYPTORSTREAMTYPE_VIDEO, | 1827 PP_DECRYPTORSTREAMTYPE_VIDEO, |
| 1708 0); | 1828 0); |
| 1709 return true; | 1829 return true; |
| 1710 } | 1830 } |
| 1711 | 1831 |
| 1712 bool PluginInstance::DecryptAndDecode( | 1832 bool PluginInstance::DecryptAndDecodeAudio( |
| 1833 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
| 1834 const media::Decryptor::AudioDecodeCB& audio_decode_cb) { |
| 1835 if (!LoadContentDecryptorInterface()) |
| 1836 return false; |
| 1837 |
| 1838 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize() |
| 1839 // return NULL and 0 respectively. In that case, we'll just create a 0 |
| 1840 // resource. |
| 1841 ScopedPPResource encrypted_resource( |
| 1842 ScopedPPResource::PassRef(), |
| 1843 MakeBufferResource(pp_instance(), |
| 1844 encrypted_buffer->GetData(), |
| 1845 encrypted_buffer->GetDataSize())); |
| 1846 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) |
| 1847 return false; |
| 1848 |
| 1849 const uint32_t request_id = next_decryption_request_id_++; |
| 1850 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; |
| 1851 |
| 1852 PP_EncryptedBlockInfo block_info; |
| 1853 if (!MakeEncryptedBlockInfo( |
| 1854 encrypted_buffer->GetDecryptConfig(), |
| 1855 encrypted_buffer->GetTimestamp().InMicroseconds(), |
| 1856 request_id, |
| 1857 &block_info)) { |
| 1858 return false; |
| 1859 } |
| 1860 |
| 1861 // There is only one pending audio decode request at any time. This is |
| 1862 // enforced by the media pipeline. |
| 1863 DCHECK_EQ(pending_audio_decode_request_id_, 0u); |
| 1864 DCHECK(pending_audio_decode_cb_.is_null()); |
| 1865 pending_audio_decode_request_id_ = request_id; |
| 1866 pending_audio_decode_cb_ = audio_decode_cb; |
| 1867 |
| 1868 plugin_decryption_interface_->DecryptAndDecode(pp_instance(), |
| 1869 PP_DECRYPTORSTREAMTYPE_AUDIO, |
| 1870 encrypted_resource, |
| 1871 &block_info); |
| 1872 return true; |
| 1873 } |
| 1874 |
| 1875 bool PluginInstance::DecryptAndDecodeVideo( |
| 1713 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 1876 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
| 1714 const media::Decryptor::VideoDecodeCB& video_decode_cb) { | 1877 const media::Decryptor::VideoDecodeCB& video_decode_cb) { |
| 1715 if (!LoadContentDecryptorInterface()) | 1878 if (!LoadContentDecryptorInterface()) |
| 1716 return false; | 1879 return false; |
| 1717 | 1880 |
| 1718 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize() | 1881 // 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 | 1882 // return NULL and 0 respectively. In that case, we'll just create a 0 |
| 1720 // resource. | 1883 // resource. |
| 1721 ScopedPPResource encrypted_resource( | 1884 ScopedPPResource encrypted_resource( |
| 1722 ScopedPPResource::PassRef(), | 1885 ScopedPPResource::PassRef(), |
| 1723 MakeBufferResource(pp_instance(), | 1886 MakeBufferResource(pp_instance(), |
| 1724 encrypted_buffer->GetData(), | 1887 encrypted_buffer->GetData(), |
| 1725 encrypted_buffer->GetDataSize())); | 1888 encrypted_buffer->GetDataSize())); |
| 1726 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) | 1889 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) |
| 1727 return false; | 1890 return false; |
| 1728 | 1891 |
| 1729 const uint32_t request_id = next_decryption_request_id_++; | 1892 const uint32_t request_id = next_decryption_request_id_++; |
| 1730 DVLOG(2) << "DecryptAndDecode() - request_id " << request_id; | 1893 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; |
| 1731 | 1894 |
| 1732 PP_EncryptedBlockInfo block_info; | 1895 PP_EncryptedBlockInfo block_info; |
| 1733 if (!MakeEncryptedBlockInfo( | 1896 if (!MakeEncryptedBlockInfo( |
| 1734 encrypted_buffer->GetDecryptConfig(), | 1897 encrypted_buffer->GetDecryptConfig(), |
| 1735 encrypted_buffer->GetTimestamp().InMicroseconds(), | 1898 encrypted_buffer->GetTimestamp().InMicroseconds(), |
| 1736 request_id, | 1899 request_id, |
| 1737 &block_info)) { | 1900 &block_info)) { |
| 1738 return false; | 1901 return false; |
| 1739 } | 1902 } |
| 1740 | 1903 |
| (...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2371 void PluginInstance::NeedKey(PP_Instance instance, | 2534 void PluginInstance::NeedKey(PP_Instance instance, |
| 2372 PP_Var key_system_var, | 2535 PP_Var key_system_var, |
| 2373 PP_Var session_id_var, | 2536 PP_Var session_id_var, |
| 2374 PP_Var init_data_var) { | 2537 PP_Var init_data_var) { |
| 2375 // TODO(tomfinegan): send the data to media stack. | 2538 // TODO(tomfinegan): send the data to media stack. |
| 2376 } | 2539 } |
| 2377 | 2540 |
| 2378 void PluginInstance::KeyAdded(PP_Instance instance, | 2541 void PluginInstance::KeyAdded(PP_Instance instance, |
| 2379 PP_Var key_system_var, | 2542 PP_Var key_system_var, |
| 2380 PP_Var session_id_var) { | 2543 PP_Var session_id_var) { |
| 2544 if (!decryptor_client_) |
| 2545 return; |
| 2546 |
| 2381 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); | 2547 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); |
| 2382 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); | 2548 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); |
| 2383 if (!key_system_string || !session_id_string) { | 2549 if (!key_system_string || !session_id_string) { |
| 2384 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); | 2550 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); |
| 2385 return; | 2551 return; |
| 2386 } | 2552 } |
| 2387 | 2553 |
| 2388 DCHECK(decryptor_client_); | |
| 2389 decryptor_client_->KeyAdded(key_system_string->value(), | 2554 decryptor_client_->KeyAdded(key_system_string->value(), |
| 2390 session_id_string->value()); | 2555 session_id_string->value()); |
| 2391 } | 2556 } |
| 2392 | 2557 |
| 2393 void PluginInstance::KeyMessage(PP_Instance instance, | 2558 void PluginInstance::KeyMessage(PP_Instance instance, |
| 2394 PP_Var key_system_var, | 2559 PP_Var key_system_var, |
| 2395 PP_Var session_id_var, | 2560 PP_Var session_id_var, |
| 2396 PP_Resource message_resource, | 2561 PP_Resource message_resource, |
| 2397 PP_Var default_url_var) { | 2562 PP_Var default_url_var) { |
| 2563 if (!decryptor_client_) |
| 2564 return; |
| 2565 |
| 2398 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); | 2566 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); |
| 2399 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); | 2567 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); |
| 2400 StringVar* default_url_string = StringVar::FromPPVar(default_url_var); | 2568 StringVar* default_url_string = StringVar::FromPPVar(default_url_var); |
| 2401 | 2569 |
| 2402 if (!key_system_string || !session_id_string || !default_url_string) { | 2570 if (!key_system_string || !session_id_string || !default_url_string) { |
| 2403 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); | 2571 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); |
| 2404 return; | 2572 return; |
| 2405 } | 2573 } |
| 2406 | 2574 |
| 2407 EnterResourceNoLock<PPB_Buffer_API> enter(message_resource, true); | 2575 EnterResourceNoLock<PPB_Buffer_API> enter(message_resource, true); |
| 2408 if (!enter.succeeded()) { | 2576 if (!enter.succeeded()) { |
| 2409 decryptor_client_->KeyError(key_system_string->value(), | 2577 decryptor_client_->KeyError(key_system_string->value(), |
| 2410 session_id_string->value(), | 2578 session_id_string->value(), |
| 2411 media::Decryptor::kUnknownError, | 2579 media::Decryptor::kUnknownError, |
| 2412 0); | 2580 0); |
| 2413 return; | 2581 return; |
| 2414 } | 2582 } |
| 2415 | 2583 |
| 2416 BufferAutoMapper mapper(enter.object()); | 2584 BufferAutoMapper mapper(enter.object()); |
| 2417 scoped_array<uint8> message_array(new uint8[mapper.size()]); | 2585 scoped_array<uint8> message_array(new uint8[mapper.size()]); |
| 2418 if (mapper.data() && mapper.size()) | 2586 if (mapper.data() && mapper.size()) |
| 2419 memcpy(message_array.get(), mapper.data(), mapper.size()); | 2587 memcpy(message_array.get(), mapper.data(), mapper.size()); |
| 2420 | 2588 |
| 2421 DCHECK(decryptor_client_); | |
| 2422 decryptor_client_->KeyMessage(key_system_string->value(), | 2589 decryptor_client_->KeyMessage(key_system_string->value(), |
| 2423 session_id_string->value(), | 2590 session_id_string->value(), |
| 2424 message_array.Pass(), | 2591 message_array.Pass(), |
| 2425 mapper.size(), | 2592 mapper.size(), |
| 2426 default_url_string->value()); | 2593 default_url_string->value()); |
| 2427 } | 2594 } |
| 2428 | 2595 |
| 2429 void PluginInstance::KeyError(PP_Instance instance, | 2596 void PluginInstance::KeyError(PP_Instance instance, |
| 2430 PP_Var key_system_var, | 2597 PP_Var key_system_var, |
| 2431 PP_Var session_id_var, | 2598 PP_Var session_id_var, |
| 2432 int32_t media_error, | 2599 int32_t media_error, |
| 2433 int32_t system_code) { | 2600 int32_t system_code) { |
| 2601 if (!decryptor_client_) |
| 2602 return; |
| 2603 |
| 2434 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); | 2604 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); |
| 2435 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); | 2605 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); |
| 2436 if (!key_system_string || !session_id_string) { | 2606 if (!key_system_string || !session_id_string) { |
| 2437 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); | 2607 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); |
| 2438 return; | 2608 return; |
| 2439 } | 2609 } |
| 2440 | 2610 |
| 2441 DCHECK(decryptor_client_); | |
| 2442 decryptor_client_->KeyError( | 2611 decryptor_client_->KeyError( |
| 2443 key_system_string->value(), | 2612 key_system_string->value(), |
| 2444 session_id_string->value(), | 2613 session_id_string->value(), |
| 2445 static_cast<media::Decryptor::KeyError>(media_error), | 2614 static_cast<media::Decryptor::KeyError>(media_error), |
| 2446 system_code); | 2615 system_code); |
| 2447 } | 2616 } |
| 2448 | 2617 |
| 2449 void PluginInstance::DecoderInitializeDone(PP_Instance instance, | 2618 void PluginInstance::DecoderInitializeDone(PP_Instance instance, |
| 2450 PP_DecryptorStreamType decoder_type, | 2619 PP_DecryptorStreamType decoder_type, |
| 2451 uint32_t request_id, | 2620 uint32_t request_id, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2482 | 2651 |
| 2483 void PluginInstance::DecoderResetDone(PP_Instance instance, | 2652 void PluginInstance::DecoderResetDone(PP_Instance instance, |
| 2484 PP_DecryptorStreamType decoder_type, | 2653 PP_DecryptorStreamType decoder_type, |
| 2485 uint32_t request_id) { | 2654 uint32_t request_id) { |
| 2486 // TODO(tomfinegan): Add decoder reset completion handling. | 2655 // TODO(tomfinegan): Add decoder reset completion handling. |
| 2487 } | 2656 } |
| 2488 | 2657 |
| 2489 void PluginInstance::DeliverBlock(PP_Instance instance, | 2658 void PluginInstance::DeliverBlock(PP_Instance instance, |
| 2490 PP_Resource decrypted_block, | 2659 PP_Resource decrypted_block, |
| 2491 const PP_DecryptedBlockInfo* block_info) { | 2660 const PP_DecryptedBlockInfo* block_info) { |
| 2492 DVLOG(2) << "DeliverBlock() - request_id: " | |
| 2493 << block_info->tracking_info.request_id; | |
| 2494 DCHECK(block_info); | 2661 DCHECK(block_info); |
| 2495 DecryptionCBMap::iterator found = pending_decryption_cbs_.find( | 2662 const uint32_t request_id = block_info->tracking_info.request_id; |
| 2496 block_info->tracking_info.request_id); | 2663 DVLOG(2) << "DeliverBlock() - request_id: " << request_id; |
| 2497 if (found == pending_decryption_cbs_.end()) | 2664 |
| 2665 // If the request ID is not valid or does not match what's saved, do nothing. |
| 2666 if (request_id == 0) { |
| 2667 DVLOG(1) << "DeliverBlock() - invalid request_id " << request_id; |
| 2498 return; | 2668 return; |
| 2499 media::Decryptor::DecryptCB decrypt_cb = found->second; | 2669 } |
| 2500 pending_decryption_cbs_.erase(found); | 2670 |
| 2671 media::Decryptor::DecryptCB decrypt_cb; |
| 2672 if (request_id == pending_audio_decrypt_request_id_) { |
| 2673 DCHECK(!pending_audio_decrypt_cb_.is_null()); |
| 2674 pending_audio_decrypt_request_id_ = 0; |
| 2675 decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_); |
| 2676 } else if (request_id == pending_video_decrypt_request_id_) { |
| 2677 DCHECK(!pending_video_decrypt_cb_.is_null()); |
| 2678 pending_video_decrypt_request_id_ = 0; |
| 2679 decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_); |
| 2680 } else { |
| 2681 DVLOG(1) << "DeliverBlock() - request_id " << request_id << " not found"; |
| 2682 return; |
| 2683 } |
| 2501 | 2684 |
| 2502 media::Decryptor::Status status = | 2685 media::Decryptor::Status status = |
| 2503 PpDecryptResultToMediaDecryptorStatus(block_info->result); | 2686 PpDecryptResultToMediaDecryptorStatus(block_info->result); |
| 2504 if (status != media::Decryptor::kSuccess) { | 2687 if (status != media::Decryptor::kSuccess) { |
| 2505 decrypt_cb.Run(status, NULL); | 2688 decrypt_cb.Run(status, NULL); |
| 2506 return; | 2689 return; |
| 2507 } | 2690 } |
| 2508 | 2691 |
| 2509 EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true); | 2692 EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true); |
| 2510 if (!enter.succeeded()) { | 2693 if (!enter.succeeded()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2523 media::DecoderBuffer::CopyFrom( | 2706 media::DecoderBuffer::CopyFrom( |
| 2524 static_cast<uint8*>(mapper.data()), mapper.size())); | 2707 static_cast<uint8*>(mapper.data()), mapper.size())); |
| 2525 decrypted_buffer->SetTimestamp(base::TimeDelta::FromMicroseconds( | 2708 decrypted_buffer->SetTimestamp(base::TimeDelta::FromMicroseconds( |
| 2526 block_info->tracking_info.timestamp)); | 2709 block_info->tracking_info.timestamp)); |
| 2527 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); | 2710 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); |
| 2528 } | 2711 } |
| 2529 | 2712 |
| 2530 void PluginInstance::DeliverFrame(PP_Instance instance, | 2713 void PluginInstance::DeliverFrame(PP_Instance instance, |
| 2531 PP_Resource decrypted_frame, | 2714 PP_Resource decrypted_frame, |
| 2532 const PP_DecryptedFrameInfo* frame_info) { | 2715 const PP_DecryptedFrameInfo* frame_info) { |
| 2533 DVLOG(2) << "DeliverFrame() - request_id: " | |
| 2534 << frame_info->tracking_info.request_id; | |
| 2535 DCHECK(frame_info); | 2716 DCHECK(frame_info); |
| 2717 const uint32_t request_id = frame_info->tracking_info.request_id; |
| 2718 DVLOG(2) << "DeliverFrame() - request_id: " << request_id; |
| 2536 | 2719 |
| 2537 // If the request ID is not valid or does not match what's saved, do nothing. | 2720 // 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 || | 2721 if (request_id == 0 || request_id != pending_video_decode_request_id_) { |
| 2539 frame_info->tracking_info.request_id != | 2722 DVLOG(1) << "DeliverFrame() - request_id " << request_id << " not found"; |
| 2540 pending_video_decode_request_id_) { | |
| 2541 DCHECK(pending_video_decode_cb_.is_null()); | 2723 DCHECK(pending_video_decode_cb_.is_null()); |
| 2542 return; | 2724 return; |
| 2543 } | 2725 } |
| 2544 | 2726 |
| 2545 DCHECK(!pending_video_decode_cb_.is_null()); | 2727 DCHECK(!pending_video_decode_cb_.is_null()); |
| 2546 pending_video_decode_request_id_ = 0; | 2728 pending_video_decode_request_id_ = 0; |
| 2547 media::Decryptor::VideoDecodeCB video_decode_cb = | 2729 media::Decryptor::VideoDecodeCB video_decode_cb = |
| 2548 base::ResetAndReturn(&pending_video_decode_cb_); | 2730 base::ResetAndReturn(&pending_video_decode_cb_); |
| 2549 | 2731 |
| 2550 media::Decryptor::Status status = | 2732 media::Decryptor::Status status = |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2596 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_V], | 2778 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_V], |
| 2597 frame_info->height, | 2779 frame_info->height, |
| 2598 decoded_frame.get()); | 2780 decoded_frame.get()); |
| 2599 | 2781 |
| 2600 video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame); | 2782 video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame); |
| 2601 } | 2783 } |
| 2602 | 2784 |
| 2603 void PluginInstance::DeliverSamples(PP_Instance instance, | 2785 void PluginInstance::DeliverSamples(PP_Instance instance, |
| 2604 PP_Resource audio_frames, | 2786 PP_Resource audio_frames, |
| 2605 const PP_DecryptedBlockInfo* block_info) { | 2787 const PP_DecryptedBlockInfo* block_info) { |
| 2606 DVLOG(2) << "DeliverSamples() - request_id: " | 2788 DCHECK(block_info); |
| 2607 << block_info->tracking_info.request_id; | 2789 const uint32_t request_id = block_info->tracking_info.request_id; |
| 2608 // TODO(tomfinegan): To be implemented after completion of v0.1 of the | 2790 DVLOG(2) << "DeliverSamples() - request_id: " << request_id; |
| 2609 // EME/CDM work. | 2791 |
| 2792 // If the request ID is not valid or does not match what's saved, do nothing. |
| 2793 if (request_id == 0 || request_id != pending_audio_decode_request_id_) { |
| 2794 DVLOG(1) << "DeliverSamples() - request_id " << request_id << " not found"; |
| 2795 DCHECK(pending_audio_decode_cb_.is_null()); |
| 2796 return; |
| 2797 } |
| 2798 |
| 2799 DCHECK(!pending_audio_decode_cb_.is_null()); |
| 2800 pending_audio_decode_request_id_ = 0; |
| 2801 media::Decryptor::AudioDecodeCB audio_decode_cb = |
| 2802 base::ResetAndReturn(&pending_audio_decode_cb_); |
| 2803 |
| 2804 const media::Decryptor::AudioBuffers empty_frames; |
| 2805 |
| 2806 media::Decryptor::Status status = |
| 2807 PpDecryptResultToMediaDecryptorStatus(block_info->result); |
| 2808 if (status != media::Decryptor::kSuccess) { |
| 2809 audio_decode_cb.Run(status, empty_frames); |
| 2810 return; |
| 2811 } |
| 2812 |
| 2813 media::Decryptor::AudioBuffers audio_frame_list; |
| 2814 if (!DeserializeAudioFrames(audio_frames, &audio_frame_list)) { |
| 2815 NOTREACHED() << "CDM did not serialize the buffer correctly."; |
| 2816 audio_decode_cb.Run(media::Decryptor::kError, empty_frames); |
| 2817 return; |
| 2818 } |
| 2819 |
| 2820 audio_decode_cb.Run(media::Decryptor::kSuccess, audio_frame_list); |
| 2610 } | 2821 } |
| 2611 | 2822 |
| 2612 void PluginInstance::NumberOfFindResultsChanged(PP_Instance instance, | 2823 void PluginInstance::NumberOfFindResultsChanged(PP_Instance instance, |
| 2613 int32_t total, | 2824 int32_t total, |
| 2614 PP_Bool final_result) { | 2825 PP_Bool final_result) { |
| 2615 DCHECK_NE(find_identifier_, -1); | 2826 DCHECK_NE(find_identifier_, -1); |
| 2616 delegate_->NumberOfFindResultsChanged(find_identifier_, total, | 2827 delegate_->NumberOfFindResultsChanged(find_identifier_, total, |
| 2617 PP_ToBool(final_result)); | 2828 PP_ToBool(final_result)); |
| 2618 } | 2829 } |
| 2619 | 2830 |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2989 screen_size_for_fullscreen_ = gfx::Size(); | 3200 screen_size_for_fullscreen_ = gfx::Size(); |
| 2990 WebElement element = container_->element(); | 3201 WebElement element = container_->element(); |
| 2991 element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_); | 3202 element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_); |
| 2992 element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_); | 3203 element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_); |
| 2993 element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_); | 3204 element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_); |
| 2994 element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_); | 3205 element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_); |
| 2995 } | 3206 } |
| 2996 | 3207 |
| 2997 } // namespace ppapi | 3208 } // namespace ppapi |
| 2998 } // namespace webkit | 3209 } // namespace webkit |
| OLD | NEW |