Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / renderer / pepper / content_decryptor_delegate.h
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_