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 <cstring> | 5 #include <cstring> | 
| 6 #include <string> | 6 #include <string> | 
| 7 #include <vector> | 7 #include <vector> | 
| 8 | 8 | 
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" | 
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" | 
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 397 } | 397 } | 
| 398 | 398 | 
| 399 void VideoFrameImpl::set_timestamp(int64_t timestamp) { | 399 void VideoFrameImpl::set_timestamp(int64_t timestamp) { | 
| 400 timestamp_ = timestamp; | 400 timestamp_ = timestamp; | 
| 401 } | 401 } | 
| 402 | 402 | 
| 403 int64_t VideoFrameImpl::timestamp() const { | 403 int64_t VideoFrameImpl::timestamp() const { | 
| 404 return timestamp_; | 404 return timestamp_; | 
| 405 } | 405 } | 
| 406 | 406 | 
| 407 class AudioFramesImpl : public cdm::AudioFrames { | |
| 408 public: | |
| 409 AudioFramesImpl() : buffer_(NULL) {} | |
| 410 virtual ~AudioFramesImpl() { | |
| 411 if (buffer_) | |
| 412 buffer_->Destroy(); | |
| 413 } | |
| 414 | |
| 415 // AudioFrames implementation. | |
| 416 virtual void set_buffer(cdm::Buffer* buffer) OVERRIDE { | |
| 417 buffer_ = static_cast<PpbBuffer*>(buffer); | |
| 418 } | |
| 419 virtual cdm::Buffer* buffer() OVERRIDE { | |
| 420 return buffer_; | |
| 421 } | |
| 422 | |
| 423 private: | |
| 424 PpbBuffer* buffer_; | |
| 425 | |
| 426 DISALLOW_COPY_AND_ASSIGN(AudioFramesImpl); | |
| 427 }; | |
| 428 | |
| 407 // A wrapper class for abstracting away PPAPI interaction and threading for a | 429 // A wrapper class for abstracting away PPAPI interaction and threading for a | 
| 408 // Content Decryption Module (CDM). | 430 // Content Decryption Module (CDM). | 
| 409 class CdmWrapper : public pp::Instance, | 431 class CdmWrapper : public pp::Instance, | 
| 410 public pp::ContentDecryptor_Private, | 432 public pp::ContentDecryptor_Private, | 
| 411 public cdm::CdmHost { | 433 public cdm::CdmHost { | 
| 412 public: | 434 public: | 
| 413 CdmWrapper(PP_Instance instance, pp::Module* module); | 435 CdmWrapper(PP_Instance instance, pp::Module* module); | 
| 414 virtual ~CdmWrapper(); | 436 virtual ~CdmWrapper(); | 
| 415 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { | 437 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { | 
| 416 return true; | 438 return true; | 
| (...skipping 27 matching lines...) Expand all Loading... | |
| 444 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; | 466 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; | 
| 445 | 467 | 
| 446 // CdmHost methods. | 468 // CdmHost methods. | 
| 447 virtual void SetTimer(int64 delay_ms) OVERRIDE; | 469 virtual void SetTimer(int64 delay_ms) OVERRIDE; | 
| 448 virtual double GetCurrentWallTimeMs() OVERRIDE; | 470 virtual double GetCurrentWallTimeMs() OVERRIDE; | 
| 449 | 471 | 
| 450 private: | 472 private: | 
| 451 typedef linked_ptr<DecryptedBlockImpl> LinkedDecryptedBlock; | 473 typedef linked_ptr<DecryptedBlockImpl> LinkedDecryptedBlock; | 
| 452 typedef linked_ptr<KeyMessageImpl> LinkedKeyMessage; | 474 typedef linked_ptr<KeyMessageImpl> LinkedKeyMessage; | 
| 453 typedef linked_ptr<VideoFrameImpl> LinkedVideoFrame; | 475 typedef linked_ptr<VideoFrameImpl> LinkedVideoFrame; | 
| 476 typedef linked_ptr<AudioFramesImpl> LinkedAudioFrames; | |
| 454 | 477 | 
| 455 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to | 478 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to | 
| 456 // <code>callback_factory_</code> to ensure that calls into | 479 // <code>callback_factory_</code> to ensure that calls into | 
| 457 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. | 480 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. | 
| 458 void KeyAdded(int32_t result, const std::string& session_id); | 481 void KeyAdded(int32_t result, const std::string& session_id); | 
| 459 void KeyMessage(int32_t result, const LinkedKeyMessage& message); | 482 void KeyMessage(int32_t result, const LinkedKeyMessage& message); | 
| 460 void KeyError(int32_t result, const std::string& session_id); | 483 void KeyError(int32_t result, const std::string& session_id); | 
| 461 void DeliverBlock(int32_t result, | 484 void DeliverBlock(int32_t result, | 
| 462 const cdm::Status& status, | 485 const cdm::Status& status, | 
| 463 const LinkedDecryptedBlock& decrypted_block, | 486 const LinkedDecryptedBlock& decrypted_block, | 
| 464 const PP_DecryptTrackingInfo& tracking_info); | 487 const PP_DecryptTrackingInfo& tracking_info); | 
| 465 void DecoderInitializeDone(int32_t result, | 488 void DecoderInitializeDone(int32_t result, | 
| 466 PP_DecryptorStreamType decoder_type, | 489 PP_DecryptorStreamType decoder_type, | 
| 467 uint32_t request_id, | 490 uint32_t request_id, | 
| 468 bool success); | 491 bool success); | 
| 469 void DecoderDeinitializeDone(int32_t result, | 492 void DecoderDeinitializeDone(int32_t result, | 
| 470 PP_DecryptorStreamType decoder_type, | 493 PP_DecryptorStreamType decoder_type, | 
| 471 uint32_t request_id); | 494 uint32_t request_id); | 
| 472 void DecoderResetDone(int32_t result, | 495 void DecoderResetDone(int32_t result, | 
| 473 PP_DecryptorStreamType decoder_type, | 496 PP_DecryptorStreamType decoder_type, | 
| 474 uint32_t request_id); | 497 uint32_t request_id); | 
| 475 void DeliverFrame(int32_t result, | 498 void DeliverFrame(int32_t result, | 
| 476 const cdm::Status& status, | 499 const cdm::Status& status, | 
| 477 const LinkedVideoFrame& video_frame, | 500 const LinkedVideoFrame& video_frame, | 
| 478 const PP_DecryptTrackingInfo& tracking_info); | 501 const PP_DecryptTrackingInfo& tracking_info); | 
| 502 void DeliverSamples(int32_t result, | |
| 503 const cdm::Status& status, | |
| 504 const LinkedAudioFrames& audio_frames, | |
| 505 const PP_DecryptTrackingInfo& tracking_info); | |
| 479 | 506 | 
| 480 // Helper for SetTimer(). | 507 // Helper for SetTimer(). | 
| 481 void TimerExpired(int32 result); | 508 void TimerExpired(int32 result); | 
| 482 | 509 | 
| 483 PpbBufferAllocator allocator_; | 510 PpbBufferAllocator allocator_; | 
| 484 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; | 511 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; | 
| 485 cdm::ContentDecryptionModule* cdm_; | 512 cdm::ContentDecryptionModule* cdm_; | 
| 486 std::string key_system_; | 513 std::string key_system_; | 
| 487 }; | 514 }; | 
| 488 | 515 | 
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 671 // here. | 698 // here. | 
| 672 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::DecoderResetDone, | 699 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::DecoderResetDone, | 
| 673 decoder_type, | 700 decoder_type, | 
| 674 request_id)); | 701 request_id)); | 
| 675 } | 702 } | 
| 676 | 703 | 
| 677 void CdmWrapper::DecryptAndDecode( | 704 void CdmWrapper::DecryptAndDecode( | 
| 678 PP_DecryptorStreamType decoder_type, | 705 PP_DecryptorStreamType decoder_type, | 
| 679 pp::Buffer_Dev encrypted_buffer, | 706 pp::Buffer_Dev encrypted_buffer, | 
| 680 const PP_EncryptedBlockInfo& encrypted_block_info) { | 707 const PP_EncryptedBlockInfo& encrypted_block_info) { | 
| 681 // TODO(tomfinegan): Remove this check when audio decoding is added. | |
| 682 PP_DCHECK(decoder_type == PP_DECRYPTORSTREAMTYPE_VIDEO); | |
| 683 PP_DCHECK(cdm_); | 708 PP_DCHECK(cdm_); | 
| 684 | 709 | 
| 685 cdm::InputBuffer input_buffer; | 710 cdm::InputBuffer input_buffer; | 
| 686 std::vector<cdm::SubsampleEntry> subsamples; | 711 std::vector<cdm::SubsampleEntry> subsamples; | 
| 687 if (!encrypted_buffer.is_null()) { | 712 if (!encrypted_buffer.is_null()) { | 
| 688 ConfigureInputBuffer(encrypted_buffer, | 713 ConfigureInputBuffer(encrypted_buffer, | 
| 689 encrypted_block_info, | 714 encrypted_block_info, | 
| 690 &subsamples, | 715 &subsamples, | 
| 691 &input_buffer); | 716 &input_buffer); | 
| 692 } | 717 } | 
| 693 | 718 | 
| 694 LinkedVideoFrame video_frame(new VideoFrameImpl()); | 719 cdm::Status status = cdm::kDecodeError; | 
| 695 cdm::Status status = cdm_->DecryptAndDecodeFrame(input_buffer, | 720 switch (decoder_type) { | 
| 696 video_frame.get()); | 721 case PP_DECRYPTORSTREAMTYPE_VIDEO: { | 
| 697 CallOnMain(callback_factory_.NewCallback( | 722 LinkedVideoFrame video_frame(new VideoFrameImpl()); | 
| 698 &CdmWrapper::DeliverFrame, | 723 status = cdm_->DecryptAndDecodeFrame(input_buffer, video_frame.get()); | 
| 699 status, | 724 CallOnMain(callback_factory_.NewCallback( | 
| 700 video_frame, | 725 &CdmWrapper::DeliverFrame, | 
| 701 encrypted_block_info.tracking_info)); | 726 status, | 
| 727 video_frame, | |
| 728 encrypted_block_info.tracking_info)); | |
| 729 return; | |
| 730 } | |
| 731 | |
| 732 case PP_DECRYPTORSTREAMTYPE_AUDIO: { | |
| 733 LinkedAudioFrames audio_frames(new AudioFramesImpl()); | |
| 734 status = cdm_->DecryptAndDecodeSamples(input_buffer, audio_frames.get()); | |
| 735 CallOnMain(callback_factory_.NewCallback( | |
| 736 &CdmWrapper::DeliverSamples, | |
| 737 status, | |
| 738 audio_frames, | |
| 739 encrypted_block_info.tracking_info)); | |
| 740 return; | |
| 741 } | |
| 742 | |
| 743 default: | |
| 744 PP_NOTREACHED(); | |
| 745 return; | |
| 746 } | |
| 702 } | 747 } | 
| 703 | 748 | 
| 704 void CdmWrapper::SetTimer(int64 delay_ms) { | 749 void CdmWrapper::SetTimer(int64 delay_ms) { | 
| 705 // NOTE: doesn't really need to run on the main thread; could just as well run | 750 // NOTE: doesn't really need to run on the main thread; could just as well run | 
| 706 // on a helper thread if |cdm_| were thread-friendly and care was taken. We | 751 // on a helper thread if |cdm_| were thread-friendly and care was taken. We | 
| 707 // only use CallOnMainThread() here to get delayed-execution behavior. | 752 // only use CallOnMainThread() here to get delayed-execution behavior. | 
| 708 pp::Module::Get()->core()->CallOnMainThread( | 753 pp::Module::Get()->core()->CallOnMainThread( | 
| 709 delay_ms, | 754 delay_ms, | 
| 710 callback_factory_.NewCallback(&CdmWrapper::TimerExpired), | 755 callback_factory_.NewCallback(&CdmWrapper::TimerExpired), | 
| 711 PP_OK); | 756 PP_OK); | 
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 868 } | 913 } | 
| 869 | 914 | 
| 870 const pp::Buffer_Dev& buffer = | 915 const pp::Buffer_Dev& buffer = | 
| 871 video_frame.get() && video_frame->frame_buffer() ? | 916 video_frame.get() && video_frame->frame_buffer() ? | 
| 872 static_cast<PpbBuffer*>(video_frame->frame_buffer())->buffer_dev() : | 917 static_cast<PpbBuffer*>(video_frame->frame_buffer())->buffer_dev() : | 
| 873 pp::Buffer_Dev(); | 918 pp::Buffer_Dev(); | 
| 874 | 919 | 
| 875 pp::ContentDecryptor_Private::DeliverFrame(buffer, decrypted_frame_info); | 920 pp::ContentDecryptor_Private::DeliverFrame(buffer, decrypted_frame_info); | 
| 876 } | 921 } | 
| 877 | 922 | 
| 923 void CdmWrapper::DeliverSamples(int32_t result, | |
| 924 const cdm::Status& status, | |
| 925 const LinkedAudioFrames& audio_frames, | |
| 926 const PP_DecryptTrackingInfo& tracking_info) { | |
| 927 PP_DCHECK(result == PP_OK); | |
| 928 // TODO(tomfinegan): Add PP_DecryptedSamplesInfo (or better name) for | |
| 929 // cdm::AudioFrames. | |
| 
 
Tom Finegan
2012/10/23 03:15:27
Why do we need PP_DecryptedSamplesInfo? Does the m
 
xhwang
2012/10/23 03:25:09
We still need the decrypt result and request ID. W
 
 | |
| 930 PP_DecryptedBlockInfo decrypted_block_info; | |
| 931 decrypted_block_info.tracking_info = tracking_info; | |
| 932 // TODO(tomfinegan): Remove this after PP_DecryptedSamplesInfo is added. | |
| 933 decrypted_block_info.tracking_info.timestamp = 0; | |
| 
 
Tom Finegan
2012/10/23 03:15:27
Ditto about PP_DSI, and setting this to 0 will be
 
xhwang
2012/10/23 03:25:09
ditto
 
 | |
| 934 | |
| 935 switch (status) { | |
| 936 case cdm::kSuccess: | |
| 937 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS; | |
| 938 PP_DCHECK(audio_frames.get() && audio_frames->buffer()); | |
| 939 break; | |
| 940 case cdm::kNeedMoreData: | |
| 941 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS; | |
| 942 break; | |
| 943 case cdm::kNoKey: | |
| 944 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY; | |
| 945 break; | |
| 946 case cdm::kDecryptError: | |
| 947 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR; | |
| 948 break; | |
| 949 default: | |
| 950 PP_DCHECK(false); | |
| 951 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR; | |
| 952 } | |
| 953 | |
| 954 const pp::Buffer_Dev& buffer = | |
| 955 audio_frames.get() && audio_frames->buffer() ? | |
| 956 static_cast<PpbBuffer*>(audio_frames->buffer())->buffer_dev() : | |
| 957 pp::Buffer_Dev(); | |
| 958 | |
| 959 pp::ContentDecryptor_Private::DeliverSamples(buffer, decrypted_block_info); | |
| 960 } | |
| 961 | |
| 878 | 962 | 
| 879 // This object is the global object representing this plugin library as long | 963 // This object is the global object representing this plugin library as long | 
| 880 // as it is loaded. | 964 // as it is loaded. | 
| 881 class CdmWrapperModule : public pp::Module { | 965 class CdmWrapperModule : public pp::Module { | 
| 882 public: | 966 public: | 
| 883 CdmWrapperModule() : pp::Module() {} | 967 CdmWrapperModule() : pp::Module() {} | 
| 884 virtual ~CdmWrapperModule() {} | 968 virtual ~CdmWrapperModule() {} | 
| 885 | 969 | 
| 886 virtual pp::Instance* CreateInstance(PP_Instance instance) { | 970 virtual pp::Instance* CreateInstance(PP_Instance instance) { | 
| 887 return new CdmWrapper(instance, this); | 971 return new CdmWrapper(instance, this); | 
| 888 } | 972 } | 
| 889 }; | 973 }; | 
| 890 | 974 | 
| 891 } // namespace webkit_media | 975 } // namespace webkit_media | 
| 892 | 976 | 
| 893 namespace pp { | 977 namespace pp { | 
| 894 | 978 | 
| 895 // Factory function for your specialization of the Module object. | 979 // Factory function for your specialization of the Module object. | 
| 896 Module* CreateModule() { | 980 Module* CreateModule() { | 
| 897 return new webkit_media::CdmWrapperModule(); | 981 return new webkit_media::CdmWrapperModule(); | 
| 898 } | 982 } | 
| 899 | 983 | 
| 900 } // namespace pp | 984 } // namespace pp | 
| OLD | NEW |