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_
12 #include "base/basictypes.h"
13 #include "media/cdm/ppapi/api/content_decryption_module.h"
14 #include "media/cdm/ppapi/cdm_helpers.h"
15 #include "media/cdm/ppapi/supported_cdm_versions.h"
16 #include "ppapi/cpp/logging.h"
20 // CdmWrapper wraps different versions of ContentDecryptionModule interfaces and
21 // exposes a common interface to the caller.
23 // The caller should call CdmWrapper::Create() to create a CDM instance.
24 // CdmWrapper will first try to create a CDM instance that supports the latest
25 // CDM interface (ContentDecryptionModule). If such an instance cannot be
26 // created (e.g. an older CDM was loaded), CdmWrapper will try to create a CDM
27 // that supports an older version of CDM interface (e.g.
28 // ContentDecryptionModule_*). Internally CdmWrapper converts the CdmWrapper
29 // calls to corresponding ContentDecryptionModule calls.
31 // Note that CdmWrapper interface always reflects the latest state of content
32 // decryption related PPAPI APIs (e.g. pp::ContentDecryptor_Private).
34 // Since this file is highly templated and default implementations are short
35 // (just a shim layer in most cases), everything is done in this header file.
38 static CdmWrapper
* Create(const char* key_system
,
39 uint32_t key_system_size
,
40 GetCdmHostFunc get_cdm_host_func
,
43 virtual ~CdmWrapper() {};
45 virtual void Initialize(bool allow_distinctive_identifier
,
46 bool allow_persistent_state
) = 0;
47 virtual void SetServerCertificate(uint32_t promise_id
,
48 const uint8_t* server_certificate_data
,
49 uint32_t server_certificate_data_size
) = 0;
50 virtual void CreateSessionAndGenerateRequest(uint32_t promise_id
,
51 cdm::SessionType session_type
,
52 cdm::InitDataType init_data_type
,
53 const uint8_t* init_data
,
54 uint32_t init_data_size
) = 0;
55 virtual void LoadSession(uint32_t promise_id
,
56 cdm::SessionType session_type
,
57 const char* session_id
,
58 uint32_t session_id_size
) = 0;
59 virtual void UpdateSession(uint32_t promise_id
,
60 const char* session_id
,
61 uint32_t session_id_size
,
62 const uint8_t* response
,
63 uint32_t response_size
) = 0;
64 virtual void CloseSession(uint32_t promise_id
,
65 const char* session_id
,
66 uint32_t session_id_size
) = 0;
67 virtual void RemoveSession(uint32_t promise_id
,
68 const char* session_id
,
69 uint32_t session_id_size
) = 0;
70 virtual void TimerExpired(void* context
) = 0;
71 virtual cdm::Status
Decrypt(const cdm::InputBuffer
& encrypted_buffer
,
72 cdm::DecryptedBlock
* decrypted_buffer
) = 0;
73 virtual cdm::Status
InitializeAudioDecoder(
74 const cdm::AudioDecoderConfig
& audio_decoder_config
) = 0;
75 virtual cdm::Status
InitializeVideoDecoder(
76 const cdm::VideoDecoderConfig
& video_decoder_config
) = 0;
77 virtual void DeinitializeDecoder(cdm::StreamType decoder_type
) = 0;
78 virtual void ResetDecoder(cdm::StreamType decoder_type
) = 0;
79 virtual cdm::Status
DecryptAndDecodeFrame(
80 const cdm::InputBuffer
& encrypted_buffer
,
81 cdm::VideoFrame
* video_frame
) = 0;
82 virtual cdm::Status
DecryptAndDecodeSamples(
83 const cdm::InputBuffer
& encrypted_buffer
,
84 cdm::AudioFrames
* audio_frames
) = 0;
85 virtual void OnPlatformChallengeResponse(
86 const cdm::PlatformChallengeResponse
& response
) = 0;
87 virtual void OnQueryOutputProtectionStatus(
88 cdm::QueryResult result
,
90 uint32_t output_protection_mask
) = 0;
96 DISALLOW_COPY_AND_ASSIGN(CdmWrapper
);
99 // Template class that does the CdmWrapper -> CdmInterface conversion. Default
100 // implementations are provided. Any methods that need special treatment should
102 template <class CdmInterface
>
103 class CdmWrapperImpl
: public CdmWrapper
{
105 static CdmWrapper
* Create(const char* key_system
,
106 uint32_t key_system_size
,
107 GetCdmHostFunc get_cdm_host_func
,
109 void* cdm_instance
= ::CreateCdmInstance(
110 CdmInterface::kVersion
, key_system
, key_system_size
, get_cdm_host_func
,
115 return new CdmWrapperImpl
<CdmInterface
>(
116 static_cast<CdmInterface
*>(cdm_instance
));
119 ~CdmWrapperImpl() override
{
123 void Initialize(bool allow_distinctive_identifier
,
124 bool allow_persistent_state
) override
{
125 cdm_
->Initialize(allow_distinctive_identifier
, allow_persistent_state
);
128 void SetServerCertificate(
130 const uint8_t* server_certificate_data
,
131 uint32_t server_certificate_data_size
) override
{
132 cdm_
->SetServerCertificate(
133 promise_id
, server_certificate_data
, server_certificate_data_size
);
136 void CreateSessionAndGenerateRequest(
138 cdm::SessionType session_type
,
139 cdm::InitDataType init_data_type
,
140 const uint8_t* init_data
,
141 uint32_t init_data_size
) override
{
142 cdm_
->CreateSessionAndGenerateRequest(
143 promise_id
, session_type
, init_data_type
, init_data
, init_data_size
);
146 void LoadSession(uint32_t promise_id
,
147 cdm::SessionType session_type
,
148 const char* session_id
,
149 uint32_t session_id_size
) override
{
150 cdm_
->LoadSession(promise_id
, session_type
, session_id
, session_id_size
);
153 void UpdateSession(uint32_t promise_id
,
154 const char* session_id
,
155 uint32_t session_id_size
,
156 const uint8_t* response
,
157 uint32_t response_size
) override
{
158 cdm_
->UpdateSession(promise_id
, session_id
, session_id_size
, response
,
162 void CloseSession(uint32_t promise_id
,
163 const char* session_id
,
164 uint32_t session_id_size
) override
{
165 cdm_
->CloseSession(promise_id
, session_id
, session_id_size
);
168 void RemoveSession(uint32_t promise_id
,
169 const char* session_id
,
170 uint32_t session_id_size
) override
{
171 cdm_
->RemoveSession(promise_id
, session_id
, session_id_size
);
174 void TimerExpired(void* context
) override
{
175 cdm_
->TimerExpired(context
);
178 cdm::Status
Decrypt(const cdm::InputBuffer
& encrypted_buffer
,
179 cdm::DecryptedBlock
* decrypted_buffer
) override
{
180 return cdm_
->Decrypt(encrypted_buffer
, decrypted_buffer
);
183 cdm::Status
InitializeAudioDecoder(
184 const cdm::AudioDecoderConfig
& audio_decoder_config
) override
{
185 return cdm_
->InitializeAudioDecoder(audio_decoder_config
);
188 cdm::Status
InitializeVideoDecoder(
189 const cdm::VideoDecoderConfig
& video_decoder_config
) override
{
190 return cdm_
->InitializeVideoDecoder(video_decoder_config
);
193 void DeinitializeDecoder(cdm::StreamType decoder_type
) override
{
194 cdm_
->DeinitializeDecoder(decoder_type
);
197 void ResetDecoder(cdm::StreamType decoder_type
) override
{
198 cdm_
->ResetDecoder(decoder_type
);
201 cdm::Status
DecryptAndDecodeFrame(
202 const cdm::InputBuffer
& encrypted_buffer
,
203 cdm::VideoFrame
* video_frame
) override
{
204 return cdm_
->DecryptAndDecodeFrame(encrypted_buffer
, video_frame
);
207 cdm::Status
DecryptAndDecodeSamples(
208 const cdm::InputBuffer
& encrypted_buffer
,
209 cdm::AudioFrames
* audio_frames
) override
{
210 return cdm_
->DecryptAndDecodeSamples(encrypted_buffer
, audio_frames
);
213 void OnPlatformChallengeResponse(
214 const cdm::PlatformChallengeResponse
& response
) override
{
215 cdm_
->OnPlatformChallengeResponse(response
);
218 void OnQueryOutputProtectionStatus(
219 cdm::QueryResult result
,
221 uint32_t output_protection_mask
) override
{
222 cdm_
->OnQueryOutputProtectionStatus(result
, link_mask
,
223 output_protection_mask
);
227 CdmWrapperImpl(CdmInterface
* cdm
) : cdm_(cdm
) {
233 DISALLOW_COPY_AND_ASSIGN(CdmWrapperImpl
);
236 // Overrides for the cdm::Host_7 methods.
237 // TODO(jrummell): Remove these once Host_7 interface is removed.
240 void CdmWrapperImpl
<cdm::ContentDecryptionModule_7
>::Initialize(
241 bool allow_distinctive_identifier
,
242 bool allow_persistent_state
) {
246 void CdmWrapperImpl
<cdm::ContentDecryptionModule_7
>::
247 CreateSessionAndGenerateRequest(uint32_t promise_id
,
248 cdm::SessionType session_type
,
249 cdm::InitDataType init_data_type
,
250 const uint8_t* init_data
,
251 uint32_t init_data_size
) {
252 std::string init_data_type_as_string
= "unknown";
253 switch (init_data_type
) {
255 init_data_type_as_string
= "cenc";
258 init_data_type_as_string
= "keyids";
261 init_data_type_as_string
= "webm";
265 cdm_
->CreateSessionAndGenerateRequest(
266 promise_id
, session_type
, &init_data_type_as_string
[0],
267 init_data_type_as_string
.length(), init_data
, init_data_size
);
270 CdmWrapper
* CdmWrapper::Create(const char* key_system
,
271 uint32_t key_system_size
,
272 GetCdmHostFunc get_cdm_host_func
,
274 static_assert(cdm::ContentDecryptionModule::kVersion
==
275 cdm::ContentDecryptionModule_8::kVersion
,
276 "update the code below");
278 // Ensure IsSupportedCdmInterfaceVersion() matches this implementation.
279 // Always update this DCHECK when updating this function.
280 // If this check fails, update this function and DCHECK or update
281 // IsSupportedCdmInterfaceVersion().
282 PP_DCHECK(!IsSupportedCdmInterfaceVersion(
283 cdm::ContentDecryptionModule_8::kVersion
+ 1) &&
284 IsSupportedCdmInterfaceVersion(
285 cdm::ContentDecryptionModule_8::kVersion
) &&
286 IsSupportedCdmInterfaceVersion(
287 cdm::ContentDecryptionModule_7::kVersion
) &&
288 !IsSupportedCdmInterfaceVersion(
289 cdm::ContentDecryptionModule_7::kVersion
- 1));
291 // Try to create the CDM using the latest CDM interface version.
292 CdmWrapper
* cdm_wrapper
=
293 CdmWrapperImpl
<cdm::ContentDecryptionModule
>::Create(
294 key_system
, key_system_size
, get_cdm_host_func
, user_data
);
296 // If |cdm_wrapper| is NULL, try to create the CDM using older supported
297 // versions of the CDM interface here.
299 cdm_wrapper
= CdmWrapperImpl
<cdm::ContentDecryptionModule_7
>::Create(
300 key_system
, key_system_size
, get_cdm_host_func
, user_data
);
306 // When updating the CdmAdapter, ensure you've updated the CdmWrapper to contain
307 // stub implementations for new or modified methods that the older CDM interface
309 // Also update supported_cdm_versions.h.
310 static_assert(cdm::ContentDecryptionModule::kVersion
==
311 cdm::ContentDecryptionModule_8::kVersion
,
312 "ensure cdm wrapper templates have old version support");
316 #endif // MEDIA_CDM_PPAPI_CDM_WRAPPER_H_