Home | History | Annotate | Download | only in ppapi
      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/api/content_decryption_module.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 cdm::ContentDecryptionModule {
     32  public:
     33   explicit ClearKeyCdm(cdm::Host* host);
     34   virtual ~ClearKeyCdm();
     35 
     36   // ContentDecryptionModule implementation.
     37   virtual cdm::Status GenerateKeyRequest(
     38       const char* type, int type_size,
     39       const uint8_t* init_data, int init_data_size) OVERRIDE;
     40   virtual cdm::Status AddKey(const char* session_id, int session_id_size,
     41                              const uint8_t* key, int key_size,
     42                              const uint8_t* key_id, int key_id_size) OVERRIDE;
     43   virtual cdm::Status CancelKeyRequest(const char* session_id,
     44                                        int session_id_size) OVERRIDE;
     45   virtual void TimerExpired(void* context) OVERRIDE;
     46   virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer,
     47                               cdm::DecryptedBlock* decrypted_block) OVERRIDE;
     48   virtual cdm::Status InitializeAudioDecoder(
     49       const cdm::AudioDecoderConfig& audio_decoder_config) OVERRIDE;
     50   virtual cdm::Status InitializeVideoDecoder(
     51       const cdm::VideoDecoderConfig& video_decoder_config) OVERRIDE;
     52   virtual void DeinitializeDecoder(cdm::StreamType decoder_type) OVERRIDE;
     53   virtual void ResetDecoder(cdm::StreamType decoder_type) OVERRIDE;
     54   virtual cdm::Status DecryptAndDecodeFrame(
     55       const cdm::InputBuffer& encrypted_buffer,
     56       cdm::VideoFrame* video_frame) OVERRIDE;
     57   virtual cdm::Status DecryptAndDecodeSamples(
     58       const cdm::InputBuffer& encrypted_buffer,
     59       cdm::AudioFrames* audio_frames) OVERRIDE;
     60   virtual void Destroy() OVERRIDE;
     61 
     62  private:
     63   // TODO(xhwang): After we removed DecryptorClient. We probably can also remove
     64   // this Client class as well. Investigate this possibility.
     65   class Client {
     66    public:
     67     enum Status {
     68       kKeyAdded,
     69       kKeyError,
     70       kKeyMessage
     71     };
     72 
     73     Client();
     74     virtual ~Client();
     75 
     76     Status status() { return status_; }
     77     const std::string& session_id() { return session_id_; }
     78     const std::vector<uint8>& key_message() { return key_message_; }
     79     const std::string& default_url() { return default_url_; }
     80 
     81     // Resets the Client to a clean state.
     82     void Reset();
     83 
     84     void KeyAdded(const std::string& session_id);
     85     void KeyError(const std::string& session_id,
     86                   MediaKeys::KeyError error_code,
     87                   int system_code);
     88     void KeyMessage(const std::string& session_id,
     89                     const std::vector<uint8>& message,
     90                     const std::string& default_url);
     91 
     92    private:
     93     Status status_;
     94     std::string session_id_;
     95     std::vector<uint8> key_message_;
     96     std::string default_url_;
     97   };
     98 
     99   // Prepares next heartbeat message and sets a timer for it.
    100   void ScheduleNextHeartBeat();
    101 
    102   // Decrypts the |encrypted_buffer| and puts the result in |decrypted_buffer|.
    103   // Returns cdm::kSuccess if decryption succeeded. The decrypted result is
    104   // put in |decrypted_buffer|. If |encrypted_buffer| is empty, the
    105   // |decrypted_buffer| is set to an empty (EOS) buffer.
    106   // Returns cdm::kNoKey if no decryption key was available. In this case
    107   // |decrypted_buffer| should be ignored by the caller.
    108   // Returns cdm::kDecryptError if any decryption error occurred. In this case
    109   // |decrypted_buffer| should be ignored by the caller.
    110   cdm::Status DecryptToMediaDecoderBuffer(
    111       const cdm::InputBuffer& encrypted_buffer,
    112       scoped_refptr<DecoderBuffer>* decrypted_buffer);
    113 
    114 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
    115   int64 CurrentTimeStampInMicroseconds() const;
    116 
    117   // Generates fake video frames with |duration_in_microseconds|.
    118   // Returns the number of samples generated in the |audio_frames|.
    119   int GenerateFakeAudioFramesFromDuration(int64 duration_in_microseconds,
    120                                           cdm::AudioFrames* audio_frames) const;
    121 
    122   // Generates fake video frames given |input_timestamp|.
    123   // Returns cdm::kSuccess if any audio frame is successfully generated.
    124   cdm::Status GenerateFakeAudioFrames(int64 timestamp_in_microseconds,
    125                                       cdm::AudioFrames* audio_frames);
    126 #endif  // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER
    127 
    128   Client client_;
    129   AesDecryptor decryptor_;
    130 
    131   // Protects the |client_| from being accessed by the |decryptor_|
    132   // simultaneously.
    133   base::Lock client_lock_;
    134 
    135   cdm::Host* host_;
    136 
    137   std::string heartbeat_session_id_;
    138   std::string next_heartbeat_message_;
    139 
    140   // Timer delay in milliseconds for the next host_->SetTimer() call.
    141   int64 timer_delay_ms_;
    142 
    143   // Indicates whether a timer has been set to prevent multiple timers from
    144   // running.
    145   bool timer_set_;
    146 
    147 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
    148   int channel_count_;
    149   int bits_per_channel_;
    150   int samples_per_second_;
    151   int64 output_timestamp_base_in_microseconds_;
    152   int total_samples_generated_;
    153 #endif  // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER
    154 
    155 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
    156   scoped_ptr<FFmpegCdmAudioDecoder> audio_decoder_;
    157 #endif  // CLEAR_KEY_CDM_USE_FFMPEG_DECODER
    158 
    159   scoped_ptr<CdmVideoDecoder> video_decoder_;
    160 
    161   DISALLOW_COPY_AND_ASSIGN(ClearKeyCdm);
    162 };
    163 
    164 }  // namespace media
    165 
    166 #endif  // MEDIA_CDM_PPAPI_CLEAR_KEY_CDM_H_
    167