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 <map> | 6 #include <map> |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "ppapi/utility/completion_callback_factory.h" | 27 #include "ppapi/utility/completion_callback_factory.h" |
28 #include "webkit/media/crypto/ppapi/content_decryption_module.h" | 28 #include "webkit/media/crypto/ppapi/content_decryption_module.h" |
29 #include "webkit/media/crypto/ppapi/linked_ptr.h" | 29 #include "webkit/media/crypto/ppapi/linked_ptr.h" |
30 | 30 |
31 namespace { | 31 namespace { |
32 | 32 |
33 bool IsMainThread() { | 33 bool IsMainThread() { |
34 return pp::Module::Get()->core()->IsMainThread(); | 34 return pp::Module::Get()->core()->IsMainThread(); |
35 } | 35 } |
36 | 36 |
| 37 // Posts a task to run |cb| on the main thread. The task is posted even if the |
| 38 // current thread is the main thread. |
| 39 void PostOnMain(pp::CompletionCallback cb) { |
| 40 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK); |
| 41 } |
| 42 |
| 43 // Ensures |cb| is called on the main thread, either because the current thread |
| 44 // is the main thread or by posting it to the main thread. |
37 void CallOnMain(pp::CompletionCallback cb) { | 45 void CallOnMain(pp::CompletionCallback cb) { |
38 // TODO(tomfinegan): This is only necessary because PPAPI doesn't allow calls | 46 // TODO(tomfinegan): This is only necessary because PPAPI doesn't allow calls |
39 // off the main thread yet. Remove this once the change lands. | 47 // off the main thread yet. Remove this once the change lands. |
40 if (IsMainThread()) | 48 if (IsMainThread()) |
41 cb.Run(PP_OK); | 49 cb.Run(PP_OK); |
42 else | 50 else |
43 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK); | 51 PostOnMain(cb); |
44 } | 52 } |
45 | 53 |
46 // Configures a cdm::InputBuffer. |subsamples| must exist as long as | 54 // Configures a cdm::InputBuffer. |subsamples| must exist as long as |
47 // |input_buffer| is in use. | 55 // |input_buffer| is in use. |
48 void ConfigureInputBuffer( | 56 void ConfigureInputBuffer( |
49 const pp::Buffer_Dev& encrypted_buffer, | 57 const pp::Buffer_Dev& encrypted_buffer, |
50 const PP_EncryptedBlockInfo& encrypted_block_info, | 58 const PP_EncryptedBlockInfo& encrypted_block_info, |
51 std::vector<cdm::SubsampleEntry>* subsamples, | 59 std::vector<cdm::SubsampleEntry>* subsamples, |
52 cdm::InputBuffer* input_buffer) { | 60 cdm::InputBuffer* input_buffer) { |
53 PP_DCHECK(subsamples); | 61 PP_DCHECK(subsamples); |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 virtual void SendKeyError(const char* session_id, | 519 virtual void SendKeyError(const char* session_id, |
512 int32_t session_id_length, | 520 int32_t session_id_length, |
513 cdm::MediaKeyError error_code, | 521 cdm::MediaKeyError error_code, |
514 uint32_t system_code) OVERRIDE; | 522 uint32_t system_code) OVERRIDE; |
515 | 523 |
516 private: | 524 private: |
517 typedef linked_ptr<DecryptedBlockImpl> LinkedDecryptedBlock; | 525 typedef linked_ptr<DecryptedBlockImpl> LinkedDecryptedBlock; |
518 typedef linked_ptr<VideoFrameImpl> LinkedVideoFrame; | 526 typedef linked_ptr<VideoFrameImpl> LinkedVideoFrame; |
519 typedef linked_ptr<AudioFramesImpl> LinkedAudioFrames; | 527 typedef linked_ptr<AudioFramesImpl> LinkedAudioFrames; |
520 | 528 |
| 529 void SendUnknownKeyError(const std::string& session_id); |
| 530 |
| 531 void SendKeyAdded(const std::string& session_id); |
| 532 |
521 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to | 533 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to |
522 // <code>callback_factory_</code> to ensure that calls into | 534 // <code>callback_factory_</code> to ensure that calls into |
523 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. | 535 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. |
524 void KeyAdded(int32_t result, const std::string& session_id); | 536 void KeyAdded(int32_t result, const std::string& session_id); |
525 void KeyMessage(int32_t result, | 537 void KeyMessage(int32_t result, |
526 const std::string& session_id, | 538 const std::string& session_id, |
527 const std::string& message, | 539 const std::string& message, |
528 const std::string& default_url); | 540 const std::string& default_url); |
529 void KeyError(int32_t result, | 541 void KeyError(int32_t result, |
530 const std::string& session_id, | 542 const std::string& session_id, |
(...skipping 15 matching lines...) Expand all Loading... |
546 uint32_t request_id); | 558 uint32_t request_id); |
547 void DeliverFrame(int32_t result, | 559 void DeliverFrame(int32_t result, |
548 const cdm::Status& status, | 560 const cdm::Status& status, |
549 const LinkedVideoFrame& video_frame, | 561 const LinkedVideoFrame& video_frame, |
550 const PP_DecryptTrackingInfo& tracking_info); | 562 const PP_DecryptTrackingInfo& tracking_info); |
551 void DeliverSamples(int32_t result, | 563 void DeliverSamples(int32_t result, |
552 const cdm::Status& status, | 564 const cdm::Status& status, |
553 const LinkedAudioFrames& audio_frames, | 565 const LinkedAudioFrames& audio_frames, |
554 const PP_DecryptTrackingInfo& tracking_info); | 566 const PP_DecryptTrackingInfo& tracking_info); |
555 | 567 |
556 // Helper function to fire KeyError event on the main thread. | |
557 void SendUnknownKeyError(const std::string& session_id); | |
558 | |
559 // Helper for SetTimer(). | 568 // Helper for SetTimer(). |
560 void TimerExpired(int32_t result, void* context); | 569 void TimerExpired(int32_t result, void* context); |
561 | 570 |
562 bool IsValidVideoFrame(const LinkedVideoFrame& video_frame); | 571 bool IsValidVideoFrame(const LinkedVideoFrame& video_frame); |
563 | 572 |
564 PpbBufferAllocator allocator_; | 573 PpbBufferAllocator allocator_; |
565 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; | 574 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; |
566 cdm::ContentDecryptionModule* cdm_; | 575 cdm::ContentDecryptionModule* cdm_; |
567 std::string key_system_; | 576 std::string key_system_; |
568 | 577 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 | 638 |
630 cdm::Status status = cdm_->AddKey(session_id.data(), session_id.size(), | 639 cdm::Status status = cdm_->AddKey(session_id.data(), session_id.size(), |
631 key_ptr, key_size, | 640 key_ptr, key_size, |
632 init_data_ptr, init_data_size); | 641 init_data_ptr, init_data_size); |
633 PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError); | 642 PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError); |
634 if (status != cdm::kSuccess) { | 643 if (status != cdm::kSuccess) { |
635 SendUnknownKeyError(session_id); | 644 SendUnknownKeyError(session_id); |
636 return; | 645 return; |
637 } | 646 } |
638 | 647 |
639 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyAdded, session_id)); | 648 SendKeyAdded(session_id); |
640 } | 649 } |
641 | 650 |
642 void CdmWrapper::CancelKeyRequest(const std::string& session_id) { | 651 void CdmWrapper::CancelKeyRequest(const std::string& session_id) { |
643 PP_DCHECK(cdm_); // GenerateKeyRequest() should have succeeded. | 652 PP_DCHECK(cdm_); // GenerateKeyRequest() should have succeeded. |
644 if (!cdm_) { | 653 if (!cdm_) { |
645 SendUnknownKeyError(session_id); | 654 SendUnknownKeyError(session_id); |
646 return; | 655 return; |
647 } | 656 } |
648 | 657 |
649 cdm::Status status = cdm_->CancelKeyRequest(session_id.data(), | 658 cdm::Status status = cdm_->CancelKeyRequest(session_id.data(), |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
813 encrypted_block_info.tracking_info)); | 822 encrypted_block_info.tracking_info)); |
814 return; | 823 return; |
815 } | 824 } |
816 | 825 |
817 default: | 826 default: |
818 PP_NOTREACHED(); | 827 PP_NOTREACHED(); |
819 return; | 828 return; |
820 } | 829 } |
821 } | 830 } |
822 | 831 |
823 void CdmWrapper::SendUnknownKeyError(const std::string& session_id) { | |
824 CallOnMain(callback_factory_.NewCallback( | |
825 &CdmWrapper::KeyError, session_id, cdm::kUnknownError, 0)); | |
826 } | |
827 | |
828 void CdmWrapper::SetTimer(int64_t delay_ms, void* context) { | 832 void CdmWrapper::SetTimer(int64_t delay_ms, void* context) { |
829 // NOTE: doesn't really need to run on the main thread; could just as well run | 833 // NOTE: doesn't really need to run on the main thread; could just as well run |
830 // on a helper thread if |cdm_| were thread-friendly and care was taken. We | 834 // on a helper thread if |cdm_| were thread-friendly and care was taken. We |
831 // only use CallOnMainThread() here to get delayed-execution behavior. | 835 // only use CallOnMainThread() here to get delayed-execution behavior. |
832 pp::Module::Get()->core()->CallOnMainThread( | 836 pp::Module::Get()->core()->CallOnMainThread( |
833 delay_ms, | 837 delay_ms, |
834 callback_factory_.NewCallback(&CdmWrapper::TimerExpired, context), | 838 callback_factory_.NewCallback(&CdmWrapper::TimerExpired, context), |
835 PP_OK); | 839 PP_OK); |
836 } | 840 } |
837 | 841 |
838 void CdmWrapper::TimerExpired(int32_t result, void* context) { | 842 void CdmWrapper::TimerExpired(int32_t result, void* context) { |
839 PP_DCHECK(result == PP_OK); | 843 PP_DCHECK(result == PP_OK); |
840 cdm_->TimerExpired(context); | 844 cdm_->TimerExpired(context); |
841 } | 845 } |
842 | 846 |
843 double CdmWrapper::GetCurrentWallTimeInSeconds() { | 847 double CdmWrapper::GetCurrentWallTimeInSeconds() { |
844 return pp::Module::Get()->core()->GetTime(); | 848 return pp::Module::Get()->core()->GetTime(); |
845 } | 849 } |
846 | 850 |
847 void CdmWrapper::SendKeyMessage( | 851 void CdmWrapper::SendKeyMessage( |
848 const char* session_id, int32_t session_id_length, | 852 const char* session_id, int32_t session_id_length, |
849 const char* message, int32_t message_length, | 853 const char* message, int32_t message_length, |
850 const char* default_url, int32_t default_url_length) { | 854 const char* default_url, int32_t default_url_length) { |
851 CallOnMain(callback_factory_.NewCallback( | 855 PostOnMain(callback_factory_.NewCallback( |
852 &CdmWrapper::KeyMessage, | 856 &CdmWrapper::KeyMessage, |
853 std::string(session_id, session_id_length), | 857 std::string(session_id, session_id_length), |
854 std::string(message, message_length), | 858 std::string(message, message_length), |
855 std::string(default_url, default_url_length))); | 859 std::string(default_url, default_url_length))); |
856 } | 860 } |
857 | 861 |
858 void CdmWrapper::SendKeyError(const char* session_id, | 862 void CdmWrapper::SendKeyError(const char* session_id, |
859 int32_t session_id_length, | 863 int32_t session_id_length, |
860 cdm::MediaKeyError error_code, | 864 cdm::MediaKeyError error_code, |
861 uint32_t system_code) { | 865 uint32_t system_code) { |
862 CallOnMain(callback_factory_.NewCallback( | 866 PostOnMain(callback_factory_.NewCallback( |
863 &CdmWrapper::KeyError, | 867 &CdmWrapper::KeyError, |
864 std::string(session_id, session_id_length), | 868 std::string(session_id, session_id_length), |
865 error_code, | 869 error_code, |
866 system_code)); | 870 system_code)); |
867 } | 871 } |
868 | 872 |
| 873 void CdmWrapper::SendUnknownKeyError(const std::string& session_id) { |
| 874 SendKeyError(session_id.data(), session_id.size(), cdm::kUnknownError, 0); |
| 875 } |
| 876 |
| 877 void CdmWrapper::SendKeyAdded(const std::string& session_id) { |
| 878 PostOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyAdded,session_id)); |
| 879 } |
| 880 |
869 void CdmWrapper::KeyAdded(int32_t result, const std::string& session_id) { | 881 void CdmWrapper::KeyAdded(int32_t result, const std::string& session_id) { |
870 PP_DCHECK(result == PP_OK); | 882 PP_DCHECK(result == PP_OK); |
| 883 PP_DCHECK(!key_system_.empty()); |
871 pp::ContentDecryptor_Private::KeyAdded(key_system_, session_id); | 884 pp::ContentDecryptor_Private::KeyAdded(key_system_, session_id); |
872 } | 885 } |
873 | 886 |
874 void CdmWrapper::KeyMessage(int32_t result, | 887 void CdmWrapper::KeyMessage(int32_t result, |
875 const std::string& session_id, | 888 const std::string& session_id, |
876 const std::string& message, | 889 const std::string& message, |
877 const std::string& default_url) { | 890 const std::string& default_url) { |
878 PP_DCHECK(result == PP_OK); | 891 PP_DCHECK(result == PP_OK); |
879 | 892 |
880 pp::VarArrayBuffer message_array_buffer(message.size()); | 893 pp::VarArrayBuffer message_array_buffer(message.size()); |
881 if (message.size() > 0) { | 894 if (message.size() > 0) { |
882 memcpy(message_array_buffer.Map(), message.data(), message.size()); | 895 memcpy(message_array_buffer.Map(), message.data(), message.size()); |
883 } | 896 } |
884 | 897 |
| 898 PP_DCHECK(!key_system_.empty()); |
885 pp::ContentDecryptor_Private::KeyMessage( | 899 pp::ContentDecryptor_Private::KeyMessage( |
886 key_system_, session_id, message_array_buffer, default_url); | 900 key_system_, session_id, message_array_buffer, default_url); |
887 } | 901 } |
888 | 902 |
889 // TODO(xhwang): Support MediaKeyError (see spec: http://goo.gl/rbdnR) in CDM | |
890 // interface and in this function. | |
891 void CdmWrapper::KeyError(int32_t result, | 903 void CdmWrapper::KeyError(int32_t result, |
892 const std::string& session_id, | 904 const std::string& session_id, |
893 cdm::MediaKeyError error_code, | 905 cdm::MediaKeyError error_code, |
894 uint32_t system_code) { | 906 uint32_t system_code) { |
895 PP_DCHECK(result == PP_OK); | 907 PP_DCHECK(result == PP_OK); |
| 908 PP_DCHECK(!key_system_.empty()); |
896 pp::ContentDecryptor_Private::KeyError( | 909 pp::ContentDecryptor_Private::KeyError( |
897 key_system_, session_id, error_code, system_code); | 910 key_system_, session_id, error_code, system_code); |
898 } | 911 } |
899 | 912 |
900 void CdmWrapper::DeliverBlock(int32_t result, | 913 void CdmWrapper::DeliverBlock(int32_t result, |
901 const cdm::Status& status, | 914 const cdm::Status& status, |
902 const LinkedDecryptedBlock& decrypted_block, | 915 const LinkedDecryptedBlock& decrypted_block, |
903 const PP_DecryptTrackingInfo& tracking_info) { | 916 const PP_DecryptTrackingInfo& tracking_info) { |
904 PP_DCHECK(result == PP_OK); | 917 PP_DCHECK(result == PP_OK); |
905 PP_DecryptedBlockInfo decrypted_block_info; | 918 PP_DecryptedBlockInfo decrypted_block_info; |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 } // namespace webkit_media | 1087 } // namespace webkit_media |
1075 | 1088 |
1076 namespace pp { | 1089 namespace pp { |
1077 | 1090 |
1078 // Factory function for your specialization of the Module object. | 1091 // Factory function for your specialization of the Module object. |
1079 Module* CreateModule() { | 1092 Module* CreateModule() { |
1080 return new webkit_media::CdmWrapperModule(); | 1093 return new webkit_media::CdmWrapperModule(); |
1081 } | 1094 } |
1082 | 1095 |
1083 } // namespace pp | 1096 } // namespace pp |
OLD | NEW |