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 "ppapi/cpp/logging.h"
15 // CdmWrapper wraps different versions of ContentDecryptionModule interfaces and
16 // exposes a common interface to the caller.
18 // The caller should call CdmWrapper::Create() to create a CDM instance.
19 // CdmWrapper will first try to create a CDM instance that supports the latest
20 // CDM interface (ContentDecryptionModule). If such an instance cannot be
21 // created (e.g. an older CDM was loaded), CdmWrapper will try to create a CDM
22 // that supports an older version of CDM interface (e.g.
23 // ContentDecryptionModule_*). Internally CdmWrapper converts the CdmWrapper
24 // calls to corresponding ContentDecryptionModule calls.
26 // Note that CdmWrapper interface always reflects the latest state of content
27 // decryption related PPAPI APIs (e.g. pp::ContentDecryptor_Private).
29 // Since this file is highly templated and default implementations are short
30 // (just a shim layer in most cases), everything is done in this header file.
33 static CdmWrapper
* Create(const char* key_system
,
34 uint32_t key_system_size
,
35 GetCdmHostFunc get_cdm_host_func
,
38 virtual ~CdmWrapper() {};
40 virtual cdm::Status
GenerateKeyRequest(const char* type
,
42 const uint8_t* init_data
,
43 uint32_t init_data_size
) = 0;
44 virtual cdm::Status
AddKey(const char* session_id
,
45 uint32_t session_id_size
,
48 const uint8_t* key_id
,
49 uint32_t key_id_size
) = 0;
50 virtual cdm::Status
CancelKeyRequest(const char* session_id
,
51 uint32_t session_id_size
) = 0;
52 virtual void TimerExpired(void* context
) = 0;
53 virtual cdm::Status
Decrypt(const cdm::InputBuffer
& encrypted_buffer
,
54 cdm::DecryptedBlock
* decrypted_buffer
) = 0;
55 virtual cdm::Status
InitializeAudioDecoder(
56 const cdm::AudioDecoderConfig
& audio_decoder_config
) = 0;
57 virtual cdm::Status
InitializeVideoDecoder(
58 const cdm::VideoDecoderConfig
& video_decoder_config
) = 0;
59 virtual void DeinitializeDecoder(cdm::StreamType decoder_type
) = 0;
60 virtual void ResetDecoder(cdm::StreamType decoder_type
) = 0;
61 virtual cdm::Status
DecryptAndDecodeFrame(
62 const cdm::InputBuffer
& encrypted_buffer
,
63 cdm::VideoFrame
* video_frame
) = 0;
64 virtual cdm::Status
DecryptAndDecodeSamples(
65 const cdm::InputBuffer
& encrypted_buffer
,
66 cdm::AudioFrames
* audio_frames
) = 0;
67 virtual void OnPlatformChallengeResponse(
68 const cdm::PlatformChallengeResponse
& response
) = 0;
69 virtual void OnQueryOutputProtectionStatus(
71 uint32_t output_protection_mask
) = 0;
77 DISALLOW_COPY_AND_ASSIGN(CdmWrapper
);
80 // Template class that does the CdmWrapper -> CdmInterface conversion. Default
81 // implementations are provided. Any methods that need special treatment should
83 template <class CdmInterface
>
84 class CdmWrapperImpl
: public CdmWrapper
{
86 static CdmWrapper
* Create(const char* key_system
,
87 uint32_t key_system_size
,
88 GetCdmHostFunc get_cdm_host_func
,
90 void* cdm_instance
= ::CreateCdmInstance(
91 CdmInterface::kVersion
, key_system
, key_system_size
, get_cdm_host_func
,
96 return new CdmWrapperImpl
<CdmInterface
>(
97 static_cast<CdmInterface
*>(cdm_instance
));
100 virtual ~CdmWrapperImpl() {
104 virtual cdm::Status
GenerateKeyRequest(const char* type
,
106 const uint8_t* init_data
,
107 uint32_t init_data_size
) OVERRIDE
{
108 return cdm_
->GenerateKeyRequest(type
, type_size
, init_data
, init_data_size
);
111 virtual cdm::Status
AddKey(const char* session_id
,
112 uint32_t session_id_size
,
115 const uint8_t* key_id
,
116 uint32_t key_id_size
) OVERRIDE
{
118 session_id
, session_id_size
, key
, key_size
, key_id
, key_id_size
);
121 virtual cdm::Status
CancelKeyRequest(const char* session_id
,
122 uint32_t session_id_size
) OVERRIDE
{
123 return cdm_
->CancelKeyRequest(session_id
, session_id_size
);
126 virtual void TimerExpired(void* context
) OVERRIDE
{
127 cdm_
->TimerExpired(context
);
130 virtual cdm::Status
Decrypt(const cdm::InputBuffer
& encrypted_buffer
,
131 cdm::DecryptedBlock
* decrypted_buffer
) OVERRIDE
{
132 return cdm_
->Decrypt(encrypted_buffer
, decrypted_buffer
);
135 virtual cdm::Status
InitializeAudioDecoder(
136 const cdm::AudioDecoderConfig
& audio_decoder_config
) OVERRIDE
{
137 return cdm_
->InitializeAudioDecoder(audio_decoder_config
);
140 virtual cdm::Status
InitializeVideoDecoder(
141 const cdm::VideoDecoderConfig
& video_decoder_config
) OVERRIDE
{
142 return cdm_
->InitializeVideoDecoder(video_decoder_config
);
145 virtual void DeinitializeDecoder(cdm::StreamType decoder_type
) OVERRIDE
{
146 cdm_
->DeinitializeDecoder(decoder_type
);
149 virtual void ResetDecoder(cdm::StreamType decoder_type
) OVERRIDE
{
150 cdm_
->ResetDecoder(decoder_type
);
153 virtual cdm::Status
DecryptAndDecodeFrame(
154 const cdm::InputBuffer
& encrypted_buffer
,
155 cdm::VideoFrame
* video_frame
) OVERRIDE
{
156 return cdm_
->DecryptAndDecodeFrame(encrypted_buffer
, video_frame
);
159 virtual cdm::Status
DecryptAndDecodeSamples(
160 const cdm::InputBuffer
& encrypted_buffer
,
161 cdm::AudioFrames
* audio_frames
) OVERRIDE
{
162 return cdm_
->DecryptAndDecodeSamples(encrypted_buffer
, audio_frames
);
165 virtual void OnPlatformChallengeResponse(
166 const cdm::PlatformChallengeResponse
& response
) OVERRIDE
{
167 cdm_
->OnPlatformChallengeResponse(response
);
170 virtual void OnQueryOutputProtectionStatus(
172 uint32_t output_protection_mask
) OVERRIDE
{
173 cdm_
->OnQueryOutputProtectionStatus(link_mask
, output_protection_mask
);
177 CdmWrapperImpl(CdmInterface
* cdm
) : cdm_(cdm
) {
183 DISALLOW_COPY_AND_ASSIGN(CdmWrapperImpl
);
186 // Specializations for ContentDecryptionModule_1.
188 template <> void CdmWrapperImpl
<cdm::ContentDecryptionModule_1
>::
189 OnPlatformChallengeResponse(
190 const cdm::PlatformChallengeResponse
& response
) {
194 template <> void CdmWrapperImpl
<cdm::ContentDecryptionModule_1
>::
195 OnQueryOutputProtectionStatus(uint32_t link_mask
,
196 uint32_t output_protection_mask
) {
200 template <> cdm::Status CdmWrapperImpl
<cdm::ContentDecryptionModule_1
>::
201 DecryptAndDecodeSamples(const cdm::InputBuffer
& encrypted_buffer
,
202 cdm::AudioFrames
* audio_frames
) {
203 AudioFramesImpl audio_frames_1
;
205 cdm_
->DecryptAndDecodeSamples(encrypted_buffer
, &audio_frames_1
);
206 if (status
!= cdm::kSuccess
)
209 audio_frames
->SetFrameBuffer(audio_frames_1
.PassFrameBuffer());
210 audio_frames
->SetFormat(cdm::kAudioFormatS16
);
211 return cdm::kSuccess
;
214 CdmWrapper
* CdmWrapper::Create(const char* key_system
,
215 uint32_t key_system_size
,
216 GetCdmHostFunc get_cdm_host_func
,
218 // Try to create the CDM using the latest CDM interface version.
219 CdmWrapper
* cdm_adapter
=
220 CdmWrapperImpl
<cdm::ContentDecryptionModule
>::Create(
221 key_system
, key_system_size
, get_cdm_host_func
, user_data
);
225 // Try to see if the CDM supports older version(s) of CDM interface(s).
226 cdm_adapter
= CdmWrapperImpl
<cdm::ContentDecryptionModule_1
>::Create(
227 key_system
, key_system_size
, get_cdm_host_func
, user_data
);
231 // When updating the CdmAdapter, ensure you've updated the CdmWrapper to contain
232 // stub implementations for new or modified methods that the older CDM interface
234 COMPILE_ASSERT(cdm::ContentDecryptionModule::kVersion
==
235 cdm::ContentDecryptionModule_2::kVersion
,
236 ensure_cdm_wrapper_templates_have_old_version_support
);
240 #endif // MEDIA_CDM_PPAPI_CDM_WRAPPER_H_