diff options
author | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-19 15:49:37 +0000 |
---|---|---|
committer | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-19 15:49:37 +0000 |
commit | 58023736bcd68899eb802e29a8afdfc5e516ff83 (patch) | |
tree | 47eb9557941394181b0e82084cb8fe6a6666650e /media/cdm/ppapi | |
parent | 71d4bd80077d11ebf351d0c2a901d9ccb4e0fbec (diff) | |
download | chromium_src-58023736bcd68899eb802e29a8afdfc5e516ff83.zip chromium_src-58023736bcd68899eb802e29a8afdfc5e516ff83.tar.gz chromium_src-58023736bcd68899eb802e29a8afdfc5e516ff83.tar.bz2 |
Add CdmWrapper to support multiple CDM versions in CdmAdapter.
CdmWrapper wraps different versions of ContentDecryptionModule interfaces and exposes a common interface to the caller.
BUG=306647
TEST=none
Review URL: https://codereview.chromium.org/26155003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@229571 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/cdm/ppapi')
-rw-r--r-- | media/cdm/ppapi/cdm_adapter.cc | 12 | ||||
-rw-r--r-- | media/cdm/ppapi/cdm_adapter.h | 3 | ||||
-rw-r--r-- | media/cdm/ppapi/cdm_wrapper.h | 211 | ||||
-rw-r--r-- | media/cdm/ppapi/linked_ptr.h | 1 |
4 files changed, 217 insertions, 10 deletions
diff --git a/media/cdm/ppapi/cdm_adapter.cc b/media/cdm/ppapi/cdm_adapter.cc index fb8e5f4..7fcd5f0 100644 --- a/media/cdm/ppapi/cdm_adapter.cc +++ b/media/cdm/ppapi/cdm_adapter.cc @@ -212,18 +212,12 @@ CdmAdapter::CdmAdapter(PP_Instance instance, pp::Module* module) callback_factory_.Initialize(this); } -CdmAdapter::~CdmAdapter() { - if (cdm_) - cdm_->Destroy(); -} +CdmAdapter::~CdmAdapter() {} bool CdmAdapter::CreateCdmInstance(const std::string& key_system) { PP_DCHECK(!cdm_); - cdm_ = static_cast<cdm::ContentDecryptionModule*>( - ::CreateCdmInstance(cdm::kCdmInterfaceVersion, - key_system.data(), key_system.size(), - GetCdmHost, this)); - + cdm_ = make_linked_ptr(CdmWrapper::Create( + key_system.data(), key_system.size(), GetCdmHost, this)); return (cdm_ != NULL); } diff --git a/media/cdm/ppapi/cdm_adapter.h b/media/cdm/ppapi/cdm_adapter.h index f739213..bf180d1 100644 --- a/media/cdm/ppapi/cdm_adapter.h +++ b/media/cdm/ppapi/cdm_adapter.h @@ -12,6 +12,7 @@ #include "base/compiler_specific.h" #include "media/cdm/ppapi/api/content_decryption_module.h" #include "media/cdm/ppapi/cdm_helpers.h" +#include "media/cdm/ppapi/cdm_wrapper.h" #include "media/cdm/ppapi/linked_ptr.h" #include "ppapi/c/pp_stdint.h" #include "ppapi/c/private/pp_content_decryptor.h" @@ -154,7 +155,7 @@ class CdmAdapter : public pp::Instance, PpbBufferAllocator allocator_; pp::CompletionCallbackFactory<CdmAdapter> callback_factory_; - cdm::ContentDecryptionModule* cdm_; + linked_ptr<CdmWrapper> cdm_; std::string key_system_; DISALLOW_COPY_AND_ASSIGN(CdmAdapter); diff --git a/media/cdm/ppapi/cdm_wrapper.h b/media/cdm/ppapi/cdm_wrapper.h new file mode 100644 index 0000000..016292e --- /dev/null +++ b/media/cdm/ppapi/cdm_wrapper.h @@ -0,0 +1,211 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_CDM_PPAPI_CDM_WRAPPER_H_ +#define MEDIA_CDM_PPAPI_CDM_WRAPPER_H_ + +#include "base/basictypes.h" +#include "media/cdm/ppapi/api/content_decryption_module.h" +#include "media/cdm/ppapi/cdm_helpers.h" +#include "ppapi/cpp/logging.h" + +namespace media { + +// CdmWrapper wraps different versions of ContentDecryptionModule interfaces and +// exposes a common interface to the caller. +// +// The caller should call CdmWrapper::Create() to create a CDM instance. +// CdmWrapper will first try to create a CDM instance that supports the latest +// CDM interface (ContentDecryptionModule). If such an instance cannot be +// created (e.g. an older CDM was loaded), CdmWrapper will try to create a CDM +// that supports an older version of CDM interface (e.g. +// ContentDecryptionModule_*). Internally CdmWrapper converts the CdmWrapper +// calls to corresponding ContentDecryptionModule calls. +// +// Note that CdmWrapper interface always reflects the latest state of content +// decryption related PPAPI APIs (e.g. pp::ContentDecryptor_Private). +// +// Since this file is highly templated and default implementations are short +// (just a shim layer in most cases), everything is done in this header file. +class CdmWrapper { + public: + static CdmWrapper* Create(const char* key_system, + int key_system_size, + GetCdmHostFunc get_cdm_host_func, + void* user_data); + + virtual ~CdmWrapper() {}; + + virtual cdm::Status GenerateKeyRequest(const char* type, + int type_size, + const uint8_t* init_data, + int init_data_size) = 0; + virtual cdm::Status AddKey(const char* session_id, + int session_id_size, + const uint8_t* key, + int key_size, + const uint8_t* key_id, + int key_id_size) = 0; + virtual cdm::Status CancelKeyRequest(const char* session_id, + int session_id_size) = 0; + virtual void TimerExpired(void* context) = 0; + virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer, + cdm::DecryptedBlock* decrypted_buffer) = 0; + virtual cdm::Status InitializeAudioDecoder( + const cdm::AudioDecoderConfig& audio_decoder_config) = 0; + virtual cdm::Status InitializeVideoDecoder( + const cdm::VideoDecoderConfig& video_decoder_config) = 0; + virtual void DeinitializeDecoder(cdm::StreamType decoder_type) = 0; + virtual void ResetDecoder(cdm::StreamType decoder_type) = 0; + virtual cdm::Status DecryptAndDecodeFrame( + const cdm::InputBuffer& encrypted_buffer, + cdm::VideoFrame* video_frame) = 0; + virtual cdm::Status DecryptAndDecodeSamples( + const cdm::InputBuffer& encrypted_buffer, + cdm::AudioFrames* audio_frames) = 0; + + protected: + CdmWrapper() {}; + + private: + DISALLOW_COPY_AND_ASSIGN(CdmWrapper); +}; + +// Template class that does the CdmWrapper -> CdmInterface conversion. Default +// implementations are provided. Any methods that need special treatment should +// be specialized. +// TODO(xhwang): Remove CdmInterfaceVersion template parameter after we roll +// CDM.h DEPS. +template <class CdmInterface, int CdmInterfaceVersion> +class CdmWrapperImpl : public CdmWrapper { + public: + static CdmWrapper* Create(const char* key_system, + int key_system_size, + GetCdmHostFunc get_cdm_host_func, + void* user_data) { + void* cdm_instance = ::CreateCdmInstance(CdmInterfaceVersion, + key_system, key_system_size, get_cdm_host_func, user_data); + if (!cdm_instance) + return NULL; + + return new CdmWrapperImpl<CdmInterface, CdmInterfaceVersion>( + static_cast<CdmInterface*>(cdm_instance)); + } + + virtual ~CdmWrapperImpl() { + cdm_->Destroy(); + } + + virtual cdm::Status GenerateKeyRequest(const char* type, + int type_size, + const uint8_t* init_data, + int init_data_size) OVERRIDE { + return cdm_->GenerateKeyRequest(type, type_size, init_data, init_data_size); + } + + virtual cdm::Status AddKey(const char* session_id, + int session_id_size, + const uint8_t* key, + int key_size, + const uint8_t* key_id, + int key_id_size) OVERRIDE { + return cdm_->AddKey( + session_id, session_id_size, key, key_size, key_id, key_id_size); + } + + virtual cdm::Status CancelKeyRequest(const char* session_id, + int session_id_size) OVERRIDE { + return cdm_->CancelKeyRequest(session_id, session_id_size); + } + + virtual void TimerExpired(void* context) OVERRIDE { + cdm_->TimerExpired(context); + } + + virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer, + cdm::DecryptedBlock* decrypted_buffer) OVERRIDE { + return cdm_->Decrypt(encrypted_buffer, decrypted_buffer); + } + + virtual cdm::Status InitializeAudioDecoder( + const cdm::AudioDecoderConfig& audio_decoder_config) OVERRIDE { + return cdm_->InitializeAudioDecoder(audio_decoder_config); + } + + virtual cdm::Status InitializeVideoDecoder( + const cdm::VideoDecoderConfig& video_decoder_config) OVERRIDE { + return cdm_->InitializeVideoDecoder(video_decoder_config); + } + + virtual void DeinitializeDecoder(cdm::StreamType decoder_type) OVERRIDE { + cdm_->DeinitializeDecoder(decoder_type); + } + + virtual void ResetDecoder(cdm::StreamType decoder_type) OVERRIDE { + cdm_->ResetDecoder(decoder_type); + } + + virtual cdm::Status DecryptAndDecodeFrame( + const cdm::InputBuffer& encrypted_buffer, + cdm::VideoFrame* video_frame) OVERRIDE { + return cdm_->DecryptAndDecodeFrame(encrypted_buffer, video_frame); + } + + virtual cdm::Status DecryptAndDecodeSamples( + const cdm::InputBuffer& encrypted_buffer, + cdm::AudioFrames* audio_frames) OVERRIDE { + return cdm_->DecryptAndDecodeSamples(encrypted_buffer, audio_frames); + } + + private: + CdmWrapperImpl(CdmInterface* cdm) : cdm_(cdm) { + PP_DCHECK(cdm_); + } + + CdmInterface* cdm_; + + DISALLOW_COPY_AND_ASSIGN(CdmWrapperImpl); +}; + +// Specializations for old ContentDecryptionModule interfaces. +// For example: + +// template <> cdm::Status CdmAdapterImpl<cdm::ContentDecryptionModule_1>:: +// DecryptAndDecodeSamples(const cdm::InputBuffer& encrypted_buffer, +// cdm::AudioFrames* audio_frames) { +// AudioFramesImpl audio_frames_1; +// cdm::Status status = +// cdm_->DecryptAndDecodeSamples(encrypted_buffer, &audio_frames_1); +// if (status != cdm::kSuccess) +// return status; +// +// audio_frames->SetFrameBuffer(audio_frames_1.PassFrameBuffer()); +// audio_frames->SetFormat(cdm::kAudioFormatS16); +// return cdm::kSuccess; +// } + +CdmWrapper* CdmWrapper::Create(const char* key_system, + int key_system_size, + GetCdmHostFunc get_cdm_host_func, + void* user_data) { + // Try to create the CDM using the latest CDM interface version. + CdmWrapper* cdm_wrapper = + CdmWrapperImpl<cdm::ContentDecryptionModule, cdm::kCdmInterfaceVersion>:: + Create(key_system, key_system_size, get_cdm_host_func, user_data); + + // Try to see if the CDM supports older version(s) of CDM interface(s). + // For example: + // + // if (cdm_wrapper) + // return cdm_wrapper; + // + // cdm_wrapper = CdmWrapperImpl<cdm::ContentDecryptionModule_1>::Create( + // key_system, key_system_size, get_cdm_host_func, user_data); + + return cdm_wrapper; +} + +} // namespace media + +#endif // MEDIA_CDM_PPAPI_CDM_WRAPPER_H_ diff --git a/media/cdm/ppapi/linked_ptr.h b/media/cdm/ppapi/linked_ptr.h index f3eccbb..1e47a03 100644 --- a/media/cdm/ppapi/linked_ptr.h +++ b/media/cdm/ppapi/linked_ptr.h @@ -115,6 +115,7 @@ class linked_ptr { capture(ptr); } T* get() const { return value_; } + operator T*() const { return value_; } T* operator->() const { return value_; } T& operator*() const { return *value_; } // Release ownership of the pointed object and returns it. |