cdm_wrapper.h revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file. 48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 58bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#ifndef MEDIA_CDM_PPAPI_CDM_WRAPPER_H_ 68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#define MEDIA_CDM_PPAPI_CDM_WRAPPER_H_ 78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <map> 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <queue> 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <string> 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/basictypes.h" 138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "media/cdm/ppapi/api/content_decryption_module.h" 148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "media/cdm/ppapi/cdm_helpers.h" 150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "media/cdm/ppapi/supported_cdm_versions.h" 168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ppapi/cpp/logging.h" 178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace media { 198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// CdmWrapper wraps different versions of ContentDecryptionModule interfaces and 218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// exposes a common interface to the caller. 228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// 238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// The caller should call CdmWrapper::Create() to create a CDM instance. 248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// CdmWrapper will first try to create a CDM instance that supports the latest 258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// CDM interface (ContentDecryptionModule). If such an instance cannot be 268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// created (e.g. an older CDM was loaded), CdmWrapper will try to create a CDM 278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// that supports an older version of CDM interface (e.g. 288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// ContentDecryptionModule_*). Internally CdmWrapper converts the CdmWrapper 298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// calls to corresponding ContentDecryptionModule calls. 308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// 318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Note that CdmWrapper interface always reflects the latest state of content 328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// decryption related PPAPI APIs (e.g. pp::ContentDecryptor_Private). 338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// 348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Since this file is highly templated and default implementations are short 358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// (just a shim layer in most cases), everything is done in this header file. 368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class CdmWrapper { 378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public: 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // CDM_1 and CDM_2 methods AddKey() and CancelKeyRequest() may require 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // callbacks to fire. Use this enum to indicate the additional calls required. 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(jrummell): Remove return value once CDM_1 and CDM_2 are no longer 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // supported. 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) enum Result { 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NO_ACTION, 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CALL_KEY_ADDED, 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CALL_KEY_ERROR 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) }; 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) static CdmWrapper* Create(const char* key_system, 491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) uint32_t key_system_size, 508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) GetCdmHostFunc get_cdm_host_func, 518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) void* user_data); 528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual ~CdmWrapper() {}; 548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void CreateSession(uint32_t session_id, 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const char* type, 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t type_size, 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8_t* init_data, 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t init_data_size) = 0; 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual Result UpdateSession(uint32_t session_id, 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8_t* response, 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t response_size) = 0; 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual Result ReleaseSession(uint32_t session_id) = 0; 648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void TimerExpired(void* context) = 0; 658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer, 668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cdm::DecryptedBlock* decrypted_buffer) = 0; 678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual cdm::Status InitializeAudioDecoder( 688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const cdm::AudioDecoderConfig& audio_decoder_config) = 0; 698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual cdm::Status InitializeVideoDecoder( 708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const cdm::VideoDecoderConfig& video_decoder_config) = 0; 718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void DeinitializeDecoder(cdm::StreamType decoder_type) = 0; 728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void ResetDecoder(cdm::StreamType decoder_type) = 0; 738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual cdm::Status DecryptAndDecodeFrame( 748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const cdm::InputBuffer& encrypted_buffer, 758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cdm::VideoFrame* video_frame) = 0; 768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual cdm::Status DecryptAndDecodeSamples( 778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const cdm::InputBuffer& encrypted_buffer, 788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cdm::AudioFrames* audio_frames) = 0; 798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void OnPlatformChallengeResponse( 808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const cdm::PlatformChallengeResponse& response) = 0; 818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void OnQueryOutputProtectionStatus( 828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) uint32_t link_mask, 838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) uint32_t output_protection_mask) = 0; 848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // ContentDecryptionModule_1 and ContentDecryptionModule_2 interface methods 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // AddKey() and CancelKeyRequest() (older versions of UpdateSession() and 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // ReleaseSession(), respectively) pass in the web_session_id rather than the 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // session_id. As well, Host_1 and Host_2 callbacks SendKeyMessage() and 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // SendKeyError() include the web_session_id, but the actual callbacks need 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // session_id. 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The following functions maintain the session_id <-> web_session_id mapping. 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // These can be removed once _1 and _2 interfaces are no longer supported. 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Determine the corresponding session_id for |web_session_id|. 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual uint32_t LookupSessionId(const std::string& web_session_id) = 0; 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Determine the corresponding session_id for |session_id|. 99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual const std::string LookupWebSessionId(uint32_t session_id) = 0; 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Map between session_id and web_session_id. 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // TODO(jrummell): The following can be removed once CDM_1 and CDM_2 are 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // no longer supported. 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) typedef std::map<uint32_t, std::string> SessionMap; 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SessionMap session_map_; 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static const uint32_t kInvalidSessionId = 0; 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // As the response from PrefixedGenerateKeyRequest() may be synchronous or 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // asynchronous, keep track of the current request during the call to handle 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // synchronous responses or errors. If no response received, add this request 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // to a queue and assume that the subsequent responses come back in the order 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // issued. 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(jrummell): Remove once all supported CDM host interfaces support 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // session_id. 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t current_key_request_session_id_; 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::queue<uint32_t> pending_key_request_session_ids_; 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected: 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CdmWrapper() : current_key_request_session_id_(kInvalidSessionId) {} 1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private: 1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CdmWrapper); 1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}; 1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Template class that does the CdmWrapper -> CdmInterface conversion. Default 1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// implementations are provided. Any methods that need special treatment should 1288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// be specialized. 1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)template <class CdmInterface> 1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class CdmWrapperImpl : public CdmWrapper { 1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public: 1328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) static CdmWrapper* Create(const char* key_system, 1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) uint32_t key_system_size, 1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) GetCdmHostFunc get_cdm_host_func, 1358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) void* user_data) { 1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) void* cdm_instance = ::CreateCdmInstance( 1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CdmInterface::kVersion, key_system, key_system_size, get_cdm_host_func, 1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) user_data); 1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!cdm_instance) 1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return NULL; 1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return new CdmWrapperImpl<CdmInterface>( 1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) static_cast<CdmInterface*>(cdm_instance)); 1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual ~CdmWrapperImpl() { 1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cdm_->Destroy(); 1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void CreateSession(uint32_t session_id, 151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const char* type, 152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t type_size, 153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8_t* init_data, 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t init_data_size) OVERRIDE { 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm_->CreateSession(session_id, type, type_size, init_data, init_data_size); 1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual Result UpdateSession(uint32_t session_id, 159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8_t* response, 160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t response_size) OVERRIDE { 161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm_->UpdateSession(session_id, response, response_size); 162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return NO_ACTION; 1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual Result ReleaseSession(uint32_t session_id) OVERRIDE { 166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm_->ReleaseSession(session_id); 167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return NO_ACTION; 1688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void TimerExpired(void* context) OVERRIDE { 1718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cdm_->TimerExpired(context); 1728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer, 1758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cdm::DecryptedBlock* decrypted_buffer) OVERRIDE { 1768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return cdm_->Decrypt(encrypted_buffer, decrypted_buffer); 1778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual cdm::Status InitializeAudioDecoder( 1808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const cdm::AudioDecoderConfig& audio_decoder_config) OVERRIDE { 1818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return cdm_->InitializeAudioDecoder(audio_decoder_config); 1828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual cdm::Status InitializeVideoDecoder( 1858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const cdm::VideoDecoderConfig& video_decoder_config) OVERRIDE { 1868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return cdm_->InitializeVideoDecoder(video_decoder_config); 1878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void DeinitializeDecoder(cdm::StreamType decoder_type) OVERRIDE { 1908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cdm_->DeinitializeDecoder(decoder_type); 1918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void ResetDecoder(cdm::StreamType decoder_type) OVERRIDE { 1948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cdm_->ResetDecoder(decoder_type); 1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual cdm::Status DecryptAndDecodeFrame( 1988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const cdm::InputBuffer& encrypted_buffer, 1998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cdm::VideoFrame* video_frame) OVERRIDE { 2008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return cdm_->DecryptAndDecodeFrame(encrypted_buffer, video_frame); 2018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual cdm::Status DecryptAndDecodeSamples( 2048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const cdm::InputBuffer& encrypted_buffer, 2058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cdm::AudioFrames* audio_frames) OVERRIDE { 2068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return cdm_->DecryptAndDecodeSamples(encrypted_buffer, audio_frames); 2078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void OnPlatformChallengeResponse( 2108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const cdm::PlatformChallengeResponse& response) OVERRIDE { 2118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cdm_->OnPlatformChallengeResponse(response); 2128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void OnQueryOutputProtectionStatus( 2158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) uint32_t link_mask, 2168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) uint32_t output_protection_mask) OVERRIDE { 2178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cdm_->OnQueryOutputProtectionStatus(link_mask, output_protection_mask); 2188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t LookupSessionId(const std::string& web_session_id) { 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (SessionMap::iterator it = session_map_.begin(); 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it != session_map_.end(); 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ++it) { 224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (it->second == web_session_id) 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return it->first; 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // There is no entry in the map; assume it came from the current 229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // PrefixedGenerateKeyRequest() call (if possible). If no current request, 230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // assume it came from the oldest PrefixedGenerateKeyRequest() call. 231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t session_id = current_key_request_session_id_; 232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (current_key_request_session_id_) { 233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Only 1 response is allowed for the current 234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // PrefixedGenerateKeyRequest(). 235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) current_key_request_session_id_ = kInvalidSessionId; 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PP_DCHECK(!pending_key_request_session_ids_.empty()); 238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_id = pending_key_request_session_ids_.front(); 239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) pending_key_request_session_ids_.pop(); 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If this is a valid |session_id|, add it to the list. Otherwise, avoid 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // adding empty string as a mapping to prevent future calls with an empty 244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // string from using the wrong session_id. 245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!web_session_id.empty()) { 246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PP_DCHECK(session_map_.find(session_id) == session_map_.end()); 247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) session_map_[session_id] = web_session_id; 248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return session_id; 251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string LookupWebSessionId(uint32_t session_id) { 254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Session may not exist if error happens during CreateSession(). 255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SessionMap::iterator it = session_map_.find(session_id); 256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return (it != session_map_.end()) ? it->second : std::string(); 257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private: 2608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CdmWrapperImpl(CdmInterface* cdm) : cdm_(cdm) { 2618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) PP_DCHECK(cdm_); 2628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CdmInterface* cdm_; 2658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CdmWrapperImpl); 2678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}; 2688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// For ContentDecryptionModule_1 and ContentDecryptionModule_2, 270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// CreateSession(), UpdateSession(), and ReleaseSession() call methods 271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// are incompatible with ContentDecryptionModule_3. Use the following 272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// templated functions to handle this. 273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <class CdmInterface> 275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PrefixedGenerateKeyRequest(CdmWrapper* wrapper, 276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CdmInterface* cdm, 277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t session_id, 278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const char* type, 279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t type_size, 280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8_t* init_data, 281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t init_data_size) { 282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // As it is possible for CDMs to reply synchronously during the call to 283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // GenerateKeyRequest(), keep track of |session_id|. 284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) wrapper->current_key_request_session_id_ = session_id; 285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm::Status status = 287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm->GenerateKeyRequest(type, type_size, init_data, init_data_size); 288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError); 289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (status != cdm::kSuccess) { 290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // If GenerateKeyRequest() failed, no subsequent asynchronous replies 291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // will be sent. Verify that a response was sent synchronously. 292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PP_DCHECK(wrapper->current_key_request_session_id_ == 293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CdmWrapper::kInvalidSessionId); 294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) wrapper->current_key_request_session_id_ = CdmWrapper::kInvalidSessionId; 295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 298a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (wrapper->current_key_request_session_id_) { 299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // If this request is still pending (SendKeyMessage() or SendKeyError() 300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // not called synchronously), add |session_id| to the end of the queue. 301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Without CDM support, it is impossible to match SendKeyMessage() 302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // (or SendKeyError()) responses to the |session_id|. Doing the best 303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // we can by keeping track of this in a queue, and assuming the responses 304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // come back in order. 305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) wrapper->pending_key_request_session_ids_.push(session_id); 306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) wrapper->current_key_request_session_id_ = CdmWrapper::kInvalidSessionId; 307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <class CdmInterface> 311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CdmWrapper::Result PrefixedAddKey(CdmWrapper* wrapper, 312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CdmInterface* cdm, 313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t session_id, 314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8_t* response, 315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t response_size) { 316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string web_session_id = wrapper->LookupWebSessionId(session_id); 317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (web_session_id.empty()) { 318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Possible if UpdateSession() called before CreateSession(). 319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return CdmWrapper::CALL_KEY_ERROR; 320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 322a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // CDM_1 and CDM_2 accept initdata, which is no longer needed. 323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // In it's place pass in NULL. 324a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm::Status status = cdm->AddKey(web_session_id.data(), web_session_id.size(), 325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) response, response_size, 326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NULL, 0); 327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError); 328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (status != cdm::kSuccess) { 329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Some CDMs using Host_1/2 don't call keyerror, so send one. 330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return CdmWrapper::CALL_KEY_ERROR; 331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return CdmWrapper::CALL_KEY_ADDED; 334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <class CdmInterface> 337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CdmWrapper::Result PrefixedCancelKeyRequest(CdmWrapper* wrapper, 338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CdmInterface* cdm, 339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t session_id) { 340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string web_session_id = wrapper->LookupWebSessionId(session_id); 341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (web_session_id.empty()) { 342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Possible if ReleaseSession() called before CreateSession(). 343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return CdmWrapper::CALL_KEY_ERROR; 344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) wrapper->session_map_.erase(session_id); 347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm::Status status = 348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm->CancelKeyRequest(web_session_id.data(), web_session_id.size()); 349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError); 351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (status != cdm::kSuccess) { 352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Some CDMs using Host_1/2 don't call keyerror, so send one. 353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return CdmWrapper::CALL_KEY_ERROR; 354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return CdmWrapper::NO_ACTION; 357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Specializations for ContentDecryptionModule_1. 3608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <> 362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CdmWrapperImpl<cdm::ContentDecryptionModule_1>::CreateSession( 363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t session_id, 364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const char* type, 365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t type_size, 366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8_t* init_data, 367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t init_data_size) { 368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PrefixedGenerateKeyRequest( 369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) this, cdm_, session_id, type, type_size, init_data, init_data_size); 370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <> 373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CdmWrapper::Result CdmWrapperImpl< 374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm::ContentDecryptionModule_1>::UpdateSession(uint32_t session_id, 375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8_t* response, 376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t response_size) { 377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return PrefixedAddKey(this, cdm_, session_id, response, response_size); 378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <> 381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CdmWrapper::Result CdmWrapperImpl< 382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm::ContentDecryptionModule_1>::ReleaseSession(uint32_t session_id) { 383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return PrefixedCancelKeyRequest(this, cdm_, session_id); 384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)template <> void CdmWrapperImpl<cdm::ContentDecryptionModule_1>:: 3878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OnPlatformChallengeResponse( 3888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const cdm::PlatformChallengeResponse& response) { 3898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) PP_NOTREACHED(); 3908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 3918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)template <> void CdmWrapperImpl<cdm::ContentDecryptionModule_1>:: 3938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OnQueryOutputProtectionStatus(uint32_t link_mask, 3948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) uint32_t output_protection_mask) { 3958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) PP_NOTREACHED(); 3968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 3978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)template <> cdm::Status CdmWrapperImpl<cdm::ContentDecryptionModule_1>:: 3998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DecryptAndDecodeSamples(const cdm::InputBuffer& encrypted_buffer, 4008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cdm::AudioFrames* audio_frames) { 4018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) AudioFramesImpl audio_frames_1; 4028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cdm::Status status = 4038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cdm_->DecryptAndDecodeSamples(encrypted_buffer, &audio_frames_1); 4048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (status != cdm::kSuccess) 4058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return status; 4068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) audio_frames->SetFrameBuffer(audio_frames_1.PassFrameBuffer()); 4088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) audio_frames->SetFormat(cdm::kAudioFormatS16); 4098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return cdm::kSuccess; 4108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 4118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 412a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Specializations for ContentDecryptionModule_2. 413a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 414a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <> 415a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CdmWrapperImpl<cdm::ContentDecryptionModule_2>::CreateSession( 416a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t session_id, 417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const char* type, 418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t type_size, 419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8_t* init_data, 420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t init_data_size) { 421a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PrefixedGenerateKeyRequest( 422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) this, cdm_, session_id, type, type_size, init_data, init_data_size); 423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 424a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <> 426a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CdmWrapper::Result CdmWrapperImpl< 427a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm::ContentDecryptionModule_2>::UpdateSession(uint32_t session_id, 428a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8_t* response, 429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32_t response_size) { 430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return PrefixedAddKey(this, cdm_, session_id, response, response_size); 431a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 432a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template <> 434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)CdmWrapper::Result CdmWrapperImpl< 435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm::ContentDecryptionModule_2>::ReleaseSession(uint32_t session_id) { 436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return PrefixedCancelKeyRequest(this, cdm_, session_id); 437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 4398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)CdmWrapper* CdmWrapper::Create(const char* key_system, 4401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) uint32_t key_system_size, 4418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) GetCdmHostFunc get_cdm_host_func, 4428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) void* user_data) { 4430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) COMPILE_ASSERT(cdm::ContentDecryptionModule::kVersion == 444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm::ContentDecryptionModule_3::kVersion, 4450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) update_code_below); 4460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 4470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Ensure IsSupportedCdmInterfaceVersion matches this implementation. 4480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Always update this DCHECK when updating this function. 4490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // If this check fails, update this function and DCHECK or update 4500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // IsSupportedCdmInterfaceVersion. 4510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) PP_DCHECK( 4520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) !IsSupportedCdmInterfaceVersion( 4530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) cdm::ContentDecryptionModule::kVersion + 1) && 4540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) IsSupportedCdmInterfaceVersion(cdm::ContentDecryptionModule::kVersion) && 4550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) IsSupportedCdmInterfaceVersion( 456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm::ContentDecryptionModule_2::kVersion) && 457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) IsSupportedCdmInterfaceVersion( 4580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) cdm::ContentDecryptionModule_1::kVersion) && 4590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) !IsSupportedCdmInterfaceVersion( 4600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) cdm::ContentDecryptionModule_1::kVersion - 1)); 4610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 4628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Try to create the CDM using the latest CDM interface version. 4630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) CdmWrapper* cdm_wrapper = 4648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CdmWrapperImpl<cdm::ContentDecryptionModule>::Create( 4658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) key_system, key_system_size, get_cdm_host_func, user_data); 4660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (cdm_wrapper) 4670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return cdm_wrapper; 4688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Try to see if the CDM supports older version(s) of the CDM interface. 470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm_wrapper = CdmWrapperImpl<cdm::ContentDecryptionModule_2>::Create( 471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) key_system, key_system_size, get_cdm_host_func, user_data); 472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (cdm_wrapper) 473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return cdm_wrapper; 474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 4750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) cdm_wrapper = CdmWrapperImpl<cdm::ContentDecryptionModule_1>::Create( 4768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) key_system, key_system_size, get_cdm_host_func, user_data); 4770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return cdm_wrapper; 4788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 4798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// When updating the CdmAdapter, ensure you've updated the CdmWrapper to contain 4811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// stub implementations for new or modified methods that the older CDM interface 4821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// does not have. 4830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Also update supported_cdm_versions.h. 4841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)COMPILE_ASSERT(cdm::ContentDecryptionModule::kVersion == 485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cdm::ContentDecryptionModule_3::kVersion, 4868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ensure_cdm_wrapper_templates_have_old_version_support); 4878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} // namespace media 4898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif // MEDIA_CDM_PPAPI_CDM_WRAPPER_H_ 491