• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_CLEAR_KEY_CDM_H_
6 #define MEDIA_CDM_PPAPI_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/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 CdmVideoDecoder;
27 class DecoderBuffer;
28 class FFmpegCdmAudioDecoder;
29 
30 // Clear key implementation of the cdm::ContentDecryptionModule interface.
31 class ClearKeyCdm : public ClearKeyCdmInterface {
32  public:
33   explicit ClearKeyCdm(Host* host, bool is_decrypt_only);
34   virtual ~ClearKeyCdm();
35 
36   // ContentDecryptionModule implementation.
37   virtual cdm::Status GenerateKeyRequest(
38       const char* type, uint32_t type_size,
39       const uint8_t* init_data, uint32_t init_data_size) OVERRIDE;
40   virtual cdm::Status AddKey(const char* session_id,
41                              uint32_t session_id_size,
42                              const uint8_t* key,
43                              uint32_t key_size,
44                              const uint8_t* key_id,
45                              uint32_t key_id_size) OVERRIDE;
46   virtual cdm::Status CancelKeyRequest(const char* session_id,
47                                        uint32_t session_id_size) OVERRIDE;
48   virtual void TimerExpired(void* context) OVERRIDE;
49   virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer,
50                               cdm::DecryptedBlock* decrypted_block) OVERRIDE;
51   virtual cdm::Status InitializeAudioDecoder(
52       const cdm::AudioDecoderConfig& audio_decoder_config) OVERRIDE;
53   virtual cdm::Status InitializeVideoDecoder(
54       const cdm::VideoDecoderConfig& video_decoder_config) OVERRIDE;
55   virtual void DeinitializeDecoder(cdm::StreamType decoder_type) OVERRIDE;
56   virtual void ResetDecoder(cdm::StreamType decoder_type) OVERRIDE;
57   virtual cdm::Status DecryptAndDecodeFrame(
58       const cdm::InputBuffer& encrypted_buffer,
59       cdm::VideoFrame* video_frame) OVERRIDE;
60   virtual cdm::Status DecryptAndDecodeSamples(
61       const cdm::InputBuffer& encrypted_buffer,
62       cdm::AudioFrames* audio_frames) OVERRIDE;
63   virtual void Destroy() OVERRIDE;
64   virtual void OnPlatformChallengeResponse(
65       const cdm::PlatformChallengeResponse& response) OVERRIDE;
66   virtual void OnQueryOutputProtectionStatus(
67       uint32_t link_mask, uint32_t output_protection_mask) OVERRIDE;
68 
69  private:
70   // TODO(xhwang): After we removed DecryptorClient. We probably can also remove
71   // this Client class as well. Investigate this possibility.
72   class Client {
73    public:
74     // TODO(jrummell): Remove bitmask and rename kNone to kInvalid once CDM
75     // interface supports session_id passing completely.
76     enum Status {
77       kNone = 0,
78       kCreated = 1 << 0,
79       kMessage = 1 << 1,
80       kReady = 1 << 2,
81       kClosed = 1 << 3,
82       kError = 1 << 4
83     };
84 
85     Client();
86     virtual ~Client();
87 
status()88     Status status() { return status_; }
web_session_id()89     const std::string& web_session_id() { return web_session_id_; }
message()90     const std::vector<uint8>& message() { return message_; }
destination_url()91     const std::string& destination_url() { return destination_url_; }
error_code()92     MediaKeys::KeyError error_code() { return error_code_; }
system_code()93     int system_code() { return system_code_; }
94 
95     // Resets the Client to a clean state.
96     void Reset();
97 
98     void OnSessionCreated(uint32 session_id, const std::string& web_session_id);
99     void OnSessionMessage(uint32 session_id,
100                           const std::vector<uint8>& message,
101                           const std::string& destination_url);
102     void OnSessionReady(uint32 session_id);
103     void OnSessionClosed(uint32 session_id);
104     void OnSessionError(uint32 session_id,
105                         MediaKeys::KeyError error_code,
106                         int system_code);
107 
108    private:
109     Status status_;
110     std::string web_session_id_;
111     std::vector<uint8> message_;
112     std::string destination_url_;
113     MediaKeys::KeyError error_code_;
114     int system_code_;
115   };
116 
117   // Prepares next heartbeat message and sets a timer for it.
118   void ScheduleNextHeartBeat();
119 
120   // Decrypts the |encrypted_buffer| and puts the result in |decrypted_buffer|.
121   // Returns cdm::kSuccess if decryption succeeded. The decrypted result is
122   // put in |decrypted_buffer|. If |encrypted_buffer| is empty, the
123   // |decrypted_buffer| is set to an empty (EOS) buffer.
124   // Returns cdm::kNoKey if no decryption key was available. In this case
125   // |decrypted_buffer| should be ignored by the caller.
126   // Returns cdm::kDecryptError if any decryption error occurred. In this case
127   // |decrypted_buffer| should be ignored by the caller.
128   cdm::Status DecryptToMediaDecoderBuffer(
129       const cdm::InputBuffer& encrypted_buffer,
130       scoped_refptr<DecoderBuffer>* decrypted_buffer);
131 
132 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
133   int64 CurrentTimeStampInMicroseconds() const;
134 
135   // Generates fake video frames with |duration_in_microseconds|.
136   // Returns the number of samples generated in the |audio_frames|.
137   int GenerateFakeAudioFramesFromDuration(int64 duration_in_microseconds,
138                                           cdm::AudioFrames* audio_frames) const;
139 
140   // Generates fake video frames given |input_timestamp|.
141   // Returns cdm::kSuccess if any audio frame is successfully generated.
142   cdm::Status GenerateFakeAudioFrames(int64 timestamp_in_microseconds,
143                                       cdm::AudioFrames* audio_frames);
144 #endif  // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER
145 
146   Client client_;
147   AesDecryptor decryptor_;
148 
149   // Protects the |client_| from being accessed by the |decryptor_|
150   // simultaneously.
151   base::Lock client_lock_;
152 
153   ClearKeyCdmHost* host_;
154 
155   const bool is_decrypt_only_;
156 
157   std::string heartbeat_session_id_;
158   std::string next_heartbeat_message_;
159 
160   // Timer delay in milliseconds for the next host_->SetTimer() call.
161   int64 timer_delay_ms_;
162 
163   // Indicates whether a timer has been set to prevent multiple timers from
164   // running.
165   bool timer_set_;
166 
167 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
168   int channel_count_;
169   int bits_per_channel_;
170   int samples_per_second_;
171   int64 output_timestamp_base_in_microseconds_;
172   int total_samples_generated_;
173 #endif  // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER
174 
175 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
176   scoped_ptr<FFmpegCdmAudioDecoder> audio_decoder_;
177 #endif  // CLEAR_KEY_CDM_USE_FFMPEG_DECODER
178 
179   scoped_ptr<CdmVideoDecoder> video_decoder_;
180 
181   DISALLOW_COPY_AND_ASSIGN(ClearKeyCdm);
182 };
183 
184 }  // namespace media
185 
186 #endif  // MEDIA_CDM_PPAPI_CLEAR_KEY_CDM_H_
187