Chromium Code Reviews| 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 bool MakeAudioFrames(PP_Resource audio_frames, | |
|
xhwang
2012/10/19 17:07:33
probably need comments here.
Tom Finegan
2012/10/19 22:53:52
Agreed, but I don't think it needs anything too bi
ddorwin
2012/10/20 00:14:36
Especially since the out parameter type is "buffer
xhwang
2012/10/21 19:05:06
Done.
xhwang
2012/10/21 19:05:06
Hmm, maybe we should rename media::Decryptor::Audi
ddorwin
2012/10/22 17:47:11
SGTM (in another CL).
| |
| 398 media::Decryptor::AudioBuffers* frames) { | |
| 399 DCHECK(frames); | |
| 400 EnterResourceNoLock<PPB_Buffer_API> enter(audio_frames, true); | |
| 401 if (!enter.succeeded()) | |
| 402 return false; | |
| 403 | |
| 404 BufferAutoMapper mapper(enter.object()); | |
| 405 if (!mapper.data() || !mapper.size()) | |
| 406 return false; | |
| 407 | |
| 408 const uint8* cur = static_cast<uint8*>(mapper.data()); | |
| 409 int bytes_left = mapper.size(); | |
| 410 | |
| 411 do { | |
| 412 if (bytes_left < 16) | |
|
ddorwin
2012/10/20 00:14:36
why?
16 is a magic number here and below. 8 too. s
xhwang
2012/10/21 19:05:06
Done.
| |
| 413 return false; | |
| 414 | |
| 415 int64 timestamp = *(reinterpret_cast<const int64*>(cur)); | |
| 416 cur += 8; | |
| 417 int64 frame_size = *(reinterpret_cast<const int64*>(cur)); | |
| 418 cur += 8; | |
| 419 bytes_left -= 16; | |
|
ddorwin
2012/10/20 00:14:36
(8 + 8) would be clearer, esp. when using sizeof()
xhwang
2012/10/21 19:05:06
Done.
| |
| 420 | |
| 421 if (frame_size < 0 || bytes_left < frame_size) | |
|
ddorwin
2012/10/20 00:14:36
DCHECK? Is this a bug if we see it?
xhwang
2012/10/21 19:05:06
As I said, I don't trust CDMs. The renderer should
ddorwin
2012/10/22 17:47:11
A DCHECK just tells us something is wrong in a deb
| |
| 422 return false; | |
| 423 | |
| 424 scoped_refptr<media::DataBuffer> frame(new media::DataBuffer(frame_size)); | |
| 425 if (frame_size > 0) { | |
| 426 memcpy(frame->GetWritableData(), cur, frame_size); | |
| 427 frame->SetTimestamp(base::TimeDelta::FromMicroseconds(timestamp)); | |
| 428 cur += frame_size; | |
| 429 bytes_left -= frame_size; | |
| 430 } | |
| 431 frames->push_back(frame); | |
| 432 } | |
| 433 while (bytes_left > 0); | |
|
Tom Finegan
2012/10/19 22:53:52
Move the while up on the same line with the closin
xhwang
2012/10/21 19:05:06
Done.
| |
| 434 | |
| 435 return true; | |
| 436 } | |
| 437 | |
| 395 PP_AudioCodec MediaAudioCodecToPpAudioCodec(media::AudioCodec codec) { | 438 PP_AudioCodec MediaAudioCodecToPpAudioCodec(media::AudioCodec codec) { |
| 396 if (codec == media::kCodecVorbis) | 439 if (codec == media::kCodecVorbis) |
| 397 return PP_AUDIOCODEC_VORBIS; | 440 return PP_AUDIOCODEC_VORBIS; |
| 398 | 441 |
| 399 return PP_AUDIOCODEC_UNKNOWN; | 442 return PP_AUDIOCODEC_UNKNOWN; |
| 400 } | 443 } |
| 401 | 444 |
| 402 PP_VideoCodec MediaVideoCodecToPpVideoCodec(media::VideoCodec codec) { | 445 PP_VideoCodec MediaVideoCodecToPpVideoCodec(media::VideoCodec codec) { |
| 403 if (codec == media::kCodecVP8) | 446 if (codec == media::kCodecVP8) |
| 404 return PP_VIDEOCODEC_VP8; | 447 return PP_VIDEOCODEC_VP8; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 493 text_input_type_(kPluginDefaultTextInputType), | 536 text_input_type_(kPluginDefaultTextInputType), |
| 494 text_input_caret_(0, 0, 0, 0), | 537 text_input_caret_(0, 0, 0, 0), |
| 495 text_input_caret_bounds_(0, 0, 0, 0), | 538 text_input_caret_bounds_(0, 0, 0, 0), |
| 496 text_input_caret_set_(false), | 539 text_input_caret_set_(false), |
| 497 selection_caret_(0), | 540 selection_caret_(0), |
| 498 selection_anchor_(0), | 541 selection_anchor_(0), |
| 499 pending_user_gesture_(0.0), | 542 pending_user_gesture_(0.0), |
| 500 flash_impl_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 543 flash_impl_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 501 decryptor_client_(NULL), | 544 decryptor_client_(NULL), |
| 502 next_decryption_request_id_(1), | 545 next_decryption_request_id_(1), |
| 546 pending_audio_decrypt_request_id_(0), | |
| 547 pending_video_decrypt_request_id_(0), | |
| 503 pending_audio_decoder_init_request_id_(0), | 548 pending_audio_decoder_init_request_id_(0), |
| 504 pending_video_decoder_init_request_id_(0), | 549 pending_video_decoder_init_request_id_(0), |
| 550 pending_audio_decode_request_id_(0), | |
| 505 pending_video_decode_request_id_(0) { | 551 pending_video_decode_request_id_(0) { |
| 506 pp_instance_ = HostGlobals::Get()->AddInstance(this); | 552 pp_instance_ = HostGlobals::Get()->AddInstance(this); |
| 507 | 553 |
| 508 memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); | 554 memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); |
| 509 DCHECK(delegate); | 555 DCHECK(delegate); |
| 510 module_->InstanceCreated(this); | 556 module_->InstanceCreated(this); |
| 511 delegate_->InstanceCreated(this); | 557 delegate_->InstanceCreated(this); |
| 512 message_channel_.reset(new MessageChannel(this)); | 558 message_channel_.reset(new MessageChannel(this)); |
| 513 | 559 |
| 514 view_data_.is_page_visible = delegate->IsPageVisible(); | 560 view_data_.is_page_visible = delegate->IsPageVisible(); |
| (...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1501 PP_PrivatePageTransformType transform_type = | 1547 PP_PrivatePageTransformType transform_type = |
| 1502 type == WebPlugin::RotationType90Clockwise ? | 1548 type == WebPlugin::RotationType90Clockwise ? |
| 1503 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CW : | 1549 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CW : |
| 1504 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CCW; | 1550 PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CCW; |
| 1505 plugin_pdf_interface_->Transform(pp_instance(), transform_type); | 1551 plugin_pdf_interface_->Transform(pp_instance(), transform_type); |
| 1506 // NOTE: plugin instance may have been deleted. | 1552 // NOTE: plugin instance may have been deleted. |
| 1507 } | 1553 } |
| 1508 | 1554 |
| 1509 void PluginInstance::set_decrypt_client( | 1555 void PluginInstance::set_decrypt_client( |
| 1510 media::DecryptorClient* decryptor_client) { | 1556 media::DecryptorClient* decryptor_client) { |
| 1511 DCHECK(decryptor_client); | |
| 1512 decryptor_client_ = decryptor_client; | 1557 decryptor_client_ = decryptor_client; |
| 1513 } | 1558 } |
| 1514 | 1559 |
| 1515 bool PluginInstance::GenerateKeyRequest(const std::string& key_system, | 1560 bool PluginInstance::GenerateKeyRequest(const std::string& key_system, |
| 1516 const std::string& init_data) { | 1561 const std::string& init_data) { |
| 1517 if (!LoadContentDecryptorInterface()) | 1562 if (!LoadContentDecryptorInterface()) |
| 1518 return false; | 1563 return false; |
| 1519 if (key_system.empty()) | 1564 if (key_system.empty()) |
| 1520 return false; | 1565 return false; |
| 1521 | 1566 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1553 | 1598 |
| 1554 bool PluginInstance::CancelKeyRequest(const std::string& session_id) { | 1599 bool PluginInstance::CancelKeyRequest(const std::string& session_id) { |
| 1555 if (!LoadContentDecryptorInterface()) | 1600 if (!LoadContentDecryptorInterface()) |
| 1556 return false; | 1601 return false; |
| 1557 plugin_decryption_interface_->CancelKeyRequest( | 1602 plugin_decryption_interface_->CancelKeyRequest( |
| 1558 pp_instance(), | 1603 pp_instance(), |
| 1559 StringVar::StringToPPVar(session_id)); | 1604 StringVar::StringToPPVar(session_id)); |
| 1560 return true; | 1605 return true; |
| 1561 } | 1606 } |
| 1562 | 1607 |
| 1608 // TODO(xhwang): Remove duplication of code in Decrypt(), | |
| 1609 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). | |
|
Tom Finegan
2012/10/19 22:53:52
We should do this when we refactor and add the del
xhwang
2012/10/21 19:05:06
Agreed.
| |
| 1563 bool PluginInstance::Decrypt( | 1610 bool PluginInstance::Decrypt( |
| 1611 media::Decryptor::StreamType stream_type, | |
| 1564 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 1612 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
| 1565 const media::Decryptor::DecryptCB& decrypt_cb) { | 1613 const media::Decryptor::DecryptCB& decrypt_cb) { |
| 1566 DVLOG(3) << "Decrypt()"; | 1614 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; |
| 1567 if (!LoadContentDecryptorInterface()) | 1615 if (!LoadContentDecryptorInterface()) |
| 1568 return false; | 1616 return false; |
| 1569 | 1617 |
| 1570 ScopedPPResource encrypted_resource( | 1618 ScopedPPResource encrypted_resource( |
| 1571 ScopedPPResource::PassRef(), | 1619 ScopedPPResource::PassRef(), |
| 1572 MakeBufferResource(pp_instance(), | 1620 MakeBufferResource(pp_instance(), |
| 1573 encrypted_buffer->GetData(), | 1621 encrypted_buffer->GetData(), |
| 1574 encrypted_buffer->GetDataSize())); | 1622 encrypted_buffer->GetDataSize())); |
| 1575 if (!encrypted_resource.get()) | 1623 if (!encrypted_resource.get()) |
| 1576 return false; | 1624 return false; |
| 1577 | 1625 |
| 1578 const uint32_t request_id = next_decryption_request_id_++; | 1626 const uint32_t request_id = next_decryption_request_id_++; |
| 1579 DVLOG(2) << "Decrypt() - request_id " << request_id; | 1627 DVLOG(2) << "Decrypt() - request_id " << request_id; |
| 1580 | 1628 |
| 1581 PP_EncryptedBlockInfo block_info; | 1629 PP_EncryptedBlockInfo block_info; |
| 1582 DCHECK(encrypted_buffer->GetDecryptConfig()); | 1630 DCHECK(encrypted_buffer->GetDecryptConfig()); |
| 1583 if (!MakeEncryptedBlockInfo(encrypted_buffer->GetDecryptConfig(), | 1631 if (!MakeEncryptedBlockInfo(encrypted_buffer->GetDecryptConfig(), |
| 1584 encrypted_buffer->GetTimestamp().InMicroseconds(), | 1632 encrypted_buffer->GetTimestamp().InMicroseconds(), |
| 1585 request_id, | 1633 request_id, |
| 1586 &block_info)) { | 1634 &block_info)) { |
| 1587 return false; | 1635 return false; |
| 1588 } | 1636 } |
| 1589 | 1637 |
| 1590 DCHECK(!ContainsKey(pending_decryption_cbs_, request_id)); | 1638 uint32_t& pending_decrypt_request_id = |
|
ddorwin
2012/10/20 00:14:36
DCHECK stream_type,
Would a switch statement be eq
xhwang
2012/10/21 19:05:06
Done.
| |
| 1591 pending_decryption_cbs_.insert(std::make_pair(request_id, decrypt_cb)); | 1639 (stream_type == media::Decryptor::kAudio) ? |
| 1640 pending_audio_decrypt_request_id_ : pending_video_decrypt_request_id_; | |
| 1641 media::Decryptor::DecryptCB& pending_decrypt_cb = | |
| 1642 (stream_type == media::Decryptor::kAudio) ? | |
| 1643 pending_audio_decrypt_cb_ : pending_video_decrypt_cb_; | |
| 1644 | |
| 1645 // There is only one pending decrypt request at any time per stream. This is | |
| 1646 // enforced by the media pipeline. | |
| 1647 DCHECK_EQ(pending_decrypt_request_id, 0u); | |
| 1648 DCHECK(pending_decrypt_cb.is_null()); | |
| 1649 pending_decrypt_request_id = request_id; | |
| 1650 pending_decrypt_cb = decrypt_cb; | |
| 1592 | 1651 |
| 1593 plugin_decryption_interface_->Decrypt(pp_instance(), | 1652 plugin_decryption_interface_->Decrypt(pp_instance(), |
| 1594 encrypted_resource, | 1653 encrypted_resource, |
| 1595 &block_info); | 1654 &block_info); |
| 1596 return true; | 1655 return true; |
| 1597 } | 1656 } |
| 1598 | 1657 |
| 1658 bool PluginInstance::CancelDecrypt(media::Decryptor::StreamType stream_type) { | |
|
ddorwin
2012/10/20 00:14:36
Is it easy for the client to know whether to call
xhwang
2012/10/21 19:05:06
I agree it's confusing.
For decoder, we have Rese
| |
| 1659 DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type; | |
| 1660 | |
| 1661 media::Decryptor::DecryptCB decrypt_cb; | |
| 1662 switch (stream_type) { | |
| 1663 case media::Decryptor::kAudio: | |
| 1664 pending_audio_decrypt_request_id_ = 0; | |
| 1665 decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_); | |
|
ddorwin
2012/10/20 00:14:36
Does this work if pending_audio_decrypt_cb_ is nul
xhwang
2012/10/21 19:05:06
Yes. Line 1676 checks this condition.
| |
| 1666 break; | |
| 1667 case media::Decryptor::kVideo: | |
| 1668 pending_video_decrypt_request_id_ = 0; | |
| 1669 decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_); | |
| 1670 break; | |
| 1671 default: | |
| 1672 NOTREACHED(); | |
| 1673 return false; | |
| 1674 } | |
| 1675 | |
| 1676 if (!decrypt_cb.is_null()) | |
| 1677 decrypt_cb.Run(media::Decryptor::kSuccess, NULL); | |
| 1678 | |
| 1679 return true; | |
| 1680 } | |
| 1681 | |
| 1599 bool PluginInstance::InitializeAudioDecoder( | 1682 bool PluginInstance::InitializeAudioDecoder( |
| 1600 const media::AudioDecoderConfig& decoder_config, | 1683 const media::AudioDecoderConfig& decoder_config, |
| 1601 const media::Decryptor::DecoderInitCB& init_cb) { | 1684 const media::Decryptor::DecoderInitCB& init_cb) { |
| 1602 PP_AudioDecoderConfig pp_decoder_config; | 1685 PP_AudioDecoderConfig pp_decoder_config; |
| 1603 pp_decoder_config.channel_count = | 1686 pp_decoder_config.channel_count = |
| 1604 media::ChannelLayoutToChannelCount(decoder_config.channel_layout()); | 1687 media::ChannelLayoutToChannelCount(decoder_config.channel_layout()); |
| 1605 pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel(); | 1688 pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel(); |
| 1606 pp_decoder_config.samples_per_second = decoder_config.samples_per_second(); | 1689 pp_decoder_config.samples_per_second = decoder_config.samples_per_second(); |
| 1607 pp_decoder_config.request_id = next_decryption_request_id_++; | 1690 pp_decoder_config.request_id = next_decryption_request_id_++; |
| 1608 | 1691 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1647 DCHECK(pending_video_decoder_init_cb_.is_null()); | 1730 DCHECK(pending_video_decoder_init_cb_.is_null()); |
| 1648 pending_video_decoder_init_request_id_ = pp_decoder_config.request_id; | 1731 pending_video_decoder_init_request_id_ = pp_decoder_config.request_id; |
| 1649 pending_video_decoder_init_cb_ = init_cb; | 1732 pending_video_decoder_init_cb_ = init_cb; |
| 1650 | 1733 |
| 1651 plugin_decryption_interface_->InitializeVideoDecoder(pp_instance(), | 1734 plugin_decryption_interface_->InitializeVideoDecoder(pp_instance(), |
| 1652 &pp_decoder_config, | 1735 &pp_decoder_config, |
| 1653 extra_data_resource); | 1736 extra_data_resource); |
| 1654 return true; | 1737 return true; |
| 1655 } | 1738 } |
| 1656 | 1739 |
| 1657 bool PluginInstance::DeinitializeDecoder() { | 1740 void PluginInstance::CancelDecode(media::Decryptor::StreamType stream_type) { |
| 1741 switch (stream_type) { | |
| 1742 case media::Decryptor::kAudio: | |
| 1743 pending_audio_decode_request_id_ = 0; | |
| 1744 if (!pending_audio_decode_cb_.is_null()) | |
| 1745 base::ResetAndReturn(&pending_audio_decode_cb_).Run( | |
| 1746 media::Decryptor::kSuccess, media::Decryptor::AudioBuffers()); | |
|
ddorwin
2012/10/20 00:14:36
odd that video passes NULL but this doesn't. I ass
xhwang
2012/10/21 19:05:06
VideoDecodeCB takes scoped_refptr<VideoFrame>, so
| |
| 1747 break; | |
| 1748 case media::Decryptor::kVideo: | |
| 1749 pending_video_decode_request_id_ = 0; | |
| 1750 if (!pending_video_decode_cb_.is_null()) | |
| 1751 base::ResetAndReturn(&pending_video_decode_cb_).Run( | |
| 1752 media::Decryptor::kSuccess, NULL); | |
| 1753 break; | |
| 1754 default: | |
| 1755 NOTREACHED(); | |
| 1756 } | |
| 1757 } | |
| 1758 | |
| 1759 bool PluginInstance::DeinitializeDecoder( | |
| 1760 media::Decryptor::StreamType stream_type) { | |
| 1658 if (!LoadContentDecryptorInterface()) | 1761 if (!LoadContentDecryptorInterface()) |
| 1659 return false; | 1762 return false; |
| 1660 | 1763 |
| 1764 CancelDecode(stream_type); | |
| 1765 | |
| 1661 // TODO(tomfinegan): Add decoder deinitialize request tracking, and get | 1766 // TODO(tomfinegan): Add decoder deinitialize request tracking, and get |
| 1662 // stream type from media stack. | 1767 // stream type from media stack. |
| 1663 plugin_decryption_interface_->DeinitializeDecoder( | 1768 plugin_decryption_interface_->DeinitializeDecoder( |
| 1664 pp_instance(), | 1769 pp_instance(), |
| 1665 PP_DECRYPTORSTREAMTYPE_VIDEO, | 1770 PP_DECRYPTORSTREAMTYPE_VIDEO, |
| 1666 0); | 1771 0); |
| 1667 return true; | 1772 return true; |
| 1668 } | 1773 } |
| 1669 | 1774 |
| 1670 bool PluginInstance::ResetDecoder() { | 1775 bool PluginInstance::ResetDecoder(media::Decryptor::StreamType stream_type) { |
|
ddorwin
2012/10/20 00:14:36
Does just a Reset() for decrypt & D&D make sense?
xhwang
2012/10/21 19:05:06
We can discuss about this. See above comment.
| |
| 1671 if (!LoadContentDecryptorInterface()) | 1776 if (!LoadContentDecryptorInterface()) |
| 1672 return false; | 1777 return false; |
| 1673 | 1778 |
| 1779 CancelDecode(stream_type); | |
| 1780 | |
| 1674 // TODO(tomfinegan): Add decoder reset request tracking, and get | 1781 // TODO(tomfinegan): Add decoder reset request tracking, and get |
| 1675 // stream type from media stack. | 1782 // stream type from media stack. |
| 1676 plugin_decryption_interface_->ResetDecoder(pp_instance(), | 1783 plugin_decryption_interface_->ResetDecoder(pp_instance(), |
| 1677 PP_DECRYPTORSTREAMTYPE_VIDEO, | 1784 PP_DECRYPTORSTREAMTYPE_VIDEO, |
| 1678 0); | 1785 0); |
| 1679 return true; | 1786 return true; |
| 1680 } | 1787 } |
| 1681 | 1788 |
| 1682 bool PluginInstance::DecryptAndDecode( | 1789 bool PluginInstance::DecryptAndDecodeAudio( |
| 1790 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | |
| 1791 const media::Decryptor::AudioDecodeCB& audio_decode_cb) { | |
| 1792 if (!LoadContentDecryptorInterface()) | |
| 1793 return false; | |
| 1794 | |
| 1795 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize() | |
| 1796 // return NULL and 0 respectively. In that case, we'll just create a 0 | |
| 1797 // resource. | |
| 1798 ScopedPPResource encrypted_resource( | |
| 1799 ScopedPPResource::PassRef(), | |
| 1800 MakeBufferResource(pp_instance(), | |
| 1801 encrypted_buffer->GetData(), | |
| 1802 encrypted_buffer->GetDataSize())); | |
| 1803 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) | |
| 1804 return false; | |
| 1805 | |
| 1806 const uint32_t request_id = next_decryption_request_id_++; | |
| 1807 DVLOG(2) << "DecryptAndDecode() - request_id " << request_id; | |
|
Tom Finegan
2012/10/19 22:53:52
s/DecryptAndDecode/DecryptAndDecodeAudio/
(Here a
xhwang
2012/10/21 19:05:06
Done.
| |
| 1808 | |
| 1809 PP_EncryptedBlockInfo block_info; | |
| 1810 if (!MakeEncryptedBlockInfo( | |
| 1811 encrypted_buffer->GetDecryptConfig(), | |
| 1812 encrypted_buffer->GetTimestamp().InMicroseconds(), | |
| 1813 request_id, | |
| 1814 &block_info)) { | |
| 1815 return false; | |
| 1816 } | |
| 1817 | |
| 1818 // There is only one pending audio decode request at any time. This is | |
| 1819 // enforced by the media pipeline. | |
| 1820 DCHECK_EQ(pending_audio_decode_request_id_, 0u); | |
| 1821 DCHECK(pending_audio_decode_cb_.is_null()); | |
| 1822 pending_audio_decode_request_id_ = request_id; | |
| 1823 pending_audio_decode_cb_ = audio_decode_cb; | |
| 1824 | |
| 1825 plugin_decryption_interface_->DecryptAndDecode(pp_instance(), | |
| 1826 PP_DECRYPTORSTREAMTYPE_AUDIO, | |
| 1827 encrypted_resource, | |
| 1828 &block_info); | |
| 1829 return true; | |
| 1830 } | |
| 1831 | |
| 1832 bool PluginInstance::DecryptAndDecodeVideo( | |
| 1683 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 1833 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
| 1684 const media::Decryptor::VideoDecodeCB& video_decode_cb) { | 1834 const media::Decryptor::VideoDecodeCB& video_decode_cb) { |
| 1685 if (!LoadContentDecryptorInterface()) | 1835 if (!LoadContentDecryptorInterface()) |
| 1686 return false; | 1836 return false; |
| 1687 | 1837 |
| 1688 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize() | 1838 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize() |
| 1689 // return NULL and 0 respectively. In that case, we'll just create a 0 | 1839 // return NULL and 0 respectively. In that case, we'll just create a 0 |
| 1690 // resource. | 1840 // resource. |
| 1691 ScopedPPResource encrypted_resource( | 1841 ScopedPPResource encrypted_resource( |
| 1692 ScopedPPResource::PassRef(), | 1842 ScopedPPResource::PassRef(), |
| (...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2341 void PluginInstance::NeedKey(PP_Instance instance, | 2491 void PluginInstance::NeedKey(PP_Instance instance, |
| 2342 PP_Var key_system_var, | 2492 PP_Var key_system_var, |
| 2343 PP_Var session_id_var, | 2493 PP_Var session_id_var, |
| 2344 PP_Var init_data_var) { | 2494 PP_Var init_data_var) { |
| 2345 // TODO(tomfinegan): send the data to media stack. | 2495 // TODO(tomfinegan): send the data to media stack. |
| 2346 } | 2496 } |
| 2347 | 2497 |
| 2348 void PluginInstance::KeyAdded(PP_Instance instance, | 2498 void PluginInstance::KeyAdded(PP_Instance instance, |
| 2349 PP_Var key_system_var, | 2499 PP_Var key_system_var, |
| 2350 PP_Var session_id_var) { | 2500 PP_Var session_id_var) { |
| 2501 if (!decryptor_client_) | |
| 2502 return; | |
| 2503 | |
| 2351 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); | 2504 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); |
| 2352 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); | 2505 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); |
| 2353 if (!key_system_string || !session_id_string) { | 2506 if (!key_system_string || !session_id_string) { |
| 2354 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); | 2507 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); |
| 2355 return; | 2508 return; |
| 2356 } | 2509 } |
| 2357 | 2510 |
| 2358 DCHECK(decryptor_client_); | |
| 2359 decryptor_client_->KeyAdded(key_system_string->value(), | 2511 decryptor_client_->KeyAdded(key_system_string->value(), |
| 2360 session_id_string->value()); | 2512 session_id_string->value()); |
| 2361 } | 2513 } |
| 2362 | 2514 |
| 2363 void PluginInstance::KeyMessage(PP_Instance instance, | 2515 void PluginInstance::KeyMessage(PP_Instance instance, |
| 2364 PP_Var key_system_var, | 2516 PP_Var key_system_var, |
| 2365 PP_Var session_id_var, | 2517 PP_Var session_id_var, |
| 2366 PP_Resource message_resource, | 2518 PP_Resource message_resource, |
| 2367 PP_Var default_url_var) { | 2519 PP_Var default_url_var) { |
| 2520 if (!decryptor_client_) | |
| 2521 return; | |
| 2522 | |
| 2368 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); | 2523 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); |
| 2369 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); | 2524 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); |
| 2370 StringVar* default_url_string = StringVar::FromPPVar(default_url_var); | 2525 StringVar* default_url_string = StringVar::FromPPVar(default_url_var); |
| 2371 | 2526 |
| 2372 if (!key_system_string || !session_id_string || !default_url_string) { | 2527 if (!key_system_string || !session_id_string || !default_url_string) { |
| 2373 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); | 2528 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); |
| 2374 return; | 2529 return; |
| 2375 } | 2530 } |
| 2376 | 2531 |
| 2377 EnterResourceNoLock<PPB_Buffer_API> enter(message_resource, true); | 2532 EnterResourceNoLock<PPB_Buffer_API> enter(message_resource, true); |
| 2378 if (!enter.succeeded()) { | 2533 if (!enter.succeeded()) { |
| 2379 decryptor_client_->KeyError(key_system_string->value(), | 2534 decryptor_client_->KeyError(key_system_string->value(), |
| 2380 session_id_string->value(), | 2535 session_id_string->value(), |
| 2381 media::Decryptor::kUnknownError, | 2536 media::Decryptor::kUnknownError, |
| 2382 0); | 2537 0); |
| 2383 return; | 2538 return; |
| 2384 } | 2539 } |
| 2385 | 2540 |
| 2386 BufferAutoMapper mapper(enter.object()); | 2541 BufferAutoMapper mapper(enter.object()); |
| 2387 scoped_array<uint8> message_array(new uint8[mapper.size()]); | 2542 scoped_array<uint8> message_array(new uint8[mapper.size()]); |
| 2388 if (mapper.data() && mapper.size()) | 2543 if (mapper.data() && mapper.size()) |
| 2389 memcpy(message_array.get(), mapper.data(), mapper.size()); | 2544 memcpy(message_array.get(), mapper.data(), mapper.size()); |
| 2390 | 2545 |
| 2391 DCHECK(decryptor_client_); | |
| 2392 decryptor_client_->KeyMessage(key_system_string->value(), | 2546 decryptor_client_->KeyMessage(key_system_string->value(), |
| 2393 session_id_string->value(), | 2547 session_id_string->value(), |
| 2394 message_array.Pass(), | 2548 message_array.Pass(), |
| 2395 mapper.size(), | 2549 mapper.size(), |
| 2396 default_url_string->value()); | 2550 default_url_string->value()); |
| 2397 } | 2551 } |
| 2398 | 2552 |
| 2399 void PluginInstance::KeyError(PP_Instance instance, | 2553 void PluginInstance::KeyError(PP_Instance instance, |
| 2400 PP_Var key_system_var, | 2554 PP_Var key_system_var, |
| 2401 PP_Var session_id_var, | 2555 PP_Var session_id_var, |
| 2402 int32_t media_error, | 2556 int32_t media_error, |
| 2403 int32_t system_code) { | 2557 int32_t system_code) { |
| 2558 if (!decryptor_client_) | |
| 2559 return; | |
| 2560 | |
| 2404 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); | 2561 StringVar* key_system_string = StringVar::FromPPVar(key_system_var); |
| 2405 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); | 2562 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); |
| 2406 if (!key_system_string || !session_id_string) { | 2563 if (!key_system_string || !session_id_string) { |
| 2407 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); | 2564 decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0); |
| 2408 return; | 2565 return; |
| 2409 } | 2566 } |
| 2410 | 2567 |
| 2411 DCHECK(decryptor_client_); | |
| 2412 decryptor_client_->KeyError( | 2568 decryptor_client_->KeyError( |
| 2413 key_system_string->value(), | 2569 key_system_string->value(), |
| 2414 session_id_string->value(), | 2570 session_id_string->value(), |
| 2415 static_cast<media::Decryptor::KeyError>(media_error), | 2571 static_cast<media::Decryptor::KeyError>(media_error), |
| 2416 system_code); | 2572 system_code); |
| 2417 } | 2573 } |
| 2418 | 2574 |
| 2419 void PluginInstance::DecoderInitializeDone(PP_Instance instance, | 2575 void PluginInstance::DecoderInitializeDone(PP_Instance instance, |
| 2420 PP_DecryptorStreamType decoder_type, | 2576 PP_DecryptorStreamType decoder_type, |
| 2421 uint32_t request_id, | 2577 uint32_t request_id, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2455 uint32_t request_id) { | 2611 uint32_t request_id) { |
| 2456 // TODO(tomfinegan): Add decoder reset completion handling. | 2612 // TODO(tomfinegan): Add decoder reset completion handling. |
| 2457 } | 2613 } |
| 2458 | 2614 |
| 2459 void PluginInstance::DeliverBlock(PP_Instance instance, | 2615 void PluginInstance::DeliverBlock(PP_Instance instance, |
| 2460 PP_Resource decrypted_block, | 2616 PP_Resource decrypted_block, |
| 2461 const PP_DecryptedBlockInfo* block_info) { | 2617 const PP_DecryptedBlockInfo* block_info) { |
| 2462 DVLOG(2) << "DeliverBlock() - request_id: " | 2618 DVLOG(2) << "DeliverBlock() - request_id: " |
| 2463 << block_info->tracking_info.request_id; | 2619 << block_info->tracking_info.request_id; |
| 2464 DCHECK(block_info); | 2620 DCHECK(block_info); |
| 2465 DecryptionCBMap::iterator found = pending_decryption_cbs_.find( | 2621 |
| 2466 block_info->tracking_info.request_id); | 2622 // If the request ID is not valid or does not match what's saved, do nothing. |
| 2467 if (found == pending_decryption_cbs_.end()) | 2623 const uint32_t request_id = block_info->tracking_info.request_id; |
| 2624 if (request_id == 0) | |
| 2468 return; | 2625 return; |
| 2469 media::Decryptor::DecryptCB decrypt_cb = found->second; | 2626 |
| 2470 pending_decryption_cbs_.erase(found); | 2627 media::Decryptor::DecryptCB decrypt_cb; |
| 2628 if (request_id == pending_audio_decrypt_request_id_) { | |
| 2629 DCHECK(!pending_audio_decrypt_cb_.is_null()); | |
| 2630 pending_audio_decrypt_request_id_ = 0; | |
| 2631 decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_); | |
| 2632 } else if (request_id == pending_video_decrypt_request_id_) { | |
| 2633 DCHECK(!pending_video_decrypt_cb_.is_null()); | |
| 2634 pending_video_decrypt_request_id_ = 0; | |
| 2635 decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_); | |
| 2636 } else { | |
| 2637 DVLOG(1) << "DeliverBlock() - request_id " | |
| 2638 << block_info->tracking_info.request_id << " no found"; | |
|
ddorwin
2012/10/20 00:14:36
s/no/not/
ddorwin
2012/10/20 00:14:36
you already have request_id local var you can use.
xhwang
2012/10/21 19:05:06
Done.
| |
| 2639 return; | |
| 2640 } | |
| 2471 | 2641 |
| 2472 if (block_info->result == PP_DECRYPTRESULT_DECRYPT_NOKEY) { | 2642 if (block_info->result == PP_DECRYPTRESULT_DECRYPT_NOKEY) { |
| 2473 decrypt_cb.Run(media::Decryptor::kNoKey, NULL); | 2643 decrypt_cb.Run(media::Decryptor::kNoKey, NULL); |
| 2474 return; | 2644 return; |
| 2475 } | 2645 } |
| 2476 | 2646 |
| 2477 if (block_info->result != PP_DECRYPTRESULT_SUCCESS) { | 2647 if (block_info->result != PP_DECRYPTRESULT_SUCCESS) { |
| 2478 decrypt_cb.Run(media::Decryptor::kError, NULL); | 2648 decrypt_cb.Run(media::Decryptor::kError, NULL); |
| 2479 return; | 2649 return; |
| 2480 } | 2650 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2580 decoded_frame.get()); | 2750 decoded_frame.get()); |
| 2581 | 2751 |
| 2582 video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame); | 2752 video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame); |
| 2583 } | 2753 } |
| 2584 | 2754 |
| 2585 void PluginInstance::DeliverSamples(PP_Instance instance, | 2755 void PluginInstance::DeliverSamples(PP_Instance instance, |
| 2586 PP_Resource audio_frames, | 2756 PP_Resource audio_frames, |
| 2587 const PP_DecryptedBlockInfo* block_info) { | 2757 const PP_DecryptedBlockInfo* block_info) { |
| 2588 DVLOG(2) << "DeliverSamples() - request_id: " | 2758 DVLOG(2) << "DeliverSamples() - request_id: " |
| 2589 << block_info->tracking_info.request_id; | 2759 << block_info->tracking_info.request_id; |
| 2590 // TODO(tomfinegan): To be implemented after completion of v0.1 of the | 2760 DCHECK(audio_frames); |
|
ddorwin
2012/10/20 00:14:36
decrypted_block can be null above but this can't?
xhwang
2012/10/21 19:05:06
Done.
| |
| 2591 // EME/CDM work. | 2761 |
| 2762 // If the request ID is not valid or does not match what's saved, do nothing. | |
| 2763 if (block_info->tracking_info.request_id == 0 || | |
| 2764 block_info->tracking_info.request_id != | |
| 2765 pending_audio_decode_request_id_) { | |
| 2766 DCHECK(pending_audio_decode_cb_.is_null()); | |
| 2767 return; | |
| 2768 } | |
| 2769 | |
| 2770 DCHECK(!pending_audio_decode_cb_.is_null()); | |
| 2771 pending_audio_decode_request_id_ = 0; | |
| 2772 media::Decryptor::AudioDecodeCB audio_decode_cb = | |
| 2773 base::ResetAndReturn(&pending_audio_decode_cb_); | |
| 2774 | |
| 2775 const media::Decryptor::AudioBuffers empty_frames; | |
| 2776 | |
| 2777 if (block_info->result == PP_DECRYPTRESULT_DECRYPT_NOKEY) { | |
| 2778 audio_decode_cb.Run(media::Decryptor::kNoKey, empty_frames); | |
| 2779 return; | |
| 2780 } | |
| 2781 | |
| 2782 if (block_info->result != PP_DECRYPTRESULT_SUCCESS) { | |
| 2783 audio_decode_cb.Run(media::Decryptor::kError, empty_frames); | |
| 2784 return; | |
| 2785 } | |
| 2786 | |
| 2787 if (audio_frames == 0) { // End-of-stream frame. | |
|
xhwang
2012/10/19 17:07:33
We can remove this check if we all agree that EOS
Tom Finegan
2012/10/19 22:53:52
This isn't necessarily and end of stream frame. Th
xhwang
2012/10/21 19:05:06
Yeah, done in another CL: 11234019
| |
| 2788 audio_decode_cb.Run(media::Decryptor::kSuccess, empty_frames); | |
| 2789 return; | |
| 2790 } | |
| 2791 | |
| 2792 media::Decryptor::AudioBuffers audio_frame_list; | |
| 2793 if (!MakeAudioFrames(audio_frames, &audio_frame_list)) { | |
| 2794 audio_decode_cb.Run(media::Decryptor::kError, empty_frames); | |
| 2795 return; | |
| 2796 } | |
| 2797 | |
| 2798 audio_decode_cb.Run(media::Decryptor::kSuccess, audio_frame_list); | |
| 2592 } | 2799 } |
| 2593 | 2800 |
| 2594 void PluginInstance::NumberOfFindResultsChanged(PP_Instance instance, | 2801 void PluginInstance::NumberOfFindResultsChanged(PP_Instance instance, |
| 2595 int32_t total, | 2802 int32_t total, |
| 2596 PP_Bool final_result) { | 2803 PP_Bool final_result) { |
| 2597 DCHECK_NE(find_identifier_, -1); | 2804 DCHECK_NE(find_identifier_, -1); |
| 2598 delegate_->NumberOfFindResultsChanged(find_identifier_, total, | 2805 delegate_->NumberOfFindResultsChanged(find_identifier_, total, |
| 2599 PP_ToBool(final_result)); | 2806 PP_ToBool(final_result)); |
| 2600 } | 2807 } |
| 2601 | 2808 |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2971 screen_size_for_fullscreen_ = gfx::Size(); | 3178 screen_size_for_fullscreen_ = gfx::Size(); |
| 2972 WebElement element = container_->element(); | 3179 WebElement element = container_->element(); |
| 2973 element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_); | 3180 element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_); |
| 2974 element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_); | 3181 element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_); |
| 2975 element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_); | 3182 element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_); |
| 2976 element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_); | 3183 element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_); |
| 2977 } | 3184 } |
| 2978 | 3185 |
| 2979 } // namespace ppapi | 3186 } // namespace ppapi |
| 2980 } // namespace webkit | 3187 } // namespace webkit |
| OLD | NEW |