cdm_wrapper.h revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
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 "ppapi/cpp/logging.h" 12 13namespace media { 14 15// CdmWrapper wraps different versions of ContentDecryptionModule interfaces and 16// exposes a common interface to the caller. 17// 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. 25// 26// Note that CdmWrapper interface always reflects the latest state of content 27// decryption related PPAPI APIs (e.g. pp::ContentDecryptor_Private). 28// 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. 31class CdmWrapper { 32 public: 33 static CdmWrapper* Create(const char* key_system, 34 int key_system_size, 35 GetCdmHostFunc get_cdm_host_func, 36 void* user_data); 37 38 virtual ~CdmWrapper() {}; 39 40 virtual cdm::Status GenerateKeyRequest(const char* type, 41 int type_size, 42 const uint8_t* init_data, 43 int init_data_size) = 0; 44 virtual cdm::Status AddKey(const char* session_id, 45 int session_id_size, 46 const uint8_t* key, 47 int key_size, 48 const uint8_t* key_id, 49 int key_id_size) = 0; 50 virtual cdm::Status CancelKeyRequest(const char* session_id, 51 int 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( 70 uint32_t link_mask, 71 uint32_t output_protection_mask) = 0; 72 73 protected: 74 CdmWrapper() {}; 75 76 private: 77 DISALLOW_COPY_AND_ASSIGN(CdmWrapper); 78}; 79 80// Template class that does the CdmWrapper -> CdmInterface conversion. Default 81// implementations are provided. Any methods that need special treatment should 82// be specialized. 83template <class CdmInterface> 84class CdmWrapperImpl : public CdmWrapper { 85 public: 86 static CdmWrapper* Create(const char* key_system, 87 int key_system_size, 88 GetCdmHostFunc get_cdm_host_func, 89 void* user_data) { 90 void* cdm_instance = ::CreateCdmInstance( 91 CdmInterface::kVersion, key_system, key_system_size, get_cdm_host_func, 92 user_data); 93 if (!cdm_instance) 94 return NULL; 95 96 return new CdmWrapperImpl<CdmInterface>( 97 static_cast<CdmInterface*>(cdm_instance)); 98 } 99 100 virtual ~CdmWrapperImpl() { 101 cdm_->Destroy(); 102 } 103 104 virtual cdm::Status GenerateKeyRequest(const char* type, 105 int type_size, 106 const uint8_t* init_data, 107 int init_data_size) OVERRIDE { 108 return cdm_->GenerateKeyRequest(type, type_size, init_data, init_data_size); 109 } 110 111 virtual cdm::Status AddKey(const char* session_id, 112 int session_id_size, 113 const uint8_t* key, 114 int key_size, 115 const uint8_t* key_id, 116 int key_id_size) OVERRIDE { 117 return cdm_->AddKey( 118 session_id, session_id_size, key, key_size, key_id, key_id_size); 119 } 120 121 virtual cdm::Status CancelKeyRequest(const char* session_id, 122 int session_id_size) OVERRIDE { 123 return cdm_->CancelKeyRequest(session_id, session_id_size); 124 } 125 126 virtual void TimerExpired(void* context) OVERRIDE { 127 cdm_->TimerExpired(context); 128 } 129 130 virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer, 131 cdm::DecryptedBlock* decrypted_buffer) OVERRIDE { 132 return cdm_->Decrypt(encrypted_buffer, decrypted_buffer); 133 } 134 135 virtual cdm::Status InitializeAudioDecoder( 136 const cdm::AudioDecoderConfig& audio_decoder_config) OVERRIDE { 137 return cdm_->InitializeAudioDecoder(audio_decoder_config); 138 } 139 140 virtual cdm::Status InitializeVideoDecoder( 141 const cdm::VideoDecoderConfig& video_decoder_config) OVERRIDE { 142 return cdm_->InitializeVideoDecoder(video_decoder_config); 143 } 144 145 virtual void DeinitializeDecoder(cdm::StreamType decoder_type) OVERRIDE { 146 cdm_->DeinitializeDecoder(decoder_type); 147 } 148 149 virtual void ResetDecoder(cdm::StreamType decoder_type) OVERRIDE { 150 cdm_->ResetDecoder(decoder_type); 151 } 152 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); 157 } 158 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); 163 } 164 165 virtual void OnPlatformChallengeResponse( 166 const cdm::PlatformChallengeResponse& response) OVERRIDE { 167 cdm_->OnPlatformChallengeResponse(response); 168 } 169 170 virtual void OnQueryOutputProtectionStatus( 171 uint32_t link_mask, 172 uint32_t output_protection_mask) OVERRIDE { 173 cdm_->OnQueryOutputProtectionStatus(link_mask, output_protection_mask); 174 } 175 176 private: 177 CdmWrapperImpl(CdmInterface* cdm) : cdm_(cdm) { 178 PP_DCHECK(cdm_); 179 } 180 181 CdmInterface* cdm_; 182 183 DISALLOW_COPY_AND_ASSIGN(CdmWrapperImpl); 184}; 185 186// Specializations for ContentDecryptionModule_1. 187 188template <> void CdmWrapperImpl<cdm::ContentDecryptionModule_1>:: 189 OnPlatformChallengeResponse( 190 const cdm::PlatformChallengeResponse& response) { 191 PP_NOTREACHED(); 192} 193 194template <> void CdmWrapperImpl<cdm::ContentDecryptionModule_1>:: 195 OnQueryOutputProtectionStatus(uint32_t link_mask, 196 uint32_t output_protection_mask) { 197 PP_NOTREACHED(); 198} 199 200template <> cdm::Status CdmWrapperImpl<cdm::ContentDecryptionModule_1>:: 201 DecryptAndDecodeSamples(const cdm::InputBuffer& encrypted_buffer, 202 cdm::AudioFrames* audio_frames) { 203 AudioFramesImpl audio_frames_1; 204 cdm::Status status = 205 cdm_->DecryptAndDecodeSamples(encrypted_buffer, &audio_frames_1); 206 if (status != cdm::kSuccess) 207 return status; 208 209 audio_frames->SetFrameBuffer(audio_frames_1.PassFrameBuffer()); 210 audio_frames->SetFormat(cdm::kAudioFormatS16); 211 return cdm::kSuccess; 212} 213 214CdmWrapper* CdmWrapper::Create(const char* key_system, 215 int key_system_size, 216 GetCdmHostFunc get_cdm_host_func, 217 void* user_data) { 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); 222 if (cdm_adapter) 223 return cdm_adapter; 224 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); 228 return cdm_adapter; 229} 230 231// When updating the CdmAdapter, ensure you've updated the CdmWrapper to contain 232// stub implementations for new or modified methods which the older CDM 233// interface does not have. 234COMPILE_ASSERT(cdm::ContentDecryptionModule_2::kVersion == 235 cdm::ContentDecryptionModule::kVersion, 236 ensure_cdm_wrapper_templates_have_old_version_support); 237 238} // namespace media 239 240#endif // MEDIA_CDM_PPAPI_CDM_WRAPPER_H_ 241