cdm_adapter.h revision f2477e01787aa58f445919b809d89e252beef54f
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_1,
41                   public cdm::Host_2 {
42 public:
43  CdmAdapter(PP_Instance instance, pp::Module* module);
44  virtual ~CdmAdapter();
45
46  // pp::Instance implementation.
47  virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
48    return true;
49  }
50
51  // PPP_ContentDecryptor_Private implementation.
52  // Note: Results of calls to these methods must be reported through the
53  // PPB_ContentDecryptor_Private interface.
54  virtual void Initialize(const std::string& key_system) OVERRIDE;
55  virtual void GenerateKeyRequest(uint32_t reference_id,
56                                  const std::string& type,
57                                  pp::VarArrayBuffer init_data) OVERRIDE;
58  virtual void AddKey(uint32_t reference_id,
59                      pp::VarArrayBuffer key,
60                      pp::VarArrayBuffer init_data) OVERRIDE;
61  virtual void CancelKeyRequest(uint32_t reference_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 SendKeyMessage(
85      const char* session_id, uint32_t session_id_length,
86      const char* message, uint32_t message_length,
87      const char* default_url, uint32_t default_url_length) OVERRIDE;
88  virtual void SendKeyError(const char* session_id,
89                            uint32_t session_id_length,
90                            cdm::MediaKeyError error_code,
91                            uint32_t system_code) OVERRIDE;
92  virtual void GetPrivateData(int32_t* instance,
93                              GetPrivateInterface* get_interface) OVERRIDE;
94
95  // cdm::Host_2 implementation.
96  virtual void SendPlatformChallenge(
97      const char* service_id, uint32_t service_id_length,
98      const char* challenge, uint32_t challenge_length) OVERRIDE;
99  virtual void EnableOutputProtection(
100      uint32_t desired_protection_mask) OVERRIDE;
101  virtual void QueryOutputProtectionStatus() OVERRIDE;
102  virtual void OnDeferredInitializationDone(
103      cdm::StreamType stream_type,
104      cdm::Status decoder_status) OVERRIDE;
105
106 private:
107  typedef linked_ptr<DecryptedBlockImpl> LinkedDecryptedBlock;
108  typedef linked_ptr<VideoFrameImpl> LinkedVideoFrame;
109  typedef linked_ptr<AudioFramesImpl> LinkedAudioFrames;
110
111  bool CreateCdmInstance(const std::string& key_system);
112
113  void SendUnknownKeyError(uint32_t reference_id);
114  void SendKeyAdded(uint32_t reference_id);
115  void SendKeyErrorInternal(uint32_t reference_id,
116                            cdm::MediaKeyError error_code,
117                            uint32_t system_code);
118
119  // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to
120  // <code>callback_factory_</code> to ensure that calls into
121  // <code>PPP_ContentDecryptor_Private</code> are asynchronous.
122  void KeyAdded(int32_t result, uint32_t reference_id);
123  void KeyMessage(int32_t result,
124                  uint32_t reference_id,
125                  const std::vector<uint8>& message,
126                  const std::string& default_url);
127  void KeyError(int32_t result,
128                uint32_t reference_id,
129                cdm::MediaKeyError error_code,
130                uint32_t system_code);
131  void SetSessionId(int32_t result,
132                    uint32_t reference_id,
133                    const std::string& session_id);
134  void DeliverBlock(int32_t result,
135                    const cdm::Status& status,
136                    const LinkedDecryptedBlock& decrypted_block,
137                    const PP_DecryptTrackingInfo& tracking_info);
138  void DecoderInitializeDone(int32_t result,
139                             PP_DecryptorStreamType decoder_type,
140                             uint32_t request_id,
141                             bool success);
142  void DecoderDeinitializeDone(int32_t result,
143                               PP_DecryptorStreamType decoder_type,
144                               uint32_t request_id);
145  void DecoderResetDone(int32_t result,
146                        PP_DecryptorStreamType decoder_type,
147                        uint32_t request_id);
148  void DeliverFrame(int32_t result,
149                    const cdm::Status& status,
150                    const LinkedVideoFrame& video_frame,
151                    const PP_DecryptTrackingInfo& tracking_info);
152  void DeliverSamples(int32_t result,
153                      const cdm::Status& status,
154                      const LinkedAudioFrames& audio_frames,
155                      const PP_DecryptTrackingInfo& tracking_info);
156
157  // Helper for SetTimer().
158  void TimerExpired(int32_t result, void* context);
159
160  bool IsValidVideoFrame(const LinkedVideoFrame& video_frame);
161
162#if defined(OS_CHROMEOS)
163  void SendPlatformChallengeDone(int32_t result);
164  void EnableProtectionDone(int32_t result);
165  void QueryOutputProtectionStatusDone(int32_t result);
166
167  pp::OutputProtection_Private output_protection_;
168  pp::PlatformVerification platform_verification_;
169
170  // Since PPAPI doesn't provide handlers for CompletionCallbacks with more than
171  // one output we need to manage our own.  These values are only read by
172  // SendPlatformChallengeDone().
173  pp::Var signed_data_output_;
174  pp::Var signed_data_signature_output_;
175  pp::Var platform_key_certificate_output_;
176  bool challenge_in_progress_;
177
178  // Same as above, these are only read by QueryOutputProtectionStatusDone().
179  uint32_t output_link_mask_;
180  uint32_t output_protection_mask_;
181  bool query_output_protection_in_progress_;
182#endif
183
184  PpbBufferAllocator allocator_;
185  pp::CompletionCallbackFactory<CdmAdapter> callback_factory_;
186  linked_ptr<CdmWrapper> cdm_;
187  std::string key_system_;
188
189  // If the CDM returned kDeferredInitialization during InitializeAudioDecoder()
190  // or InitializeVideoDecoder(), the (Audio|Video)DecoderConfig.request_id is
191  // saved for the future call to OnDeferredInitializationDone().
192  bool deferred_initialize_audio_decoder_;
193  uint32_t deferred_audio_decoder_config_id_;
194  bool deferred_initialize_video_decoder_;
195  uint32_t deferred_video_decoder_config_id_;
196
197  DISALLOW_COPY_AND_ASSIGN(CdmAdapter);
198};
199
200}  // namespace media
201
202#endif  // MEDIA_CDM_PPAPI_CDM_ADAPTER_H_
203