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 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 } | 434 } |
435 | 435 |
436 void VideoFrameImpl::set_timestamp(int64_t timestamp) { | 436 void VideoFrameImpl::set_timestamp(int64_t timestamp) { |
437 timestamp_ = timestamp; | 437 timestamp_ = timestamp; |
438 } | 438 } |
439 | 439 |
440 int64_t VideoFrameImpl::timestamp() const { | 440 int64_t VideoFrameImpl::timestamp() const { |
441 return timestamp_; | 441 return timestamp_; |
442 } | 442 } |
443 | 443 |
| 444 class AudioFramesImpl : public cdm::AudioFrames { |
| 445 public: |
| 446 AudioFramesImpl() : buffer_(NULL) {} |
| 447 virtual ~AudioFramesImpl() { |
| 448 if (buffer_) |
| 449 buffer_->Destroy(); |
| 450 } |
| 451 |
| 452 // AudioFrames implementation. |
| 453 virtual void set_buffer(cdm::Buffer* buffer) OVERRIDE { |
| 454 buffer_ = static_cast<PpbBuffer*>(buffer); |
| 455 } |
| 456 virtual cdm::Buffer* buffer() OVERRIDE { |
| 457 return buffer_; |
| 458 } |
| 459 |
| 460 private: |
| 461 PpbBuffer* buffer_; |
| 462 |
| 463 DISALLOW_COPY_AND_ASSIGN(AudioFramesImpl); |
| 464 }; |
| 465 |
444 // A wrapper class for abstracting away PPAPI interaction and threading for a | 466 // A wrapper class for abstracting away PPAPI interaction and threading for a |
445 // Content Decryption Module (CDM). | 467 // Content Decryption Module (CDM). |
446 class CdmWrapper : public pp::Instance, | 468 class CdmWrapper : public pp::Instance, |
447 public pp::ContentDecryptor_Private, | 469 public pp::ContentDecryptor_Private, |
448 public cdm::CdmHost { | 470 public cdm::CdmHost { |
449 public: | 471 public: |
450 CdmWrapper(PP_Instance instance, pp::Module* module); | 472 CdmWrapper(PP_Instance instance, pp::Module* module); |
451 virtual ~CdmWrapper(); | 473 virtual ~CdmWrapper(); |
452 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { | 474 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { |
453 return true; | 475 return true; |
(...skipping 27 matching lines...) Expand all Loading... |
481 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; | 503 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; |
482 | 504 |
483 // CdmHost methods. | 505 // CdmHost methods. |
484 virtual void SetTimer(int64 delay_ms) OVERRIDE; | 506 virtual void SetTimer(int64 delay_ms) OVERRIDE; |
485 virtual double GetCurrentWallTimeMs() OVERRIDE; | 507 virtual double GetCurrentWallTimeMs() OVERRIDE; |
486 | 508 |
487 private: | 509 private: |
488 typedef linked_ptr<DecryptedBlockImpl> LinkedDecryptedBlock; | 510 typedef linked_ptr<DecryptedBlockImpl> LinkedDecryptedBlock; |
489 typedef linked_ptr<KeyMessageImpl> LinkedKeyMessage; | 511 typedef linked_ptr<KeyMessageImpl> LinkedKeyMessage; |
490 typedef linked_ptr<VideoFrameImpl> LinkedVideoFrame; | 512 typedef linked_ptr<VideoFrameImpl> LinkedVideoFrame; |
| 513 typedef linked_ptr<AudioFramesImpl> LinkedAudioFrames; |
491 | 514 |
492 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to | 515 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to |
493 // <code>callback_factory_</code> to ensure that calls into | 516 // <code>callback_factory_</code> to ensure that calls into |
494 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. | 517 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. |
495 void KeyAdded(int32_t result, const std::string& session_id); | 518 void KeyAdded(int32_t result, const std::string& session_id); |
496 void KeyMessage(int32_t result, const LinkedKeyMessage& message); | 519 void KeyMessage(int32_t result, const LinkedKeyMessage& message); |
497 void KeyError(int32_t result, const std::string& session_id); | 520 void KeyError(int32_t result, const std::string& session_id); |
498 void DeliverBlock(int32_t result, | 521 void DeliverBlock(int32_t result, |
499 const cdm::Status& status, | 522 const cdm::Status& status, |
500 const LinkedDecryptedBlock& decrypted_block, | 523 const LinkedDecryptedBlock& decrypted_block, |
501 const PP_DecryptTrackingInfo& tracking_info); | 524 const PP_DecryptTrackingInfo& tracking_info); |
502 void DecoderInitializeDone(int32_t result, | 525 void DecoderInitializeDone(int32_t result, |
503 PP_DecryptorStreamType decoder_type, | 526 PP_DecryptorStreamType decoder_type, |
504 uint32_t request_id, | 527 uint32_t request_id, |
505 bool success); | 528 bool success); |
506 void DecoderDeinitializeDone(int32_t result, | 529 void DecoderDeinitializeDone(int32_t result, |
507 PP_DecryptorStreamType decoder_type, | 530 PP_DecryptorStreamType decoder_type, |
508 uint32_t request_id); | 531 uint32_t request_id); |
509 void DecoderResetDone(int32_t result, | 532 void DecoderResetDone(int32_t result, |
510 PP_DecryptorStreamType decoder_type, | 533 PP_DecryptorStreamType decoder_type, |
511 uint32_t request_id); | 534 uint32_t request_id); |
512 void DeliverFrame(int32_t result, | 535 void DeliverFrame(int32_t result, |
513 const cdm::Status& status, | 536 const cdm::Status& status, |
514 const LinkedVideoFrame& video_frame, | 537 const LinkedVideoFrame& video_frame, |
515 const PP_DecryptTrackingInfo& tracking_info); | 538 const PP_DecryptTrackingInfo& tracking_info); |
| 539 void DeliverSamples(int32_t result, |
| 540 const cdm::Status& status, |
| 541 const LinkedAudioFrames& audio_frames, |
| 542 const PP_DecryptTrackingInfo& tracking_info); |
516 | 543 |
517 // Helper for SetTimer(). | 544 // Helper for SetTimer(). |
518 void TimerExpired(int32 result); | 545 void TimerExpired(int32 result); |
519 | 546 |
520 PpbBufferAllocator allocator_; | 547 PpbBufferAllocator allocator_; |
521 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; | 548 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; |
522 cdm::ContentDecryptionModule* cdm_; | 549 cdm::ContentDecryptionModule* cdm_; |
523 std::string key_system_; | 550 std::string key_system_; |
524 }; | 551 }; |
525 | 552 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 cdm_->ResetDecoder(PpDecryptorStreamTypeToCdmStreamType(decoder_type)); | 734 cdm_->ResetDecoder(PpDecryptorStreamTypeToCdmStreamType(decoder_type)); |
708 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::DecoderResetDone, | 735 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::DecoderResetDone, |
709 decoder_type, | 736 decoder_type, |
710 request_id)); | 737 request_id)); |
711 } | 738 } |
712 | 739 |
713 void CdmWrapper::DecryptAndDecode( | 740 void CdmWrapper::DecryptAndDecode( |
714 PP_DecryptorStreamType decoder_type, | 741 PP_DecryptorStreamType decoder_type, |
715 pp::Buffer_Dev encrypted_buffer, | 742 pp::Buffer_Dev encrypted_buffer, |
716 const PP_EncryptedBlockInfo& encrypted_block_info) { | 743 const PP_EncryptedBlockInfo& encrypted_block_info) { |
717 // TODO(tomfinegan): Remove this check when audio decoding is added. | |
718 PP_DCHECK(decoder_type == PP_DECRYPTORSTREAMTYPE_VIDEO); | |
719 PP_DCHECK(cdm_); | 744 PP_DCHECK(cdm_); |
720 | 745 |
721 cdm::InputBuffer input_buffer; | 746 cdm::InputBuffer input_buffer; |
722 std::vector<cdm::SubsampleEntry> subsamples; | 747 std::vector<cdm::SubsampleEntry> subsamples; |
723 if (!encrypted_buffer.is_null()) { | 748 if (!encrypted_buffer.is_null()) { |
724 ConfigureInputBuffer(encrypted_buffer, | 749 ConfigureInputBuffer(encrypted_buffer, |
725 encrypted_block_info, | 750 encrypted_block_info, |
726 &subsamples, | 751 &subsamples, |
727 &input_buffer); | 752 &input_buffer); |
728 } | 753 } |
729 | 754 |
730 LinkedVideoFrame video_frame(new VideoFrameImpl()); | 755 cdm::Status status = cdm::kDecodeError; |
731 cdm::Status status = cdm_->DecryptAndDecodeFrame(input_buffer, | 756 switch (decoder_type) { |
732 video_frame.get()); | 757 case PP_DECRYPTORSTREAMTYPE_VIDEO: { |
733 CallOnMain(callback_factory_.NewCallback( | 758 LinkedVideoFrame video_frame(new VideoFrameImpl()); |
734 &CdmWrapper::DeliverFrame, | 759 status = cdm_->DecryptAndDecodeFrame(input_buffer, video_frame.get()); |
735 status, | 760 CallOnMain(callback_factory_.NewCallback( |
736 video_frame, | 761 &CdmWrapper::DeliverFrame, |
737 encrypted_block_info.tracking_info)); | 762 status, |
| 763 video_frame, |
| 764 encrypted_block_info.tracking_info)); |
| 765 return; |
| 766 } |
| 767 |
| 768 case PP_DECRYPTORSTREAMTYPE_AUDIO: { |
| 769 LinkedAudioFrames audio_frames(new AudioFramesImpl()); |
| 770 status = cdm_->DecryptAndDecodeSamples(input_buffer, audio_frames.get()); |
| 771 CallOnMain(callback_factory_.NewCallback( |
| 772 &CdmWrapper::DeliverSamples, |
| 773 status, |
| 774 audio_frames, |
| 775 encrypted_block_info.tracking_info)); |
| 776 return; |
| 777 } |
| 778 |
| 779 default: |
| 780 PP_NOTREACHED(); |
| 781 return; |
| 782 } |
738 } | 783 } |
739 | 784 |
740 void CdmWrapper::SetTimer(int64 delay_ms) { | 785 void CdmWrapper::SetTimer(int64 delay_ms) { |
741 // NOTE: doesn't really need to run on the main thread; could just as well run | 786 // NOTE: doesn't really need to run on the main thread; could just as well run |
742 // on a helper thread if |cdm_| were thread-friendly and care was taken. We | 787 // on a helper thread if |cdm_| were thread-friendly and care was taken. We |
743 // only use CallOnMainThread() here to get delayed-execution behavior. | 788 // only use CallOnMainThread() here to get delayed-execution behavior. |
744 pp::Module::Get()->core()->CallOnMainThread( | 789 pp::Module::Get()->core()->CallOnMainThread( |
745 delay_ms, | 790 delay_ms, |
746 callback_factory_.NewCallback(&CdmWrapper::TimerExpired), | 791 callback_factory_.NewCallback(&CdmWrapper::TimerExpired), |
747 PP_OK); | 792 PP_OK); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 PP_DecryptedBlockInfo decrypted_block_info; | 846 PP_DecryptedBlockInfo decrypted_block_info; |
802 decrypted_block_info.tracking_info = tracking_info; | 847 decrypted_block_info.tracking_info = tracking_info; |
803 decrypted_block_info.tracking_info.timestamp = decrypted_block->timestamp(); | 848 decrypted_block_info.tracking_info.timestamp = decrypted_block->timestamp(); |
804 decrypted_block_info.result = CdmStatusToPpDecryptResult(status); | 849 decrypted_block_info.result = CdmStatusToPpDecryptResult(status); |
805 | 850 |
806 pp::Buffer_Dev buffer; | 851 pp::Buffer_Dev buffer; |
807 | 852 |
808 if (decrypted_block_info.result == PP_DECRYPTRESULT_SUCCESS) { | 853 if (decrypted_block_info.result == PP_DECRYPTRESULT_SUCCESS) { |
809 PP_DCHECK(decrypted_block.get() && decrypted_block->buffer()); | 854 PP_DCHECK(decrypted_block.get() && decrypted_block->buffer()); |
810 if (!decrypted_block.get() || !decrypted_block->buffer()) { | 855 if (!decrypted_block.get() || !decrypted_block->buffer()) { |
| 856 PP_NOTREACHED(); |
811 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR; | 857 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR; |
812 } else { | 858 } else { |
813 buffer = static_cast<PpbBuffer*>(decrypted_block->buffer())->buffer_dev(); | 859 buffer = static_cast<PpbBuffer*>(decrypted_block->buffer())->buffer_dev(); |
814 } | 860 } |
815 } | 861 } |
816 | 862 |
817 pp::ContentDecryptor_Private::DeliverBlock(buffer, decrypted_block_info); | 863 pp::ContentDecryptor_Private::DeliverBlock(buffer, decrypted_block_info); |
818 } | 864 } |
819 | 865 |
820 void CdmWrapper::DecoderInitializeDone(int32_t result, | 866 void CdmWrapper::DecoderInitializeDone(int32_t result, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
857 PP_DCHECK(video_frame->format() == cdm::kI420 || | 903 PP_DCHECK(video_frame->format() == cdm::kI420 || |
858 video_frame->format() == cdm::kYv12); | 904 video_frame->format() == cdm::kYv12); |
859 | 905 |
860 decrypted_frame_info.format = | 906 decrypted_frame_info.format = |
861 CdmVideoFormatToPpDecryptedFrameFormat(video_frame->format()); | 907 CdmVideoFormatToPpDecryptedFrameFormat(video_frame->format()); |
862 | 908 |
863 if (!video_frame.get() || | 909 if (!video_frame.get() || |
864 !video_frame->frame_buffer() || | 910 !video_frame->frame_buffer() || |
865 (decrypted_frame_info.format != PP_DECRYPTEDFRAMEFORMAT_YV12 && | 911 (decrypted_frame_info.format != PP_DECRYPTEDFRAMEFORMAT_YV12 && |
866 decrypted_frame_info.format != PP_DECRYPTEDFRAMEFORMAT_I420)) { | 912 decrypted_frame_info.format != PP_DECRYPTEDFRAMEFORMAT_I420)) { |
| 913 PP_NOTREACHED(); |
867 decrypted_frame_info.result = PP_DECRYPTRESULT_DECODE_ERROR; | 914 decrypted_frame_info.result = PP_DECRYPTRESULT_DECODE_ERROR; |
868 } else { | 915 } else { |
869 buffer = static_cast<PpbBuffer*>( | 916 buffer = static_cast<PpbBuffer*>( |
870 video_frame->frame_buffer())->buffer_dev(); | 917 video_frame->frame_buffer())->buffer_dev(); |
871 decrypted_frame_info.width = video_frame->size().width; | 918 decrypted_frame_info.width = video_frame->size().width; |
872 decrypted_frame_info.height = video_frame->size().height; | 919 decrypted_frame_info.height = video_frame->size().height; |
873 decrypted_frame_info.plane_offsets[PP_DECRYPTEDFRAMEPLANES_Y] = | 920 decrypted_frame_info.plane_offsets[PP_DECRYPTEDFRAMEPLANES_Y] = |
874 video_frame->plane_offset(cdm::VideoFrame::kYPlane); | 921 video_frame->plane_offset(cdm::VideoFrame::kYPlane); |
875 decrypted_frame_info.plane_offsets[PP_DECRYPTEDFRAMEPLANES_U] = | 922 decrypted_frame_info.plane_offsets[PP_DECRYPTEDFRAMEPLANES_U] = |
876 video_frame->plane_offset(cdm::VideoFrame::kUPlane); | 923 video_frame->plane_offset(cdm::VideoFrame::kUPlane); |
877 decrypted_frame_info.plane_offsets[PP_DECRYPTEDFRAMEPLANES_V] = | 924 decrypted_frame_info.plane_offsets[PP_DECRYPTEDFRAMEPLANES_V] = |
878 video_frame->plane_offset(cdm::VideoFrame::kVPlane); | 925 video_frame->plane_offset(cdm::VideoFrame::kVPlane); |
879 decrypted_frame_info.strides[PP_DECRYPTEDFRAMEPLANES_Y] = | 926 decrypted_frame_info.strides[PP_DECRYPTEDFRAMEPLANES_Y] = |
880 video_frame->stride(cdm::VideoFrame::kYPlane); | 927 video_frame->stride(cdm::VideoFrame::kYPlane); |
881 decrypted_frame_info.strides[PP_DECRYPTEDFRAMEPLANES_U] = | 928 decrypted_frame_info.strides[PP_DECRYPTEDFRAMEPLANES_U] = |
882 video_frame->stride(cdm::VideoFrame::kUPlane); | 929 video_frame->stride(cdm::VideoFrame::kUPlane); |
883 decrypted_frame_info.strides[PP_DECRYPTEDFRAMEPLANES_V] = | 930 decrypted_frame_info.strides[PP_DECRYPTEDFRAMEPLANES_V] = |
884 video_frame->stride(cdm::VideoFrame::kVPlane); | 931 video_frame->stride(cdm::VideoFrame::kVPlane); |
885 } | 932 } |
886 } | 933 } |
887 | 934 |
888 pp::ContentDecryptor_Private::DeliverFrame(buffer, decrypted_frame_info); | 935 pp::ContentDecryptor_Private::DeliverFrame(buffer, decrypted_frame_info); |
889 } | 936 } |
890 | 937 |
| 938 void CdmWrapper::DeliverSamples(int32_t result, |
| 939 const cdm::Status& status, |
| 940 const LinkedAudioFrames& audio_frames, |
| 941 const PP_DecryptTrackingInfo& tracking_info) { |
| 942 PP_DCHECK(result == PP_OK); |
| 943 // TODO(tomfinegan): Add PP_DecryptedSamplesInfo (or better name) for |
| 944 // cdm::AudioFrames. |
| 945 PP_DecryptedBlockInfo decrypted_block_info; |
| 946 decrypted_block_info.tracking_info = tracking_info; |
| 947 // TODO(tomfinegan): Remove this after PP_DecryptedSamplesInfo is added. |
| 948 decrypted_block_info.tracking_info.timestamp = 0; |
| 949 decrypted_block_info.result = CdmStatusToPpDecryptResult(status); |
| 950 |
| 951 pp::Buffer_Dev buffer; |
| 952 |
| 953 if (decrypted_block_info.result == PP_DECRYPTRESULT_SUCCESS) { |
| 954 PP_DCHECK(audio_frames.get() && audio_frames->buffer()); |
| 955 if (!audio_frames.get() || !audio_frames->buffer()) { |
| 956 PP_NOTREACHED(); |
| 957 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR; |
| 958 } else { |
| 959 buffer = static_cast<PpbBuffer*>(audio_frames->buffer())->buffer_dev(); |
| 960 } |
| 961 } |
| 962 |
| 963 pp::ContentDecryptor_Private::DeliverSamples(buffer, decrypted_block_info); |
| 964 } |
891 | 965 |
892 // This object is the global object representing this plugin library as long | 966 // This object is the global object representing this plugin library as long |
893 // as it is loaded. | 967 // as it is loaded. |
894 class CdmWrapperModule : public pp::Module { | 968 class CdmWrapperModule : public pp::Module { |
895 public: | 969 public: |
896 CdmWrapperModule() : pp::Module() {} | 970 CdmWrapperModule() : pp::Module() {} |
897 virtual ~CdmWrapperModule() {} | 971 virtual ~CdmWrapperModule() {} |
898 | 972 |
899 virtual pp::Instance* CreateInstance(PP_Instance instance) { | 973 virtual pp::Instance* CreateInstance(PP_Instance instance) { |
900 return new CdmWrapper(instance, this); | 974 return new CdmWrapper(instance, this); |
901 } | 975 } |
902 }; | 976 }; |
903 | 977 |
904 } // namespace webkit_media | 978 } // namespace webkit_media |
905 | 979 |
906 namespace pp { | 980 namespace pp { |
907 | 981 |
908 // Factory function for your specialization of the Module object. | 982 // Factory function for your specialization of the Module object. |
909 Module* CreateModule() { | 983 Module* CreateModule() { |
910 return new webkit_media::CdmWrapperModule(); | 984 return new webkit_media::CdmWrapperModule(); |
911 } | 985 } |
912 | 986 |
913 } // namespace pp | 987 } // namespace pp |
OLD | NEW |