Home | History | Annotate | Download | only in pepper
      1 // Copyright (c) 2012 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 CONTENT_RENDERER_PEPPER_CONTENT_DECRYPTOR_DELEGATE_H_
      6 #define CONTENT_RENDERER_PEPPER_CONTENT_DECRYPTOR_DELEGATE_H_
      7 
      8 #include <map>
      9 #include <queue>
     10 #include <string>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/callback_helpers.h"
     14 #include "base/compiler_specific.h"
     15 #include "base/containers/scoped_ptr_hash_map.h"
     16 #include "base/memory/ref_counted.h"
     17 #include "base/memory/weak_ptr.h"
     18 #include "media/base/cdm_promise.h"
     19 #include "media/base/channel_layout.h"
     20 #include "media/base/decryptor.h"
     21 #include "media/base/media_keys.h"
     22 #include "media/base/sample_format.h"
     23 #include "ppapi/c/pp_time.h"
     24 #include "ppapi/c/private/pp_content_decryptor.h"
     25 #include "ppapi/c/private/ppp_content_decryptor_private.h"
     26 #include "ui/gfx/size.h"
     27 
     28 namespace media {
     29 class AudioDecoderConfig;
     30 class DecoderBuffer;
     31 class VideoDecoderConfig;
     32 }
     33 
     34 namespace content {
     35 
     36 class PPB_Buffer_Impl;
     37 
     38 class ContentDecryptorDelegate {
     39  public:
     40   // ContentDecryptorDelegate does not take ownership of
     41   // |plugin_decryption_interface|. Therefore |plugin_decryption_interface|
     42   // must outlive this object.
     43   ContentDecryptorDelegate(
     44       PP_Instance pp_instance,
     45       const PPP_ContentDecryptor_Private* plugin_decryption_interface);
     46   ~ContentDecryptorDelegate();
     47 
     48   // This object should not be accessed after |fatal_plugin_error_cb| is called.
     49   void Initialize(
     50       const std::string& key_system,
     51       const media::SessionMessageCB& session_message_cb,
     52       const media::SessionReadyCB& session_ready_cb,
     53       const media::SessionClosedCB& session_closed_cb,
     54       const media::SessionErrorCB& session_error_cb,
     55       const media::SessionKeysChangeCB& session_keys_change_cb,
     56       const media::SessionExpirationUpdateCB& session_expiration_update_cb,
     57       const base::Closure& fatal_plugin_error_cb);
     58 
     59   void InstanceCrashed();
     60 
     61   // Provides access to PPP_ContentDecryptor_Private.
     62   void SetServerCertificate(const uint8_t* certificate,
     63                             uint32_t certificate_length,
     64                             scoped_ptr<media::SimpleCdmPromise> promise);
     65   void CreateSession(const std::string& init_data_type,
     66                      const uint8* init_data,
     67                      int init_data_length,
     68                      media::MediaKeys::SessionType session_type,
     69                      scoped_ptr<media::NewSessionCdmPromise> promise);
     70   void LoadSession(const std::string& web_session_id,
     71                    scoped_ptr<media::NewSessionCdmPromise> promise);
     72   void UpdateSession(const std::string& web_session_id,
     73                      const uint8* response,
     74                      int response_length,
     75                      scoped_ptr<media::SimpleCdmPromise> promise);
     76   void CloseSession(const std::string& web_session_id,
     77                     scoped_ptr<media::SimpleCdmPromise> promise);
     78   void RemoveSession(const std::string& web_session_id,
     79                      scoped_ptr<media::SimpleCdmPromise> promise);
     80   void GetUsableKeyIds(const std::string& web_session_id,
     81                        scoped_ptr<media::KeyIdsPromise> promise);
     82   bool Decrypt(media::Decryptor::StreamType stream_type,
     83                const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
     84                const media::Decryptor::DecryptCB& decrypt_cb);
     85   bool CancelDecrypt(media::Decryptor::StreamType stream_type);
     86   bool InitializeAudioDecoder(
     87       const media::AudioDecoderConfig& decoder_config,
     88       const media::Decryptor::DecoderInitCB& decoder_init_cb);
     89   bool InitializeVideoDecoder(
     90       const media::VideoDecoderConfig& decoder_config,
     91       const media::Decryptor::DecoderInitCB& decoder_init_cb);
     92   // TODO(tomfinegan): Add callback args for DeinitializeDecoder() and
     93   // ResetDecoder()
     94   bool DeinitializeDecoder(media::Decryptor::StreamType stream_type);
     95   bool ResetDecoder(media::Decryptor::StreamType stream_type);
     96   // Note: These methods can be used with unencrypted data.
     97   bool DecryptAndDecodeAudio(
     98       const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
     99       const media::Decryptor::AudioDecodeCB& audio_decode_cb);
    100   bool DecryptAndDecodeVideo(
    101       const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
    102       const media::Decryptor::VideoDecodeCB& video_decode_cb);
    103 
    104   // PPB_ContentDecryptor_Private dispatching methods.
    105   void OnPromiseResolved(uint32 promise_id);
    106   void OnPromiseResolvedWithSession(uint32 promise_id, PP_Var web_session_id);
    107   void OnPromiseResolvedWithKeyIds(uint32 promise_id, PP_Var key_ids_array);
    108   void OnPromiseRejected(uint32 promise_id,
    109                          PP_CdmExceptionCode exception_code,
    110                          uint32 system_code,
    111                          PP_Var error_description);
    112   void OnSessionMessage(PP_Var web_session_id,
    113                         PP_Var message,
    114                         PP_Var destination_url);
    115   void OnSessionKeysChange(PP_Var web_session_id,
    116                            PP_Bool has_additional_usable_key);
    117   void OnSessionExpirationChange(PP_Var web_session_id,
    118                                  PP_Time new_expiry_time);
    119   void OnSessionReady(PP_Var web_session_id);
    120   void OnSessionClosed(PP_Var web_session_id);
    121   void OnSessionError(PP_Var web_session_id,
    122                       PP_CdmExceptionCode exception_code,
    123                       uint32 system_code,
    124                       PP_Var error_description);
    125   void DeliverBlock(PP_Resource decrypted_block,
    126                     const PP_DecryptedBlockInfo* block_info);
    127   void DecoderInitializeDone(PP_DecryptorStreamType decoder_type,
    128                              uint32_t request_id,
    129                              PP_Bool success);
    130   void DecoderDeinitializeDone(PP_DecryptorStreamType decoder_type,
    131                                uint32_t request_id);
    132   void DecoderResetDone(PP_DecryptorStreamType decoder_type,
    133                         uint32_t request_id);
    134   void DeliverFrame(PP_Resource decrypted_frame,
    135                     const PP_DecryptedFrameInfo* frame_info);
    136   void DeliverSamples(PP_Resource audio_frames,
    137                       const PP_DecryptedSampleInfo* sample_info);
    138 
    139  private:
    140   // The following types keep track of Promises. The index is the promise_id,
    141   // so that returning results can be matched to the corresponding promise.
    142   typedef base::ScopedPtrHashMap<uint32_t, media::CdmPromise> PromiseMap;
    143 
    144   template <typename Callback>
    145   class TrackableCallback {
    146    public:
    147     TrackableCallback() : id_(0u) {}
    148     ~TrackableCallback() {
    149       // Callbacks must be satisfied.
    150       DCHECK_EQ(id_, 0u);
    151       DCHECK(is_null());
    152     };
    153 
    154     bool Matches(uint32_t id) const { return id == id_; }
    155 
    156     bool is_null() const { return cb_.is_null(); }
    157 
    158     void Set(uint32_t id, const Callback& cb) {
    159       DCHECK_EQ(id_, 0u);
    160       DCHECK(cb_.is_null());
    161       id_ = id;
    162       cb_ = cb;
    163     }
    164 
    165     Callback ResetAndReturn() {
    166       id_ = 0;
    167       return base::ResetAndReturn(&cb_);
    168     }
    169 
    170    private:
    171     uint32_t id_;
    172     Callback cb_;
    173   };
    174 
    175   // Cancels the pending decrypt-and-decode callback for |stream_type|.
    176   void CancelDecode(media::Decryptor::StreamType stream_type);
    177 
    178   // Fills |resource| with a PPB_Buffer_Impl and copies the data from
    179   // |encrypted_buffer| into the buffer resource. This method reuses
    180   // |audio_input_resource_| and |video_input_resource_| to reduce the latency
    181   // in requesting new PPB_Buffer_Impl resources. The caller must make sure that
    182   // |audio_input_resource_| or |video_input_resource_| is available before
    183   // calling this method.
    184   //
    185   // An end of stream |encrypted_buffer| is represented as a null |resource|.
    186   //
    187   // Returns true upon success and false if any error happened.
    188   bool MakeMediaBufferResource(
    189       media::Decryptor::StreamType stream_type,
    190       const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
    191       scoped_refptr<PPB_Buffer_Impl>* resource);
    192 
    193   void FreeBuffer(uint32_t buffer_id);
    194 
    195   void SetBufferToFreeInTrackingInfo(PP_DecryptTrackingInfo* tracking_info);
    196 
    197   // Deserializes audio data stored in |audio_frames| into individual audio
    198   // buffers in |frames|. Returns true upon success.
    199   bool DeserializeAudioFrames(PP_Resource audio_frames,
    200                               size_t data_size,
    201                               media::SampleFormat sample_format,
    202                               media::Decryptor::AudioBuffers* frames);
    203 
    204   void SatisfyAllPendingCallbacksOnError();
    205 
    206   // Takes ownership of |promise| and returns an identifier to be passed via
    207   // Pepper.
    208   uint32_t SavePromise(scoped_ptr<media::CdmPromise> promise);
    209 
    210   // Find the promise for a specified |promise_id|. Caller is responsible to
    211   // delete the CdmPromise<> once done with it.
    212   scoped_ptr<media::CdmPromise> TakePromise(uint32_t promise_id);
    213 
    214   const PP_Instance pp_instance_;
    215   const PPP_ContentDecryptor_Private* const plugin_decryption_interface_;
    216 
    217   // TODO(ddorwin): Remove after updating the Pepper API to not use key system.
    218   std::string key_system_;
    219 
    220   // Callbacks for firing session events.
    221   media::SessionMessageCB session_message_cb_;
    222   media::SessionReadyCB session_ready_cb_;
    223   media::SessionClosedCB session_closed_cb_;
    224   media::SessionErrorCB session_error_cb_;
    225   media::SessionKeysChangeCB session_keys_change_cb_;
    226   media::SessionExpirationUpdateCB session_expiration_update_cb_;
    227 
    228   // Callback to notify that unexpected error happened and |this| should not
    229   // be used anymore.
    230   base::Closure fatal_plugin_error_cb_;
    231 
    232   gfx::Size natural_size_;
    233 
    234   // Request ID for tracking pending content decryption callbacks.
    235   // Note that zero indicates an invalid request ID.
    236   // TODO(xhwang): Add completion callbacks for Reset/Stop and remove the use
    237   // of request IDs.
    238   uint32_t next_decryption_request_id_;
    239 
    240   TrackableCallback<media::Decryptor::DecryptCB> audio_decrypt_cb_;
    241   TrackableCallback<media::Decryptor::DecryptCB> video_decrypt_cb_;
    242   TrackableCallback<media::Decryptor::DecoderInitCB> audio_decoder_init_cb_;
    243   TrackableCallback<media::Decryptor::DecoderInitCB> video_decoder_init_cb_;
    244   TrackableCallback<media::Decryptor::AudioDecodeCB> audio_decode_cb_;
    245   TrackableCallback<media::Decryptor::VideoDecodeCB> video_decode_cb_;
    246 
    247   // Cached audio and video input buffers. See MakeMediaBufferResource.
    248   scoped_refptr<PPB_Buffer_Impl> audio_input_resource_;
    249   scoped_refptr<PPB_Buffer_Impl> video_input_resource_;
    250 
    251   std::queue<uint32_t> free_buffers_;
    252 
    253   // Keep track of audio parameters.
    254   int audio_samples_per_second_;
    255   int audio_channel_count_;
    256   media::ChannelLayout audio_channel_layout_;
    257 
    258   // Keep track of outstanding promises. Maps have ownership of the promises.
    259   uint32_t next_promise_id_;
    260   PromiseMap promises_;
    261 
    262   base::WeakPtr<ContentDecryptorDelegate> weak_this_;
    263   base::WeakPtrFactory<ContentDecryptorDelegate> weak_ptr_factory_;
    264 
    265   DISALLOW_COPY_AND_ASSIGN(ContentDecryptorDelegate);
    266 };
    267 
    268 }  // namespace content
    269 
    270 #endif  // CONTENT_RENDERER_PEPPER_CONTENT_DECRYPTOR_DELEGATE_H_
    271