1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef MEDIA_CDM_PPAPI_CDM_WRAPPER_H_
6 #define MEDIA_CDM_PPAPI_CDM_WRAPPER_H_
8 #include "base/basictypes.h"
9 #include "media/cdm/ppapi/api/content_decryption_module.h"
10 #include "media/cdm/ppapi/cdm_helpers.h"
11 #include "media/cdm/ppapi/supported_cdm_versions.h"
12 #include "ppapi/cpp/logging.h"
16 // CdmWrapper wraps different versions of ContentDecryptionModule interfaces and
17 // exposes a common interface to the caller.
19 // The caller should call CdmWrapper::Create() to create a CDM instance.
20 // CdmWrapper will first try to create a CDM instance that supports the latest
21 // CDM interface (ContentDecryptionModule). If such an instance cannot be
22 // created (e.g. an older CDM was loaded), CdmWrapper will try to create a CDM
23 // that supports an older version of CDM interface (e.g.
24 // ContentDecryptionModule_*). Internally CdmWrapper converts the CdmWrapper
25 // calls to corresponding ContentDecryptionModule calls.
27 // Note that CdmWrapper interface always reflects the latest state of content
28 // decryption related PPAPI APIs (e.g. pp::ContentDecryptor_Private).
30 // Since this file is highly templated and default implementations are short
31 // (just a shim layer in most cases), everything is done in this header file.
34 static CdmWrapper* Create(const char* key_system,
35 uint32_t key_system_size,
36 GetCdmHostFunc get_cdm_host_func,
39 virtual ~CdmWrapper() {};
41 virtual cdm::Status GenerateKeyRequest(const char* type,
43 const uint8_t* init_data,
44 uint32_t init_data_size) = 0;
45 virtual cdm::Status AddKey(const char* session_id,
46 uint32_t session_id_size,
49 const uint8_t* key_id,
50 uint32_t key_id_size) = 0;
51 virtual cdm::Status CancelKeyRequest(const char* session_id,
52 uint32_t session_id_size) = 0;
53 virtual void TimerExpired(void* context) = 0;
54 virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer,
55 cdm::DecryptedBlock* decrypted_buffer) = 0;
56 virtual cdm::Status InitializeAudioDecoder(
57 const cdm::AudioDecoderConfig& audio_decoder_config) = 0;
58 virtual cdm::Status InitializeVideoDecoder(
59 const cdm::VideoDecoderConfig& video_decoder_config) = 0;
60 virtual void DeinitializeDecoder(cdm::StreamType decoder_type) = 0;
61 virtual void ResetDecoder(cdm::StreamType decoder_type) = 0;
62 virtual cdm::Status DecryptAndDecodeFrame(
63 const cdm::InputBuffer& encrypted_buffer,
64 cdm::VideoFrame* video_frame) = 0;
65 virtual cdm::Status DecryptAndDecodeSamples(
66 const cdm::InputBuffer& encrypted_buffer,
67 cdm::AudioFrames* audio_frames) = 0;
68 virtual void OnPlatformChallengeResponse(
69 const cdm::PlatformChallengeResponse& response) = 0;
70 virtual void OnQueryOutputProtectionStatus(
72 uint32_t output_protection_mask) = 0;
78 DISALLOW_COPY_AND_ASSIGN(CdmWrapper);
81 // Template class that does the CdmWrapper -> CdmInterface conversion. Default
82 // implementations are provided. Any methods that need special treatment should
84 template <class CdmInterface>
85 class CdmWrapperImpl : public CdmWrapper {
87 static CdmWrapper* Create(const char* key_system,
88 uint32_t key_system_size,
89 GetCdmHostFunc get_cdm_host_func,
91 void* cdm_instance = ::CreateCdmInstance(
92 CdmInterface::kVersion, key_system, key_system_size, get_cdm_host_func,
97 return new CdmWrapperImpl<CdmInterface>(
98 static_cast<CdmInterface*>(cdm_instance));
101 virtual ~CdmWrapperImpl() {
105 virtual cdm::Status GenerateKeyRequest(const char* type,
107 const uint8_t* init_data,
108 uint32_t init_data_size) OVERRIDE {
109 return cdm_->GenerateKeyRequest(type, type_size, init_data, init_data_size);
112 virtual cdm::Status AddKey(const char* session_id,
113 uint32_t session_id_size,
116 const uint8_t* key_id,
117 uint32_t key_id_size) OVERRIDE {
119 session_id, session_id_size, key, key_size, key_id, key_id_size);
122 virtual cdm::Status CancelKeyRequest(const char* session_id,
123 uint32_t session_id_size) OVERRIDE {
124 return cdm_->CancelKeyRequest(session_id, session_id_size);
127 virtual void TimerExpired(void* context) OVERRIDE {
128 cdm_->TimerExpired(context);
131 virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer,
132 cdm::DecryptedBlock* decrypted_buffer) OVERRIDE {
133 return cdm_->Decrypt(encrypted_buffer, decrypted_buffer);
136 virtual cdm::Status InitializeAudioDecoder(
137 const cdm::AudioDecoderConfig& audio_decoder_config) OVERRIDE {
138 return cdm_->InitializeAudioDecoder(audio_decoder_config);
141 virtual cdm::Status InitializeVideoDecoder(
142 const cdm::VideoDecoderConfig& video_decoder_config) OVERRIDE {
143 return cdm_->InitializeVideoDecoder(video_decoder_config);
146 virtual void DeinitializeDecoder(cdm::StreamType decoder_type) OVERRIDE {
147 cdm_->DeinitializeDecoder(decoder_type);
150 virtual void ResetDecoder(cdm::StreamType decoder_type) OVERRIDE {
151 cdm_->ResetDecoder(decoder_type);
154 virtual cdm::Status DecryptAndDecodeFrame(
155 const cdm::InputBuffer& encrypted_buffer,
156 cdm::VideoFrame* video_frame) OVERRIDE {
157 return cdm_->DecryptAndDecodeFrame(encrypted_buffer, video_frame);
160 virtual cdm::Status DecryptAndDecodeSamples(
161 const cdm::InputBuffer& encrypted_buffer,
162 cdm::AudioFrames* audio_frames) OVERRIDE {
163 return cdm_->DecryptAndDecodeSamples(encrypted_buffer, audio_frames);
166 virtual void OnPlatformChallengeResponse(
167 const cdm::PlatformChallengeResponse& response) OVERRIDE {
168 cdm_->OnPlatformChallengeResponse(response);
171 virtual void OnQueryOutputProtectionStatus(
173 uint32_t output_protection_mask) OVERRIDE {
174 cdm_->OnQueryOutputProtectionStatus(link_mask, output_protection_mask);
178 CdmWrapperImpl(CdmInterface* cdm) : cdm_(cdm) {
184 DISALLOW_COPY_AND_ASSIGN(CdmWrapperImpl);
187 // Specializations for ContentDecryptionModule_1.
189 template <> void CdmWrapperImpl<cdm::ContentDecryptionModule_1>::
190 OnPlatformChallengeResponse(
191 const cdm::PlatformChallengeResponse& response) {
195 template <> void CdmWrapperImpl<cdm::ContentDecryptionModule_1>::
196 OnQueryOutputProtectionStatus(uint32_t link_mask,
197 uint32_t output_protection_mask) {
201 template <> cdm::Status CdmWrapperImpl<cdm::ContentDecryptionModule_1>::
202 DecryptAndDecodeSamples(const cdm::InputBuffer& encrypted_buffer,
203 cdm::AudioFrames* audio_frames) {
204 AudioFramesImpl audio_frames_1;
206 cdm_->DecryptAndDecodeSamples(encrypted_buffer, &audio_frames_1);
207 if (status != cdm::kSuccess)
210 audio_frames->SetFrameBuffer(audio_frames_1.PassFrameBuffer());
211 audio_frames->SetFormat(cdm::kAudioFormatS16);
212 return cdm::kSuccess;
215 CdmWrapper* CdmWrapper::Create(const char* key_system,
216 uint32_t key_system_size,
217 GetCdmHostFunc get_cdm_host_func,
219 COMPILE_ASSERT(cdm::ContentDecryptionModule::kVersion ==
220 cdm::ContentDecryptionModule_2::kVersion,
223 // Ensure IsSupportedCdmInterfaceVersion matches this implementation.
224 // Always update this DCHECK when updating this function.
225 // If this check fails, update this function and DCHECK or update
226 // IsSupportedCdmInterfaceVersion.
228 !IsSupportedCdmInterfaceVersion(
229 cdm::ContentDecryptionModule::kVersion + 1) &&
230 IsSupportedCdmInterfaceVersion(cdm::ContentDecryptionModule::kVersion) &&
231 IsSupportedCdmInterfaceVersion(
232 cdm::ContentDecryptionModule_1::kVersion) &&
233 !IsSupportedCdmInterfaceVersion(
234 cdm::ContentDecryptionModule_1::kVersion - 1));
236 // Try to create the CDM using the latest CDM interface version.
237 CdmWrapper* cdm_wrapper =
238 CdmWrapperImpl<cdm::ContentDecryptionModule>::Create(
239 key_system, key_system_size, get_cdm_host_func, user_data);
243 // Try to see if the CDM supports older version(s) of the CDM interface.
244 cdm_wrapper = CdmWrapperImpl<cdm::ContentDecryptionModule_1>::Create(
245 key_system, key_system_size, get_cdm_host_func, user_data);
249 // When updating the CdmAdapter, ensure you've updated the CdmWrapper to contain
250 // stub implementations for new or modified methods that the older CDM interface
252 // Also update supported_cdm_versions.h.
253 COMPILE_ASSERT(cdm::ContentDecryptionModule::kVersion ==
254 cdm::ContentDecryptionModule_2::kVersion,
255 ensure_cdm_wrapper_templates_have_old_version_support);
259 #endif // MEDIA_CDM_PPAPI_CDM_WRAPPER_H_