Index: media/cdm/ppapi/cdm_adapter.h |
diff --git a/media/cdm/ppapi/cdm_adapter.h b/media/cdm/ppapi/cdm_adapter.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9a7063617b3eb08df8a3af2e4b08f46429d98692 |
--- /dev/null |
+++ b/media/cdm/ppapi/cdm_adapter.h |
@@ -0,0 +1,232 @@ |
+// 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_ADAPTER_H_ |
+#define MEDIA_CDM_PPAPI_CDM_ADAPTER_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 { |
+ |
+// CdmAdapter wraps different versions of ContentDecryptionModule interfaces and |
+// exposes a common interface to the caller. |
+// |
+// The caller should call CdmAdapter::Create() to create a CDM instance. |
+// CdmAdapter will first try to create a CDM instance that supports the latest |
+// CDM interface (i.e. ContentDecryptionModule). If such an instance cannot be |
+// created (e.g. an older CDM was loaded), CdmAdapter will try to create a CDM |
+// that supports an older version of CDM interface (e.g. |
+// ContentDecryptionModule_*). Internally CdmAdapter converts the CdmAdapter |
+// calls to corresponding ContentDecryptionModule calls. |
+// |
+// Note that CdmAdapter 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 CdmAdapter { |
+ public: |
+ static CdmAdapter* Create(const char* key_system, |
+ int key_system_size, |
+ GetCdmHostFunc get_cdm_host_func, |
+ void* user_data); |
+ |
+ virtual ~CdmAdapter() {}; |
+ |
+ 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; |
+ virtual void OnPlatformChallengeResponse( |
+ const cdm::PlatformChallengeResponse& response) = 0; |
+ virtual void OnQueryOutputProtectionStatus( |
+ uint32_t link_mask, |
+ uint32_t output_protection_mask) = 0; |
+ |
+ protected: |
+ CdmAdapter() {}; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(CdmAdapter); |
+}; |
+ |
+// Template class that does the CdmAdapter -> CdmType conversion. Default |
+// implementations are provided. Any methods that need special treatment should |
+// be specialized. |
+template <class CdmType> |
+class CdmAdapterImpl : public CdmAdapter { |
+ public: |
+ static CdmAdapter* Create(const char* key_system, |
+ int key_system_size, |
+ GetCdmHostFunc get_cdm_host_func, |
+ void* user_data) { |
+ void* cdm_instance = CreateCdmInstance(CdmType::kVersion, |
+ key_system, key_system_size, get_cdm_host_func, user_data); |
+ if (!cdm_instance) |
+ return NULL; |
+ |
+ return new CdmAdapterImpl<CdmType>(static_cast<CdmType*>(cdm_instance)); |
+ } |
+ |
+ virtual ~CdmAdapterImpl() { |
+ if (cdm_) |
+ 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); |
+ } |
+ |
+ virtual void OnPlatformChallengeResponse( |
+ const cdm::PlatformChallengeResponse& response) OVERRIDE { |
+ cdm_->OnPlatformChallengeResponse(response); |
+ } |
+ |
+ virtual void OnQueryOutputProtectionStatus( |
+ uint32_t link_mask, |
+ uint32_t output_protection_mask) OVERRIDE { |
+ cdm_->OnQueryOutputProtectionStatus(link_mask, output_protection_mask); |
+ } |
+ |
+ private: |
+ CdmAdapterImpl(CdmType* cdm) : cdm_(cdm) { |
+ PP_DCHECK(cdm_); |
+ } |
+ |
+ CdmType* cdm_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CdmAdapterImpl); |
+}; |
+ |
+// Specializations for ContentDecryptionModule_1. |
+ |
+template <> void CdmAdapterImpl<cdm::ContentDecryptionModule_1>:: |
+ OnPlatformChallengeResponse( |
+ const cdm::PlatformChallengeResponse& response) { |
+ PP_NOTREACHED(); |
+} |
+ |
+template <> void CdmAdapterImpl<cdm::ContentDecryptionModule_1>:: |
+ OnQueryOutputProtectionStatus(uint32_t link_mask, |
+ uint32_t output_protection_mask) { |
+ PP_NOTREACHED(); |
+} |
+ |
+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; |
+} |
+ |
+CdmAdapter* CdmAdapter::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. |
+ CdmAdapter* cdm_adapter = |
+ CdmAdapterImpl<cdm::ContentDecryptionModule>::Create( |
+ key_system, key_system_size, get_cdm_host_func, user_data); |
+ if (cdm_adapter) |
+ return cdm_adapter; |
+ |
+ // Try to see if the CDM supports older version(s) of CDM interface(s). |
+ cdm_adapter = CdmAdapterImpl<cdm::ContentDecryptionModule_1>::Create( |
+ key_system, key_system_size, get_cdm_host_func, user_data); |
+ return cdm_adapter; |
+} |
+ |
+} // namespace media |
+ |
+#endif // MEDIA_CDM_PPAPI_CDM_ADAPTER_H_ |