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 |