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_EXTERNAL_CLEAR_KEY_CLEAR_KEY_CDM_H_ 6 #define MEDIA_CDM_PPAPI_EXTERNAL_CLEAR_KEY_CLEAR_KEY_CDM_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "base/compiler_specific.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/memory/scoped_ptr.h" 15 #include "base/synchronization/lock.h" 16 #include "media/cdm/aes_decryptor.h" 17 #include "media/cdm/ppapi/external_clear_key/clear_key_cdm_common.h" 18 19 // Enable this to use the fake decoder for testing. 20 // TODO(tomfinegan): Move fake audio decoder into a separate class. 21 #if 0 22 #define CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER 23 #endif 24 25 namespace media { 26 class FileIOTestRunner; 27 class CdmVideoDecoder; 28 class DecoderBuffer; 29 class FFmpegCdmAudioDecoder; 30 31 // Clear key implementation of the cdm::ContentDecryptionModule interface. 32 class ClearKeyCdm : public ClearKeyCdmInterface { 33 public: 34 ClearKeyCdm(Host* host, const std::string& key_system); 35 virtual ~ClearKeyCdm(); 36 37 // ContentDecryptionModule implementation. 38 virtual void CreateSession(uint32 promise_id, 39 const char* init_data_type, 40 uint32 init_data_type_size, 41 const uint8* init_data, 42 uint32 init_data_size, 43 cdm::SessionType session_type) OVERRIDE; 44 virtual void LoadSession(uint32 promise_id, 45 const char* web_session_id, 46 uint32_t web_session_id_length) OVERRIDE; 47 virtual void UpdateSession(uint32 promise_id, 48 const char* web_session_id, 49 uint32_t web_session_id_length, 50 const uint8* response, 51 uint32 response_size) OVERRIDE; 52 virtual void ReleaseSession(uint32 promise_id, 53 const char* web_session_id, 54 uint32_t web_session_id_length) OVERRIDE; 55 virtual void SetServerCertificate( 56 uint32 promise_id, 57 const uint8_t* server_certificate_data, 58 uint32_t server_certificate_data_size) OVERRIDE; 59 virtual void TimerExpired(void* context) OVERRIDE; 60 virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer, 61 cdm::DecryptedBlock* decrypted_block) OVERRIDE; 62 virtual cdm::Status InitializeAudioDecoder( 63 const cdm::AudioDecoderConfig& audio_decoder_config) OVERRIDE; 64 virtual cdm::Status InitializeVideoDecoder( 65 const cdm::VideoDecoderConfig& video_decoder_config) OVERRIDE; 66 virtual void DeinitializeDecoder(cdm::StreamType decoder_type) OVERRIDE; 67 virtual void ResetDecoder(cdm::StreamType decoder_type) OVERRIDE; 68 virtual cdm::Status DecryptAndDecodeFrame( 69 const cdm::InputBuffer& encrypted_buffer, 70 cdm::VideoFrame* video_frame) OVERRIDE; 71 virtual cdm::Status DecryptAndDecodeSamples( 72 const cdm::InputBuffer& encrypted_buffer, 73 cdm::AudioFrames* audio_frames) OVERRIDE; 74 virtual void Destroy() OVERRIDE; 75 virtual void OnPlatformChallengeResponse( 76 const cdm::PlatformChallengeResponse& response) OVERRIDE; 77 virtual void OnQueryOutputProtectionStatus( 78 uint32_t link_mask, uint32_t output_protection_mask) OVERRIDE; 79 80 private: 81 // Emulates a session stored for |session_id_for_emulated_loadsession_|. This 82 // is necessary since aes_decryptor.cc does not support storing sessions. 83 void LoadLoadableSession(); 84 85 // ContentDecryptionModule callbacks. 86 void OnSessionMessage(const std::string& web_session_id, 87 const std::vector<uint8>& message, 88 const GURL& destination_url); 89 void OnSessionClosed(const std::string& web_session_id); 90 91 // Handle the success/failure of a promise. These methods are responsible for 92 // calling |host_| to resolve or reject the promise. 93 void OnSessionCreated(uint32 promise_id, const std::string& web_session_id); 94 void OnSessionLoaded(uint32 promise_id, const std::string& web_session_id); 95 void OnSessionUpdated(uint32 promise_id, const std::string& web_session_id); 96 void OnSessionReleased(uint32 promise_id, const std::string& web_session_id); 97 void OnPromiseFailed(uint32 promise_id, 98 MediaKeys::Exception exception_code, 99 uint32 system_code, 100 const std::string& error_message); 101 102 // Prepares next heartbeat message and sets a timer for it. 103 void ScheduleNextHeartBeat(); 104 105 // Decrypts the |encrypted_buffer| and puts the result in |decrypted_buffer|. 106 // Returns cdm::kSuccess if decryption succeeded. The decrypted result is 107 // put in |decrypted_buffer|. If |encrypted_buffer| is empty, the 108 // |decrypted_buffer| is set to an empty (EOS) buffer. 109 // Returns cdm::kNoKey if no decryption key was available. In this case 110 // |decrypted_buffer| should be ignored by the caller. 111 // Returns cdm::kDecryptError if any decryption error occurred. In this case 112 // |decrypted_buffer| should be ignored by the caller. 113 cdm::Status DecryptToMediaDecoderBuffer( 114 const cdm::InputBuffer& encrypted_buffer, 115 scoped_refptr<DecoderBuffer>* decrypted_buffer); 116 117 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 118 int64 CurrentTimeStampInMicroseconds() const; 119 120 // Generates fake video frames with |duration_in_microseconds|. 121 // Returns the number of samples generated in the |audio_frames|. 122 int GenerateFakeAudioFramesFromDuration(int64 duration_in_microseconds, 123 cdm::AudioFrames* audio_frames) const; 124 125 // Generates fake video frames given |input_timestamp|. 126 // Returns cdm::kSuccess if any audio frame is successfully generated. 127 cdm::Status GenerateFakeAudioFrames(int64 timestamp_in_microseconds, 128 cdm::AudioFrames* audio_frames); 129 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER 130 131 void StartFileIOTest(); 132 133 // Callback for CDM File IO test. 134 void OnFileIOTestComplete(bool success); 135 136 // Keep track of the last session created. 137 void SetSessionId(const std::string& web_session_id); 138 139 AesDecryptor decryptor_; 140 141 ClearKeyCdmHost* host_; 142 143 const std::string key_system_; 144 145 std::string last_session_id_; 146 std::string next_heartbeat_message_; 147 148 // TODO(xhwang): Extract testing code from main implementation. 149 // See http://crbug.com/341751 150 std::string session_id_for_emulated_loadsession_; 151 uint32_t promise_id_for_emulated_loadsession_; 152 153 // Timer delay in milliseconds for the next host_->SetTimer() call. 154 int64 timer_delay_ms_; 155 156 // Indicates whether a heartbeat timer has been set to prevent multiple timers 157 // from running. 158 bool heartbeat_timer_set_; 159 160 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 161 int channel_count_; 162 int bits_per_channel_; 163 int samples_per_second_; 164 int64 output_timestamp_base_in_microseconds_; 165 int total_samples_generated_; 166 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER 167 168 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) 169 scoped_ptr<FFmpegCdmAudioDecoder> audio_decoder_; 170 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER 171 172 scoped_ptr<CdmVideoDecoder> video_decoder_; 173 174 scoped_ptr<FileIOTestRunner> file_io_test_runner_; 175 176 DISALLOW_COPY_AND_ASSIGN(ClearKeyCdm); 177 }; 178 179 } // namespace media 180 181 #endif // MEDIA_CDM_PPAPI_EXTERNAL_CLEAR_KEY_CLEAR_KEY_CDM_H_ 182