cdm_adapter.h revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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_CDM_ADAPTER_H_
6#define MEDIA_CDM_PPAPI_CDM_ADAPTER_H_
7
8#include <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/compiler_specific.h"
13#include "build/build_config.h"
14#include "media/cdm/ppapi/api/content_decryption_module.h"
15#include "media/cdm/ppapi/cdm_helpers.h"
16#include "media/cdm/ppapi/cdm_wrapper.h"
17#include "media/cdm/ppapi/linked_ptr.h"
18#include "ppapi/c/pp_stdint.h"
19#include "ppapi/c/private/pp_content_decryptor.h"
20#include "ppapi/cpp/completion_callback.h"
21#include "ppapi/cpp/private/content_decryptor_private.h"
22#include "ppapi/cpp/var.h"
23#include "ppapi/cpp/var_array_buffer.h"
24#include "ppapi/utility/completion_callback_factory.h"
25
26#if defined(OS_CHROMEOS)
27#include "ppapi/cpp/private/output_protection_private.h"
28#include "ppapi/cpp/private/platform_verification.h"
29#endif
30
31namespace media {
32
33// GetCdmHostFunc implementation.
34void* GetCdmHost(int host_interface_version, void* user_data);
35
36// An adapter class for abstracting away PPAPI interaction and threading for a
37// Content Decryption Module (CDM).
38class CdmAdapter : public pp::Instance,
39                   public pp::ContentDecryptor_Private,
40                   public cdm::Host_4 {
41 public:
42  CdmAdapter(PP_Instance instance, pp::Module* module);
43  virtual ~CdmAdapter();
44
45  // pp::Instance implementation.
46  virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
47    return true;
48  }
49
50  // PPP_ContentDecryptor_Private implementation.
51  // Note: Results of calls to these methods must be reported through the
52  // PPB_ContentDecryptor_Private interface.
53  virtual void Initialize(const std::string& key_system) OVERRIDE;
54  virtual void CreateSession(uint32_t session_id,
55                             const std::string& content_type,
56                             pp::VarArrayBuffer init_data) OVERRIDE;
57  virtual void LoadSession(uint32_t session_id,
58                           const std::string& web_session_id) OVERRIDE;
59  virtual void UpdateSession(uint32_t session_id,
60                             pp::VarArrayBuffer response) OVERRIDE;
61  virtual void ReleaseSession(uint32_t session_id) OVERRIDE;
62  virtual void Decrypt(
63      pp::Buffer_Dev encrypted_buffer,
64      const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE;
65  virtual void InitializeAudioDecoder(
66      const PP_AudioDecoderConfig& decoder_config,
67      pp::Buffer_Dev extra_data_buffer) OVERRIDE;
68  virtual void InitializeVideoDecoder(
69      const PP_VideoDecoderConfig& decoder_config,
70      pp::Buffer_Dev extra_data_buffer) OVERRIDE;
71  virtual void DeinitializeDecoder(PP_DecryptorStreamType decoder_type,
72                                   uint32_t request_id) OVERRIDE;
73  virtual void ResetDecoder(PP_DecryptorStreamType decoder_type,
74                            uint32_t request_id) OVERRIDE;
75  virtual void DecryptAndDecode(
76      PP_DecryptorStreamType decoder_type,
77      pp::Buffer_Dev encrypted_buffer,
78      const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE;
79
80  // cdm::Host implementation.
81  virtual cdm::Buffer* Allocate(uint32_t capacity) OVERRIDE;
82  virtual void SetTimer(int64_t delay_ms, void* context) OVERRIDE;
83  virtual double GetCurrentWallTimeInSeconds() OVERRIDE;
84  virtual void OnSessionCreated(uint32_t session_id,
85                                const char* web_session_id,
86                                uint32_t web_session_id_length) OVERRIDE;
87  virtual void OnSessionMessage(uint32_t session_id,
88                                const char* message,
89                                uint32_t message_length,
90                                const char* destination_url,
91                                uint32_t destination_url_length) OVERRIDE;
92  virtual void OnSessionReady(uint32_t session_id) OVERRIDE;
93  virtual void OnSessionClosed(uint32_t session_id) OVERRIDE;
94  virtual void OnSessionError(uint32_t session_id,
95                              cdm::MediaKeyError error_code,
96                              uint32_t system_code) OVERRIDE;
97  virtual void SendPlatformChallenge(
98      const char* service_id, uint32_t service_id_length,
99      const char* challenge, uint32_t challenge_length) OVERRIDE;
100  virtual void EnableOutputProtection(
101      uint32_t desired_protection_mask) OVERRIDE;
102  virtual void QueryOutputProtectionStatus() OVERRIDE;
103  virtual void OnDeferredInitializationDone(
104      cdm::StreamType stream_type,
105      cdm::Status decoder_status) OVERRIDE;
106  virtual cdm::FileIO* CreateFileIO(cdm::FileIOClient* client) OVERRIDE;
107
108 private:
109  typedef linked_ptr<DecryptedBlockImpl> LinkedDecryptedBlock;
110  typedef linked_ptr<VideoFrameImpl> LinkedVideoFrame;
111  typedef linked_ptr<AudioFramesImpl> LinkedAudioFrames;
112
113  bool CreateCdmInstance(const std::string& key_system);
114
115  // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to
116  // <code>callback_factory_</code> to ensure that calls into
117  // <code>PPP_ContentDecryptor_Private</code> are asynchronous.
118  void SendSessionCreatedInternal(int32_t result,
119                                  uint32_t session_id,
120                                  const std::string& web_session_id);
121  void SendSessionMessageInternal(int32_t result,
122                                  uint32_t session_id,
123                                  const std::vector<uint8>& message,
124                                  const std::string& default_url);
125  void SendSessionReadyInternal(int32_t result, uint32_t session_id);
126  void SendSessionClosedInternal(int32_t result, uint32_t session_id);
127  void SendSessionErrorInternal(int32_t result,
128                                uint32_t session_id,
129                                cdm::MediaKeyError error_code,
130                                uint32_t system_code);
131
132  void DeliverBlock(int32_t result,
133                    const cdm::Status& status,
134                    const LinkedDecryptedBlock& decrypted_block,
135                    const PP_DecryptTrackingInfo& tracking_info);
136  void DecoderInitializeDone(int32_t result,
137                             PP_DecryptorStreamType decoder_type,
138                             uint32_t request_id,
139                             bool success);
140  void DecoderDeinitializeDone(int32_t result,
141                               PP_DecryptorStreamType decoder_type,
142                               uint32_t request_id);
143  void DecoderResetDone(int32_t result,
144                        PP_DecryptorStreamType decoder_type,
145                        uint32_t request_id);
146  void DeliverFrame(int32_t result,
147                    const cdm::Status& status,
148                    const LinkedVideoFrame& video_frame,
149                    const PP_DecryptTrackingInfo& tracking_info);
150  void DeliverSamples(int32_t result,
151                      const cdm::Status& status,
152                      const LinkedAudioFrames& audio_frames,
153                      const PP_DecryptTrackingInfo& tracking_info);
154
155  // Helper for SetTimer().
156  void TimerExpired(int32_t result, void* context);
157
158  bool IsValidVideoFrame(const LinkedVideoFrame& video_frame);
159
160#if !defined(NDEBUG)
161  // Logs the given message to the JavaScript console associated with the
162  // CDM adapter instance. The name of the CDM adapter issuing the log message
163  // will be automatically prepended to the message.
164  void LogToConsole(const pp::Var& value);
165#endif  // !defined(NDEBUG)
166
167#if defined(OS_CHROMEOS)
168  void SendPlatformChallengeDone(int32_t result);
169  void EnableProtectionDone(int32_t result);
170  void QueryOutputProtectionStatusDone(int32_t result);
171
172  pp::OutputProtection_Private output_protection_;
173  pp::PlatformVerification platform_verification_;
174
175  // Since PPAPI doesn't provide handlers for CompletionCallbacks with more than
176  // one output we need to manage our own.  These values are only read by
177  // SendPlatformChallengeDone().
178  pp::Var signed_data_output_;
179  pp::Var signed_data_signature_output_;
180  pp::Var platform_key_certificate_output_;
181  bool challenge_in_progress_;
182
183  // Same as above, these are only read by QueryOutputProtectionStatusDone().
184  uint32_t output_link_mask_;
185  uint32_t output_protection_mask_;
186  bool query_output_protection_in_progress_;
187#endif
188
189  PpbBufferAllocator allocator_;
190  pp::CompletionCallbackFactory<CdmAdapter> callback_factory_;
191  linked_ptr<CdmWrapper> cdm_;
192  std::string key_system_;
193
194  // If the CDM returned kDeferredInitialization during InitializeAudioDecoder()
195  // or InitializeVideoDecoder(), the (Audio|Video)DecoderConfig.request_id is
196  // saved for the future call to OnDeferredInitializationDone().
197  bool deferred_initialize_audio_decoder_;
198  uint32_t deferred_audio_decoder_config_id_;
199  bool deferred_initialize_video_decoder_;
200  uint32_t deferred_video_decoder_config_id_;
201
202  DISALLOW_COPY_AND_ASSIGN(CdmAdapter);
203};
204
205}  // namespace media
206
207#endif  // MEDIA_CDM_PPAPI_CDM_ADAPTER_H_
208