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 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 size_(0) {} | 248 size_(0) {} |
249 virtual ~PpbBuffer() {} | 249 virtual ~PpbBuffer() {} |
250 | 250 |
251 pp::Buffer_Dev buffer_; | 251 pp::Buffer_Dev buffer_; |
252 uint32_t buffer_id_; | 252 uint32_t buffer_id_; |
253 int32_t size_; | 253 int32_t size_; |
254 | 254 |
255 DISALLOW_COPY_AND_ASSIGN(PpbBuffer); | 255 DISALLOW_COPY_AND_ASSIGN(PpbBuffer); |
256 }; | 256 }; |
257 | 257 |
258 class PpbBufferAllocator : public cdm::Allocator { | 258 class PpbBufferAllocator { |
259 public: | 259 public: |
260 explicit PpbBufferAllocator(pp::Instance* instance) | 260 explicit PpbBufferAllocator(pp::Instance* instance) |
261 : instance_(instance), | 261 : instance_(instance), |
262 next_buffer_id_(1) {} | 262 next_buffer_id_(1) {} |
263 virtual ~PpbBufferAllocator() {} | 263 ~PpbBufferAllocator() {} |
264 | 264 |
265 // cdm::Allocator implementation. | 265 cdm::Buffer* Allocate(int32_t capacity); |
266 virtual cdm::Buffer* Allocate(int32_t capacity) OVERRIDE; | |
267 | 266 |
268 // Releases the buffer with |buffer_id|. A buffer can be recycled after | 267 // Releases the buffer with |buffer_id|. A buffer can be recycled after |
269 // it is released. | 268 // it is released. |
270 void Release(uint32_t buffer_id); | 269 void Release(uint32_t buffer_id); |
271 | 270 |
272 private: | 271 private: |
273 typedef std::map<uint32_t, pp::Buffer_Dev> AllocatedBufferMap; | 272 typedef std::map<uint32_t, pp::Buffer_Dev> AllocatedBufferMap; |
274 typedef std::multimap<int, std::pair<uint32_t, pp::Buffer_Dev> > | 273 typedef std::multimap<int, std::pair<uint32_t, pp::Buffer_Dev> > |
275 FreeBufferMap; | 274 FreeBufferMap; |
276 | 275 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 virtual cdm::Buffer* FrameBuffer() OVERRIDE { | 466 virtual cdm::Buffer* FrameBuffer() OVERRIDE { |
468 return buffer_; | 467 return buffer_; |
469 } | 468 } |
470 | 469 |
471 private: | 470 private: |
472 PpbBuffer* buffer_; | 471 PpbBuffer* buffer_; |
473 | 472 |
474 DISALLOW_COPY_AND_ASSIGN(AudioFramesImpl); | 473 DISALLOW_COPY_AND_ASSIGN(AudioFramesImpl); |
475 }; | 474 }; |
476 | 475 |
| 476 // GetCdmHostFunc implementation. |
| 477 void* GetCdmHost(int host_interface_version, void* user_data); |
| 478 |
477 // A wrapper class for abstracting away PPAPI interaction and threading for a | 479 // A wrapper class for abstracting away PPAPI interaction and threading for a |
478 // Content Decryption Module (CDM). | 480 // Content Decryption Module (CDM). |
479 class CdmWrapper : public pp::Instance, | 481 class CdmWrapper : public pp::Instance, |
480 public pp::ContentDecryptor_Private, | 482 public pp::ContentDecryptor_Private, |
481 public cdm::Host { | 483 public cdm::Host { |
482 public: | 484 public: |
483 CdmWrapper(PP_Instance instance, pp::Module* module); | 485 CdmWrapper(PP_Instance instance, pp::Module* module); |
484 virtual ~CdmWrapper(); | 486 virtual ~CdmWrapper(); |
485 | 487 |
486 // pp::Instance implementation. | 488 // pp::Instance implementation. |
(...skipping 23 matching lines...) Expand all Loading... |
510 virtual void DeinitializeDecoder(PP_DecryptorStreamType decoder_type, | 512 virtual void DeinitializeDecoder(PP_DecryptorStreamType decoder_type, |
511 uint32_t request_id) OVERRIDE; | 513 uint32_t request_id) OVERRIDE; |
512 virtual void ResetDecoder(PP_DecryptorStreamType decoder_type, | 514 virtual void ResetDecoder(PP_DecryptorStreamType decoder_type, |
513 uint32_t request_id) OVERRIDE; | 515 uint32_t request_id) OVERRIDE; |
514 virtual void DecryptAndDecode( | 516 virtual void DecryptAndDecode( |
515 PP_DecryptorStreamType decoder_type, | 517 PP_DecryptorStreamType decoder_type, |
516 pp::Buffer_Dev encrypted_buffer, | 518 pp::Buffer_Dev encrypted_buffer, |
517 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; | 519 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; |
518 | 520 |
519 // cdm::Host implementation. | 521 // cdm::Host implementation. |
| 522 virtual cdm::Buffer* Allocate(int32_t capacity) OVERRIDE; |
520 virtual void SetTimer(int64_t delay_ms, void* context) OVERRIDE; | 523 virtual void SetTimer(int64_t delay_ms, void* context) OVERRIDE; |
521 virtual double GetCurrentWallTimeInSeconds() OVERRIDE; | 524 virtual double GetCurrentWallTimeInSeconds() OVERRIDE; |
522 virtual void SendKeyMessage( | 525 virtual void SendKeyMessage( |
523 const char* session_id, int32_t session_id_length, | 526 const char* session_id, int32_t session_id_length, |
524 const char* message, int32_t message_length, | 527 const char* message, int32_t message_length, |
525 const char* default_url, int32_t default_url_length) OVERRIDE; | 528 const char* default_url, int32_t default_url_length) OVERRIDE; |
526 virtual void SendKeyError(const char* session_id, | 529 virtual void SendKeyError(const char* session_id, |
527 int32_t session_id_length, | 530 int32_t session_id_length, |
528 cdm::MediaKeyError error_code, | 531 cdm::MediaKeyError error_code, |
529 uint32_t system_code) OVERRIDE; | 532 uint32_t system_code) OVERRIDE; |
| 533 virtual void GetPrivateData(int32_t* instance, |
| 534 GetPrivateInterface* get_interface) OVERRIDE; |
530 | 535 |
531 private: | 536 private: |
532 struct SessionInfo { | 537 struct SessionInfo { |
533 SessionInfo(const std::string& key_system_in, | 538 SessionInfo(const std::string& key_system_in, |
534 const std::string& session_id_in) | 539 const std::string& session_id_in) |
535 : key_system(key_system_in), | 540 : key_system(key_system_in), |
536 session_id(session_id_in) {} | 541 session_id(session_id_in) {} |
537 const std::string key_system; | 542 const std::string key_system; |
538 const std::string session_id; | 543 const std::string session_id; |
539 }; | 544 }; |
540 | 545 |
541 typedef linked_ptr<DecryptedBlockImpl> LinkedDecryptedBlock; | 546 typedef linked_ptr<DecryptedBlockImpl> LinkedDecryptedBlock; |
542 typedef linked_ptr<VideoFrameImpl> LinkedVideoFrame; | 547 typedef linked_ptr<VideoFrameImpl> LinkedVideoFrame; |
543 typedef linked_ptr<AudioFramesImpl> LinkedAudioFrames; | 548 typedef linked_ptr<AudioFramesImpl> LinkedAudioFrames; |
544 | 549 |
| 550 bool CreateCdmInstance(const std::string& key_system); |
| 551 |
545 void SendUnknownKeyError(const std::string& key_system, | 552 void SendUnknownKeyError(const std::string& key_system, |
546 const std::string& session_id); | 553 const std::string& session_id); |
547 | 554 |
548 void SendKeyAdded(const std::string& key_system, | 555 void SendKeyAdded(const std::string& key_system, |
549 const std::string& session_id); | 556 const std::string& session_id); |
550 | 557 |
551 void SendKeyErrorInternal(const std::string& key_system, | 558 void SendKeyErrorInternal(const std::string& key_system, |
552 const std::string& session_id, | 559 const std::string& session_id, |
553 cdm::MediaKeyError error_code, | 560 cdm::MediaKeyError error_code, |
554 uint32_t system_code); | 561 uint32_t system_code); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module) | 611 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module) |
605 : pp::Instance(instance), | 612 : pp::Instance(instance), |
606 pp::ContentDecryptor_Private(this), | 613 pp::ContentDecryptor_Private(this), |
607 allocator_(this), | 614 allocator_(this), |
608 cdm_(NULL) { | 615 cdm_(NULL) { |
609 callback_factory_.Initialize(this); | 616 callback_factory_.Initialize(this); |
610 } | 617 } |
611 | 618 |
612 CdmWrapper::~CdmWrapper() { | 619 CdmWrapper::~CdmWrapper() { |
613 if (cdm_) | 620 if (cdm_) |
614 DestroyCdmInstance(cdm_); | 621 cdm_->Destroy(); |
| 622 } |
| 623 |
| 624 bool CdmWrapper::CreateCdmInstance(const std::string& key_system) { |
| 625 PP_DCHECK(!cdm_); |
| 626 cdm_ = static_cast<cdm::ContentDecryptionModule*>( |
| 627 ::CreateCdmInstance(cdm::kCdmInterfaceVersion, |
| 628 key_system.data(), key_system.size(), |
| 629 GetCdmHost, this)); |
| 630 |
| 631 return (cdm_ != NULL); |
615 } | 632 } |
616 | 633 |
617 void CdmWrapper::GenerateKeyRequest(const std::string& key_system, | 634 void CdmWrapper::GenerateKeyRequest(const std::string& key_system, |
618 const std::string& type, | 635 const std::string& type, |
619 pp::VarArrayBuffer init_data) { | 636 pp::VarArrayBuffer init_data) { |
620 PP_DCHECK(!key_system.empty()); | 637 PP_DCHECK(!key_system.empty()); |
621 PP_DCHECK(key_system_.empty() || key_system_ == key_system); | 638 PP_DCHECK(key_system_.empty() || key_system_ == key_system); |
622 | 639 |
623 if (!cdm_) { | 640 if (!cdm_) { |
624 cdm_ = CreateCdmInstance(key_system.data(), key_system.size(), | 641 if (!CreateCdmInstance(key_system)) { |
625 &allocator_, this); | |
626 PP_DCHECK(cdm_); | |
627 if (!cdm_) { | |
628 SendUnknownKeyError(key_system, ""); | 642 SendUnknownKeyError(key_system, ""); |
629 return; | 643 return; |
630 } | 644 } |
631 } | 645 } |
| 646 PP_DCHECK(cdm_); |
632 | 647 |
633 // Must be set here in case the CDM synchronously calls a cdm::Host method. | 648 // Must be set here in case the CDM synchronously calls a cdm::Host method. |
634 // Clear below on error. | 649 // Clear below on error. |
635 // TODO(ddorwin): Remove this when key_system is added to cdm::Host methods. | 650 // TODO(ddorwin): Set/clear key_system_ & cdm_ at same time; clear both on |
| 651 // error below. |
636 key_system_ = key_system; | 652 key_system_ = key_system; |
637 cdm::Status status = cdm_->GenerateKeyRequest( | 653 cdm::Status status = cdm_->GenerateKeyRequest( |
638 type.data(), type.size(), | 654 type.data(), type.size(), |
639 static_cast<const uint8_t*>(init_data.Map()), | 655 static_cast<const uint8_t*>(init_data.Map()), |
640 init_data.ByteLength()); | 656 init_data.ByteLength()); |
641 PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError); | 657 PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError); |
642 if (status != cdm::kSuccess) { | 658 if (status != cdm::kSuccess) { |
643 key_system_.clear(); // See comment above. | 659 key_system_.clear(); // See comment above. |
644 return; | 660 return; |
645 } | 661 } |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
853 encrypted_block_info.tracking_info)); | 869 encrypted_block_info.tracking_info)); |
854 return; | 870 return; |
855 } | 871 } |
856 | 872 |
857 default: | 873 default: |
858 PP_NOTREACHED(); | 874 PP_NOTREACHED(); |
859 return; | 875 return; |
860 } | 876 } |
861 } | 877 } |
862 | 878 |
| 879 cdm::Buffer* CdmWrapper::Allocate(int32_t capacity) { |
| 880 return allocator_.Allocate(capacity); |
| 881 } |
| 882 |
863 void CdmWrapper::SetTimer(int64_t delay_ms, void* context) { | 883 void CdmWrapper::SetTimer(int64_t delay_ms, void* context) { |
864 // NOTE: doesn't really need to run on the main thread; could just as well run | 884 // NOTE: doesn't really need to run on the main thread; could just as well run |
865 // on a helper thread if |cdm_| were thread-friendly and care was taken. We | 885 // on a helper thread if |cdm_| were thread-friendly and care was taken. We |
866 // only use CallOnMainThread() here to get delayed-execution behavior. | 886 // only use CallOnMainThread() here to get delayed-execution behavior. |
867 pp::Module::Get()->core()->CallOnMainThread( | 887 pp::Module::Get()->core()->CallOnMainThread( |
868 delay_ms, | 888 delay_ms, |
869 callback_factory_.NewCallback(&CdmWrapper::TimerExpired, context), | 889 callback_factory_.NewCallback(&CdmWrapper::TimerExpired, context), |
870 PP_OK); | 890 PP_OK); |
871 } | 891 } |
872 | 892 |
(...skipping 22 matching lines...) Expand all Loading... |
895 void CdmWrapper::SendKeyError(const char* session_id, | 915 void CdmWrapper::SendKeyError(const char* session_id, |
896 int32_t session_id_length, | 916 int32_t session_id_length, |
897 cdm::MediaKeyError error_code, | 917 cdm::MediaKeyError error_code, |
898 uint32_t system_code) { | 918 uint32_t system_code) { |
899 SendKeyErrorInternal(key_system_, | 919 SendKeyErrorInternal(key_system_, |
900 std::string(session_id, session_id_length), | 920 std::string(session_id, session_id_length), |
901 error_code, | 921 error_code, |
902 system_code); | 922 system_code); |
903 } | 923 } |
904 | 924 |
| 925 void CdmWrapper::GetPrivateData(int32_t* instance, |
| 926 cdm::Host::GetPrivateInterface* get_interface) { |
| 927 *instance = pp_instance(); |
| 928 *get_interface = pp::Module::Get()->get_browser_interface(); |
| 929 } |
| 930 |
905 void CdmWrapper::SendUnknownKeyError(const std::string& key_system, | 931 void CdmWrapper::SendUnknownKeyError(const std::string& key_system, |
906 const std::string& session_id) { | 932 const std::string& session_id) { |
907 SendKeyErrorInternal(key_system, session_id, cdm::kUnknownError, 0); | 933 SendKeyErrorInternal(key_system, session_id, cdm::kUnknownError, 0); |
908 } | 934 } |
909 | 935 |
910 | |
911 void CdmWrapper::SendKeyAdded(const std::string& key_system, | 936 void CdmWrapper::SendKeyAdded(const std::string& key_system, |
912 const std::string& session_id) { | 937 const std::string& session_id) { |
913 PostOnMain(callback_factory_.NewCallback( | 938 PostOnMain(callback_factory_.NewCallback( |
914 &CdmWrapper::KeyAdded, | 939 &CdmWrapper::KeyAdded, |
915 SessionInfo(key_system_, session_id))); | 940 SessionInfo(key_system_, session_id))); |
916 } | 941 } |
917 | 942 |
918 void CdmWrapper::SendKeyErrorInternal(const std::string& key_system, | 943 void CdmWrapper::SendKeyErrorInternal(const std::string& key_system, |
919 const std::string& session_id, | 944 const std::string& session_id, |
920 cdm::MediaKeyError error_code, | 945 cdm::MediaKeyError error_code, |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1110 static_cast<cdm::VideoFrame::VideoPlane>(i); | 1135 static_cast<cdm::VideoFrame::VideoPlane>(i); |
1111 if (ppb_buffer->Size() < video_frame->PlaneOffset(plane) + | 1136 if (ppb_buffer->Size() < video_frame->PlaneOffset(plane) + |
1112 plane_height * video_frame->Stride(plane)) { | 1137 plane_height * video_frame->Stride(plane)) { |
1113 return false; | 1138 return false; |
1114 } | 1139 } |
1115 } | 1140 } |
1116 | 1141 |
1117 return true; | 1142 return true; |
1118 } | 1143 } |
1119 | 1144 |
| 1145 void* GetCdmHost(int host_interface_version, void* user_data) { |
| 1146 if (!host_interface_version || !user_data) |
| 1147 return NULL; |
| 1148 |
| 1149 if (host_interface_version != cdm::kHostInterfaceVersion) |
| 1150 return NULL; |
| 1151 |
| 1152 CdmWrapper* cdm_wrapper = static_cast<CdmWrapper*>(user_data); |
| 1153 return static_cast<cdm::Host*>(cdm_wrapper); |
| 1154 } |
| 1155 |
1120 // This object is the global object representing this plugin library as long | 1156 // This object is the global object representing this plugin library as long |
1121 // as it is loaded. | 1157 // as it is loaded. |
1122 class CdmWrapperModule : public pp::Module { | 1158 class CdmWrapperModule : public pp::Module { |
1123 public: | 1159 public: |
1124 CdmWrapperModule() : pp::Module() { | 1160 CdmWrapperModule() : pp::Module() { |
1125 // This function blocks the renderer thread (PluginInstance::Initialize()). | 1161 // This function blocks the renderer thread (PluginInstance::Initialize()). |
1126 // Move this call to other places if this may be a concern in the future. | 1162 // Move this call to other places if this may be a concern in the future. |
1127 INITIALIZE_CDM_MODULE(); | 1163 INITIALIZE_CDM_MODULE(); |
1128 } | 1164 } |
1129 virtual ~CdmWrapperModule() { | 1165 virtual ~CdmWrapperModule() { |
1130 DeinitializeCdmModule(); | 1166 DeinitializeCdmModule(); |
1131 } | 1167 } |
1132 | 1168 |
1133 virtual pp::Instance* CreateInstance(PP_Instance instance) { | 1169 virtual pp::Instance* CreateInstance(PP_Instance instance) { |
1134 return new CdmWrapper(instance, this); | 1170 return new CdmWrapper(instance, this); |
1135 } | 1171 } |
1136 }; | 1172 }; |
1137 | 1173 |
1138 } // namespace webkit_media | 1174 } // namespace webkit_media |
1139 | 1175 |
1140 namespace pp { | 1176 namespace pp { |
1141 | 1177 |
1142 // Factory function for your specialization of the Module object. | 1178 // Factory function for your specialization of the Module object. |
1143 Module* CreateModule() { | 1179 Module* CreateModule() { |
1144 return new webkit_media::CdmWrapperModule(); | 1180 return new webkit_media::CdmWrapperModule(); |
1145 } | 1181 } |
1146 | 1182 |
1147 } // namespace pp | 1183 } // namespace pp |
OLD | NEW |