- add sources.
[platform/framework/web/crosswalk.git] / src / media / cdm / ppapi / cdm_wrapper.h
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.
4
5 #ifndef MEDIA_CDM_PPAPI_CDM_WRAPPER_H_
6 #define MEDIA_CDM_PPAPI_CDM_WRAPPER_H_
7
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"
13
14 namespace media {
15
16 // CdmWrapper wraps different versions of ContentDecryptionModule interfaces and
17 // exposes a common interface to the caller.
18 //
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.
26 //
27 // Note that CdmWrapper interface always reflects the latest state of content
28 // decryption related PPAPI APIs (e.g. pp::ContentDecryptor_Private).
29 //
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.
32 class CdmWrapper {
33  public:
34   static CdmWrapper* Create(const char* key_system,
35                             uint32_t key_system_size,
36                             GetCdmHostFunc get_cdm_host_func,
37                             void* user_data);
38
39   virtual ~CdmWrapper() {};
40
41   virtual cdm::Status GenerateKeyRequest(const char* type,
42                                          uint32_t type_size,
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,
47                              const uint8_t* key,
48                              uint32_t key_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(
71       uint32_t link_mask,
72       uint32_t output_protection_mask) = 0;
73
74  protected:
75   CdmWrapper() {};
76
77  private:
78   DISALLOW_COPY_AND_ASSIGN(CdmWrapper);
79 };
80
81 // Template class that does the CdmWrapper -> CdmInterface conversion. Default
82 // implementations are provided. Any methods that need special treatment should
83 // be specialized.
84 template <class CdmInterface>
85 class CdmWrapperImpl : public CdmWrapper {
86  public:
87   static CdmWrapper* Create(const char* key_system,
88                             uint32_t key_system_size,
89                             GetCdmHostFunc get_cdm_host_func,
90                             void* user_data) {
91     void* cdm_instance = ::CreateCdmInstance(
92         CdmInterface::kVersion, key_system, key_system_size, get_cdm_host_func,
93         user_data);
94     if (!cdm_instance)
95       return NULL;
96
97     return new CdmWrapperImpl<CdmInterface>(
98         static_cast<CdmInterface*>(cdm_instance));
99   }
100
101   virtual ~CdmWrapperImpl() {
102     cdm_->Destroy();
103   }
104
105   virtual cdm::Status GenerateKeyRequest(const char* type,
106                                          uint32_t type_size,
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);
110   }
111
112   virtual cdm::Status AddKey(const char* session_id,
113                              uint32_t session_id_size,
114                              const uint8_t* key,
115                              uint32_t key_size,
116                              const uint8_t* key_id,
117                              uint32_t key_id_size) OVERRIDE {
118     return cdm_->AddKey(
119         session_id, session_id_size, key, key_size, key_id, key_id_size);
120   }
121
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);
125   }
126
127   virtual void TimerExpired(void* context) OVERRIDE {
128     cdm_->TimerExpired(context);
129   }
130
131   virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer,
132                               cdm::DecryptedBlock* decrypted_buffer) OVERRIDE {
133     return cdm_->Decrypt(encrypted_buffer, decrypted_buffer);
134   }
135
136   virtual cdm::Status InitializeAudioDecoder(
137       const cdm::AudioDecoderConfig& audio_decoder_config) OVERRIDE {
138     return cdm_->InitializeAudioDecoder(audio_decoder_config);
139   }
140
141   virtual cdm::Status InitializeVideoDecoder(
142       const cdm::VideoDecoderConfig& video_decoder_config) OVERRIDE {
143     return cdm_->InitializeVideoDecoder(video_decoder_config);
144   }
145
146   virtual void DeinitializeDecoder(cdm::StreamType decoder_type) OVERRIDE {
147     cdm_->DeinitializeDecoder(decoder_type);
148   }
149
150   virtual void ResetDecoder(cdm::StreamType decoder_type) OVERRIDE {
151     cdm_->ResetDecoder(decoder_type);
152   }
153
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);
158   }
159
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);
164   }
165
166   virtual void OnPlatformChallengeResponse(
167       const cdm::PlatformChallengeResponse& response) OVERRIDE {
168     cdm_->OnPlatformChallengeResponse(response);
169   }
170
171   virtual void OnQueryOutputProtectionStatus(
172       uint32_t link_mask,
173       uint32_t output_protection_mask) OVERRIDE {
174     cdm_->OnQueryOutputProtectionStatus(link_mask, output_protection_mask);
175   }
176
177  private:
178   CdmWrapperImpl(CdmInterface* cdm) : cdm_(cdm) {
179     PP_DCHECK(cdm_);
180   }
181
182   CdmInterface* cdm_;
183
184   DISALLOW_COPY_AND_ASSIGN(CdmWrapperImpl);
185 };
186
187 // Specializations for ContentDecryptionModule_1.
188
189 template <> void CdmWrapperImpl<cdm::ContentDecryptionModule_1>::
190     OnPlatformChallengeResponse(
191         const cdm::PlatformChallengeResponse& response) {
192   PP_NOTREACHED();
193 }
194
195 template <> void CdmWrapperImpl<cdm::ContentDecryptionModule_1>::
196     OnQueryOutputProtectionStatus(uint32_t link_mask,
197                                   uint32_t output_protection_mask) {
198   PP_NOTREACHED();
199 }
200
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;
205   cdm::Status status =
206       cdm_->DecryptAndDecodeSamples(encrypted_buffer, &audio_frames_1);
207   if (status != cdm::kSuccess)
208     return status;
209
210   audio_frames->SetFrameBuffer(audio_frames_1.PassFrameBuffer());
211   audio_frames->SetFormat(cdm::kAudioFormatS16);
212   return cdm::kSuccess;
213 }
214
215 CdmWrapper* CdmWrapper::Create(const char* key_system,
216                                uint32_t key_system_size,
217                                GetCdmHostFunc get_cdm_host_func,
218                                void* user_data) {
219   COMPILE_ASSERT(cdm::ContentDecryptionModule::kVersion ==
220                  cdm::ContentDecryptionModule_2::kVersion,
221                  update_code_below);
222
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.
227   PP_DCHECK(
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));
235
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);
240   if (cdm_wrapper)
241     return cdm_wrapper;
242
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);
246   return cdm_wrapper;
247 }
248
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
251 // does not have.
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);
256
257 }  // namespace media
258
259 #endif  // MEDIA_CDM_PPAPI_CDM_WRAPPER_H_