Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: webkit/plugins/ppapi/ppapi_plugin_instance.cc

Issue 11189082: Update PluginInstance for audio support for content decryption. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix tests Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/plugins/ppapi/ppapi_plugin_instance.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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(&current_print_settings_, 0, sizeof(current_print_settings_)); 600 memset(&current_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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « webkit/plugins/ppapi/ppapi_plugin_instance.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698