| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <cstring> // For memcpy. | 5 #include <cstring> |
| 6 #include <string> |
| 6 #include <vector> | 7 #include <vector> |
| 7 | 8 |
| 8 #include "base/compiler_specific.h" // For OVERRIDE. | 9 #include "base/basictypes.h" |
| 10 #include "base/compiler_specific.h" |
| 9 #include "ppapi/c/pp_errors.h" | 11 #include "ppapi/c/pp_errors.h" |
| 10 #include "ppapi/c/pp_stdint.h" | 12 #include "ppapi/c/pp_stdint.h" |
| 11 #include "ppapi/c/private/pp_content_decryptor.h" | 13 #include "ppapi/c/private/pp_content_decryptor.h" |
| 12 #include "ppapi/cpp/completion_callback.h" | 14 #include "ppapi/cpp/completion_callback.h" |
| 13 #include "ppapi/cpp/core.h" | 15 #include "ppapi/cpp/core.h" |
| 14 #include "ppapi/cpp/instance.h" | 16 #include "ppapi/cpp/instance.h" |
| 15 #include "ppapi/cpp/logging.h" | 17 #include "ppapi/cpp/logging.h" |
| 16 #include "ppapi/cpp/module.h" | 18 #include "ppapi/cpp/module.h" |
| 17 #include "ppapi/cpp/pass_ref.h" | 19 #include "ppapi/cpp/pass_ref.h" |
| 18 #include "ppapi/cpp/resource.h" | 20 #include "ppapi/cpp/resource.h" |
| 19 #include "ppapi/cpp/var.h" | 21 #include "ppapi/cpp/var.h" |
| 20 #include "ppapi/cpp/var_array_buffer.h" | 22 #include "ppapi/cpp/var_array_buffer.h" |
| 21 #include "ppapi/cpp/dev/buffer_dev.h" | 23 #include "ppapi/cpp/dev/buffer_dev.h" |
| 22 #include "ppapi/cpp/private/content_decryptor_private.h" | 24 #include "ppapi/cpp/private/content_decryptor_private.h" |
| 23 #include "ppapi/utility/completion_callback_factory.h" | 25 #include "ppapi/utility/completion_callback_factory.h" |
| 26 #include "webkit/media/crypto/ppapi/linked_ptr.h" |
| 24 #include "webkit/media/crypto/ppapi/content_decryption_module.h" | 27 #include "webkit/media/crypto/ppapi/content_decryption_module.h" |
| 25 | 28 |
| 26 namespace { | 29 namespace { |
| 27 | 30 |
| 28 // This must be consistent with MediaKeyError defined in the spec: | 31 // This must be consistent with MediaKeyError defined in the spec: |
| 29 // http://goo.gl/rbdnR | 32 // http://goo.gl/rbdnR |
| 30 // TODO(xhwang): Add PP_MediaKeyError enum to avoid later static_cast in | 33 // TODO(xhwang): Add PP_MediaKeyError enum to avoid later static_cast in |
| 31 // PluginInstance. | 34 // PluginInstance. |
| 32 enum MediaKeyError { | 35 enum MediaKeyError { |
| 33 kUnknownError = 1, | 36 kUnknownError = 1, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 48 if (IsMainThread()) | 51 if (IsMainThread()) |
| 49 cb.Run(PP_OK); | 52 cb.Run(PP_OK); |
| 50 else | 53 else |
| 51 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK); | 54 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK); |
| 52 } | 55 } |
| 53 | 56 |
| 54 } // namespace | 57 } // namespace |
| 55 | 58 |
| 56 namespace webkit_media { | 59 namespace webkit_media { |
| 57 | 60 |
| 61 // Provides access to memory owned by a pp::Buffer_Dev created by |
| 62 // PpbBufferAllocator::Allocate(). This class holds a reference to the |
| 63 // Buffer_Dev throughout its lifetime. |
| 64 class PpbBuffer : public cdm::Buffer { |
| 65 public: |
| 66 // cdm::Buffer methods. |
| 67 virtual void Destroy() OVERRIDE { delete this; } |
| 68 |
| 69 virtual uint8_t* buffer() OVERRIDE { |
| 70 return static_cast<uint8_t*>(buffer_.data()); |
| 71 } |
| 72 |
| 73 virtual int32_t size() const OVERRIDE { return buffer_.size(); } |
| 74 |
| 75 pp::Buffer_Dev buffer_dev() const { return buffer_; } |
| 76 |
| 77 private: |
| 78 explicit PpbBuffer(pp::Buffer_Dev buffer) : buffer_(buffer) {} |
| 79 virtual ~PpbBuffer() {} |
| 80 |
| 81 pp::Buffer_Dev buffer_; |
| 82 |
| 83 friend class PpbBufferAllocator; |
| 84 |
| 85 DISALLOW_COPY_AND_ASSIGN(PpbBuffer); |
| 86 }; |
| 87 |
| 88 class PpbBufferAllocator : public cdm::Allocator { |
| 89 public: |
| 90 explicit PpbBufferAllocator(pp::Instance* instance); |
| 91 virtual ~PpbBufferAllocator(); |
| 92 |
| 93 // cdm::Allocator methods. |
| 94 // Allocates a pp::Buffer_Dev of the specified size and wraps it in a |
| 95 // PpbBuffer, which it returns. The caller own the returned buffer and must |
| 96 // free it by calling ReleaseBuffer(). Returns NULL on failure. |
| 97 virtual cdm::Buffer* Allocate(int32_t size) OVERRIDE; |
| 98 |
| 99 private: |
| 100 pp::Instance* const instance_; |
| 101 |
| 102 DISALLOW_COPY_AND_ASSIGN(PpbBufferAllocator); |
| 103 }; |
| 104 |
| 105 class KeyMessageImpl : public cdm::KeyMessage { |
| 106 public: |
| 107 KeyMessageImpl() : message_(NULL) {} |
| 108 virtual ~KeyMessageImpl(); |
| 109 |
| 110 // cdm::KeyMessage methods. |
| 111 virtual void set_session_id(const char* session_id, int32_t length) OVERRIDE; |
| 112 virtual const char* session_id() const OVERRIDE; |
| 113 virtual int32_t session_id_length() const OVERRIDE; |
| 114 |
| 115 virtual void set_message(cdm::Buffer* message) OVERRIDE; |
| 116 virtual cdm::Buffer* message() const OVERRIDE; |
| 117 |
| 118 virtual void set_default_url(const char* default_url, |
| 119 int32_t length) OVERRIDE; |
| 120 virtual const char* default_url() const OVERRIDE; |
| 121 virtual int32_t default_url_length() const OVERRIDE; |
| 122 |
| 123 std::string session_id_string() const { return session_id_; } |
| 124 std::string default_url_string() const { return default_url_; } |
| 125 |
| 126 private: |
| 127 PpbBuffer* message_; |
| 128 std::string session_id_; |
| 129 std::string default_url_; |
| 130 |
| 131 DISALLOW_COPY_AND_ASSIGN(KeyMessageImpl); |
| 132 }; |
| 133 |
| 134 class OutputBufferImpl : public cdm::OutputBuffer { |
| 135 public: |
| 136 OutputBufferImpl() : buffer_(NULL), timestamp_(0) {} |
| 137 virtual ~OutputBufferImpl(); |
| 138 |
| 139 virtual void set_buffer(cdm::Buffer* buffer) OVERRIDE; |
| 140 virtual cdm::Buffer* buffer() const OVERRIDE; |
| 141 |
| 142 virtual void set_timestamp(int64_t timestamp) OVERRIDE; |
| 143 virtual int64_t timestamp() const OVERRIDE; |
| 144 |
| 145 private: |
| 146 PpbBuffer* buffer_; |
| 147 int64_t timestamp_; |
| 148 |
| 149 DISALLOW_COPY_AND_ASSIGN(OutputBufferImpl); |
| 150 }; |
| 151 |
| 152 KeyMessageImpl::~KeyMessageImpl() { |
| 153 if (message_) |
| 154 message_->Destroy(); |
| 155 } |
| 156 |
| 157 void KeyMessageImpl::set_session_id(const char* session_id, int32_t length) { |
| 158 session_id_.assign(session_id, length); |
| 159 } |
| 160 |
| 161 const char* KeyMessageImpl::session_id() const { |
| 162 return session_id_.c_str(); |
| 163 } |
| 164 |
| 165 int32_t KeyMessageImpl::session_id_length() const { |
| 166 return session_id_.length(); |
| 167 } |
| 168 |
| 169 void KeyMessageImpl::set_message(cdm::Buffer* buffer) { |
| 170 message_ = static_cast<PpbBuffer*>(buffer); |
| 171 } |
| 172 |
| 173 cdm::Buffer* KeyMessageImpl::message() const { |
| 174 return message_; |
| 175 } |
| 176 |
| 177 void KeyMessageImpl::set_default_url(const char* default_url, int32_t length) { |
| 178 default_url_.assign(default_url, length); |
| 179 } |
| 180 |
| 181 const char* KeyMessageImpl::default_url() const { |
| 182 return default_url_.c_str(); |
| 183 } |
| 184 |
| 185 int32_t KeyMessageImpl::default_url_length() const { |
| 186 return default_url_.length(); |
| 187 } |
| 188 |
| 189 OutputBufferImpl::~OutputBufferImpl() { |
| 190 if (buffer_) |
| 191 buffer_->Destroy(); |
| 192 } |
| 193 |
| 194 void OutputBufferImpl::set_buffer(cdm::Buffer* buffer) { |
| 195 buffer_ = static_cast<PpbBuffer*>(buffer); |
| 196 } |
| 197 |
| 198 cdm::Buffer* OutputBufferImpl::buffer() const { |
| 199 return buffer_; |
| 200 } |
| 201 |
| 202 void OutputBufferImpl::set_timestamp(int64_t timestamp) { |
| 203 timestamp_ = timestamp; |
| 204 } |
| 205 |
| 206 int64_t OutputBufferImpl::timestamp() const { |
| 207 return timestamp_; |
| 208 } |
| 209 |
| 58 // A wrapper class for abstracting away PPAPI interaction and threading for a | 210 // A wrapper class for abstracting away PPAPI interaction and threading for a |
| 59 // Content Decryption Module (CDM). | 211 // Content Decryption Module (CDM). |
| 60 class CdmWrapper : public pp::Instance, | 212 class CdmWrapper : public pp::Instance, |
| 61 public pp::ContentDecryptor_Private { | 213 public pp::ContentDecryptor_Private { |
| 62 public: | 214 public: |
| 63 CdmWrapper(PP_Instance instance, pp::Module* module); | 215 CdmWrapper(PP_Instance instance, pp::Module* module); |
| 64 virtual ~CdmWrapper(); | 216 virtual ~CdmWrapper(); |
| 65 | |
| 66 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { | 217 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { |
| 67 return true; | 218 return true; |
| 68 } | 219 } |
| 69 | 220 |
| 70 // PPP_ContentDecryptor_Private methods | 221 // PPP_ContentDecryptor_Private methods |
| 71 // Note: As per comments in PPP_ContentDecryptor_Private, these calls should | 222 // Note: As per comments in PPP_ContentDecryptor_Private, these calls should |
| 72 // return false if the call was not forwarded to the CDM and should return | 223 // return false if the call was not forwarded to the CDM and should return |
| 73 // true otherwise. Once the call reaches the CDM, the call result/status | 224 // true otherwise. Once the call reaches the CDM, the call result/status |
| 74 // should be reported through the PPB_ContentDecryptor_Private interface. | 225 // should be reported through the PPB_ContentDecryptor_Private interface. |
| 75 virtual void GenerateKeyRequest(const std::string& key_system, | 226 virtual void GenerateKeyRequest(const std::string& key_system, |
| 76 pp::VarArrayBuffer init_data) OVERRIDE; | 227 pp::VarArrayBuffer init_data) OVERRIDE; |
| 77 virtual void AddKey(const std::string& session_id, | 228 virtual void AddKey(const std::string& session_id, |
| 78 pp::VarArrayBuffer key, | 229 pp::VarArrayBuffer key, |
| 79 pp::VarArrayBuffer init_data) OVERRIDE; | 230 pp::VarArrayBuffer init_data) OVERRIDE; |
| 80 virtual void CancelKeyRequest(const std::string& session_id) OVERRIDE; | 231 virtual void CancelKeyRequest(const std::string& session_id) OVERRIDE; |
| 81 virtual void Decrypt( | 232 virtual void Decrypt( |
| 82 pp::Buffer_Dev encrypted_buffer, | 233 pp::Buffer_Dev encrypted_buffer, |
| 83 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; | 234 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; |
| 84 virtual void DecryptAndDecode( | 235 virtual void DecryptAndDecode( |
| 85 pp::Buffer_Dev encrypted_buffer, | 236 pp::Buffer_Dev encrypted_buffer, |
| 86 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; | 237 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; |
| 87 | 238 |
| 88 private: | 239 private: |
| 89 // Creates a PP_Resource containing a PPB_Buffer_Impl, copies |data| into the | 240 typedef linked_ptr<KeyMessageImpl> LinkedKeyMessage; |
| 90 // buffer resource, and returns it. Returns a an invalid PP_Resource with an | 241 typedef linked_ptr<OutputBufferImpl> LinkedOutputBuffer; |
| 91 // ID of 0 on failure. Upon success, the returned Buffer resource has a | |
| 92 // reference count of 1. | |
| 93 pp::Buffer_Dev MakeBufferResource(const uint8_t* data, uint32_t data_size); | |
| 94 | 242 |
| 95 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to | 243 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to |
| 96 // <code>callback_factory_</code> to ensure that calls into | 244 // <code>callback_factory_</code> to ensure that calls into |
| 97 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. | 245 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. |
| 98 void KeyAdded(int32_t result, const std::string& session_id); | 246 void KeyAdded(int32_t result, const std::string& session_id); |
| 99 void KeyMessage(int32_t result, cdm::KeyMessage& key_message); | 247 void KeyMessage(int32_t result, const LinkedKeyMessage& message); |
| 100 void KeyError(int32_t result, const std::string& session_id); | 248 void KeyError(int32_t result, const std::string& session_id); |
| 101 void DeliverBlock(int32_t result, | 249 void DeliverBlock(int32_t result, |
| 102 const cdm::Status& status, | 250 const cdm::Status& status, |
| 103 cdm::OutputBuffer& output_buffer, | 251 const LinkedOutputBuffer& output_buffer, |
| 104 const PP_DecryptTrackingInfo& tracking_info); | 252 const PP_DecryptTrackingInfo& tracking_info); |
| 105 | 253 |
| 254 PpbBufferAllocator allocator_; |
| 106 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; | 255 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; |
| 107 cdm::ContentDecryptionModule* cdm_; | 256 cdm::ContentDecryptionModule* cdm_; |
| 108 std::string key_system_; | 257 std::string key_system_; |
| 109 }; | 258 }; |
| 110 | 259 |
| 260 PpbBufferAllocator::PpbBufferAllocator(pp::Instance* instance) |
| 261 : instance_(instance) { |
| 262 } |
| 263 |
| 264 PpbBufferAllocator::~PpbBufferAllocator() { |
| 265 } |
| 266 |
| 267 cdm::Buffer* PpbBufferAllocator::Allocate(int32_t size) { |
| 268 PP_DCHECK(size > 0); |
| 269 |
| 270 pp::Buffer_Dev buffer(instance_, size); |
| 271 if (buffer.is_null()) |
| 272 return NULL; |
| 273 |
| 274 return new PpbBuffer(buffer); |
| 275 } |
| 276 |
| 111 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module) | 277 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module) |
| 112 : pp::Instance(instance), | 278 : pp::Instance(instance), |
| 113 pp::ContentDecryptor_Private(this), | 279 pp::ContentDecryptor_Private(this), |
| 280 allocator_(this), |
| 114 cdm_(NULL) { | 281 cdm_(NULL) { |
| 115 callback_factory_.Initialize(this); | 282 callback_factory_.Initialize(this); |
| 116 } | 283 } |
| 117 | 284 |
| 118 CdmWrapper::~CdmWrapper() { | 285 CdmWrapper::~CdmWrapper() { |
| 119 if (cdm_) | 286 if (cdm_) |
| 120 DestroyCdmInstance(cdm_); | 287 DestroyCdmInstance(cdm_); |
| 121 } | 288 } |
| 122 | 289 |
| 123 void CdmWrapper::GenerateKeyRequest(const std::string& key_system, | 290 void CdmWrapper::GenerateKeyRequest(const std::string& key_system, |
| 124 pp::VarArrayBuffer init_data) { | 291 pp::VarArrayBuffer init_data) { |
| 125 PP_DCHECK(!key_system.empty()); | 292 PP_DCHECK(!key_system.empty()); |
| 126 | 293 |
| 127 if (!cdm_) { | 294 if (!cdm_) { |
| 128 cdm_ = CreateCdmInstance(); | 295 cdm_ = CreateCdmInstance(&allocator_); |
| 129 if (!cdm_) | 296 if (!cdm_) |
| 130 return; | 297 return; |
| 131 } | 298 } |
| 132 | 299 |
| 133 cdm::KeyMessage key_request; | 300 LinkedKeyMessage key_request(new KeyMessageImpl()); |
| 134 cdm::Status status = cdm_->GenerateKeyRequest( | 301 cdm::Status status = cdm_->GenerateKeyRequest( |
| 135 reinterpret_cast<const uint8_t*>(init_data.Map()), | 302 reinterpret_cast<const uint8_t*>(init_data.Map()), |
| 136 init_data.ByteLength(), | 303 init_data.ByteLength(), |
| 137 &key_request); | 304 key_request.get()); |
| 138 | 305 |
| 139 if (status != cdm::kSuccess || | 306 if (status != cdm::kSuccess || |
| 140 !key_request.message || | 307 !key_request->message() || |
| 141 key_request.message_size == 0) { | 308 key_request->message()->size() == 0) { |
| 142 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError, | 309 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError, |
| 143 std::string())); | 310 std::string())); |
| 144 return; | 311 return; |
| 145 } | 312 } |
| 146 | 313 |
| 147 // TODO(xhwang): Remove unnecessary CallOnMain calls here and below once we | 314 // TODO(xhwang): Remove unnecessary CallOnMain calls here and below once we |
| 148 // only support out-of-process. | 315 // only support out-of-process. |
| 149 // If running out-of-process, PPB calls will always behave asynchronously | 316 // If running out-of-process, PPB calls will always behave asynchronously |
| 150 // since IPC is involved. In that case, if we are already on main thread, | 317 // since IPC is involved. In that case, if we are already on main thread, |
| 151 // we don't need to use CallOnMain to help us call PPB call on main thread, | 318 // we don't need to use CallOnMain to help us call PPB call on main thread, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 subsamples.push_back(cdm::SubsampleEntry( | 382 subsamples.push_back(cdm::SubsampleEntry( |
| 216 encrypted_block_info.subsamples[i].clear_bytes, | 383 encrypted_block_info.subsamples[i].clear_bytes, |
| 217 encrypted_block_info.subsamples[i].cipher_bytes)); | 384 encrypted_block_info.subsamples[i].cipher_bytes)); |
| 218 } | 385 } |
| 219 | 386 |
| 220 input_buffer.subsamples = &subsamples[0]; | 387 input_buffer.subsamples = &subsamples[0]; |
| 221 } | 388 } |
| 222 | 389 |
| 223 input_buffer.timestamp = encrypted_block_info.tracking_info.timestamp; | 390 input_buffer.timestamp = encrypted_block_info.tracking_info.timestamp; |
| 224 | 391 |
| 225 cdm::OutputBuffer output_buffer; | 392 LinkedOutputBuffer output_buffer(new OutputBufferImpl()); |
| 226 cdm::Status status = cdm_->Decrypt(input_buffer, &output_buffer); | 393 cdm::Status status = cdm_->Decrypt(input_buffer, output_buffer.get()); |
| 227 | 394 |
| 395 if (status != cdm::kSuccess || !output_buffer->buffer()) { |
| 396 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError, |
| 397 std::string())); |
| 398 return; |
| 399 } |
| 400 |
| 401 PP_DCHECK(output_buffer->buffer()); |
| 228 CallOnMain(callback_factory_.NewCallback( | 402 CallOnMain(callback_factory_.NewCallback( |
| 229 &CdmWrapper::DeliverBlock, | 403 &CdmWrapper::DeliverBlock, |
| 230 status, | 404 status, |
| 231 output_buffer, | 405 output_buffer, |
| 232 encrypted_block_info.tracking_info)); | 406 encrypted_block_info.tracking_info)); |
| 233 } | 407 } |
| 234 | 408 |
| 235 void CdmWrapper::DecryptAndDecode( | 409 void CdmWrapper::DecryptAndDecode( |
| 236 pp::Buffer_Dev encrypted_buffer, | 410 pp::Buffer_Dev encrypted_buffer, |
| 237 const PP_EncryptedBlockInfo& encrypted_block_info) { | 411 const PP_EncryptedBlockInfo& encrypted_block_info) { |
| 238 } | 412 } |
| 239 | 413 |
| 240 pp::Buffer_Dev CdmWrapper::MakeBufferResource(const uint8_t* data, | |
| 241 uint32_t data_size) { | |
| 242 if (!data || !data_size) | |
| 243 return pp::Buffer_Dev(); | |
| 244 | |
| 245 pp::Buffer_Dev buffer(this, data_size); | |
| 246 if (!buffer.data()) | |
| 247 return pp::Buffer_Dev(); | |
| 248 | |
| 249 memcpy(buffer.data(), data, data_size); | |
| 250 return buffer; | |
| 251 } | |
| 252 | |
| 253 void CdmWrapper::KeyAdded(int32_t result, const std::string& session_id) { | 414 void CdmWrapper::KeyAdded(int32_t result, const std::string& session_id) { |
| 254 pp::ContentDecryptor_Private::KeyAdded(key_system_, session_id); | 415 pp::ContentDecryptor_Private::KeyAdded(key_system_, session_id); |
| 255 } | 416 } |
| 256 | 417 |
| 257 void CdmWrapper::KeyMessage(int32_t result, | 418 void CdmWrapper::KeyMessage(int32_t result, |
| 258 cdm::KeyMessage& key_message) { | 419 const LinkedKeyMessage& key_message) { |
| 259 pp::Buffer_Dev message_buffer(MakeBufferResource(key_message.message, | 420 pp::Buffer_Dev message_buffer = |
| 260 key_message.message_size)); | 421 static_cast<const PpbBuffer*>(key_message->message())->buffer_dev(); |
| 261 pp::ContentDecryptor_Private::KeyMessage( | 422 pp::ContentDecryptor_Private::KeyMessage( |
| 262 key_system_, | 423 key_system_, |
| 263 std::string(key_message.session_id, key_message.session_id_size), | 424 key_message->session_id_string(), |
| 264 message_buffer, | 425 message_buffer, |
| 265 std::string(key_message.default_url, key_message.default_url_size)); | 426 key_message->default_url_string()); |
| 266 | |
| 267 // TODO(xhwang): Fix this. This is not always safe as the memory is allocated | |
| 268 // in another shared object. | |
| 269 delete [] key_message.session_id; | |
| 270 key_message.session_id = NULL; | |
| 271 delete [] key_message.message; | |
| 272 key_message.message = NULL; | |
| 273 delete [] key_message.default_url; | |
| 274 key_message.default_url = NULL; | |
| 275 } | 427 } |
| 276 | 428 |
| 277 // TODO(xhwang): Support MediaKeyError (see spec: http://goo.gl/rbdnR) in CDM | 429 // TODO(xhwang): Support MediaKeyError (see spec: http://goo.gl/rbdnR) in CDM |
| 278 // interface and in this function. | 430 // interface and in this function. |
| 279 void CdmWrapper::KeyError(int32_t result, const std::string& session_id) { | 431 void CdmWrapper::KeyError(int32_t result, const std::string& session_id) { |
| 280 pp::ContentDecryptor_Private::KeyError(key_system_, | 432 pp::ContentDecryptor_Private::KeyError(key_system_, |
| 281 session_id, | 433 session_id, |
| 282 kUnknownError, | 434 kUnknownError, |
| 283 0); | 435 0); |
| 284 } | 436 } |
| 285 | 437 |
| 286 void CdmWrapper::DeliverBlock(int32_t result, | 438 void CdmWrapper::DeliverBlock(int32_t result, |
| 287 const cdm::Status& status, | 439 const cdm::Status& status, |
| 288 cdm::OutputBuffer& output_buffer, | 440 const LinkedOutputBuffer& output_buffer, |
| 289 const PP_DecryptTrackingInfo& tracking_info) { | 441 const PP_DecryptTrackingInfo& tracking_info) { |
| 290 pp::Buffer_Dev decrypted_buffer(MakeBufferResource(output_buffer.data, | |
| 291 output_buffer.data_size)); | |
| 292 PP_DecryptedBlockInfo decrypted_block_info; | 442 PP_DecryptedBlockInfo decrypted_block_info; |
| 293 decrypted_block_info.tracking_info.request_id = tracking_info.request_id; | 443 decrypted_block_info.tracking_info.request_id = tracking_info.request_id; |
| 294 decrypted_block_info.tracking_info.timestamp = output_buffer.timestamp; | 444 decrypted_block_info.tracking_info.timestamp = output_buffer->timestamp(); |
| 295 | 445 |
| 296 switch (status) { | 446 switch (status) { |
| 297 case cdm::kSuccess: | 447 case cdm::kSuccess: |
| 298 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS; | 448 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS; |
| 299 break; | 449 break; |
| 300 case cdm::kNoKey: | 450 case cdm::kNoKey: |
| 301 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY; | 451 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY; |
| 302 break; | 452 break; |
| 303 default: | 453 default: |
| 304 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR; | 454 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR; |
| 305 } | 455 } |
| 306 | 456 |
| 307 pp::ContentDecryptor_Private::DeliverBlock(decrypted_buffer, | 457 pp::ContentDecryptor_Private::DeliverBlock( |
| 308 decrypted_block_info); | 458 static_cast<PpbBuffer*>(output_buffer->buffer())->buffer_dev(), |
| 309 | 459 decrypted_block_info); |
| 310 // TODO(xhwang): Fix this. This is not always safe as the memory is allocated | |
| 311 // in another shared object. | |
| 312 delete [] output_buffer.data; | |
| 313 output_buffer.data = NULL; | |
| 314 } | 460 } |
| 315 | 461 |
| 316 // This object is the global object representing this plugin library as long | 462 // This object is the global object representing this plugin library as long |
| 317 // as it is loaded. | 463 // as it is loaded. |
| 318 class MyModule : public pp::Module { | 464 class CdmWrapperModule : public pp::Module { |
| 319 public: | 465 public: |
| 320 MyModule() : pp::Module() {} | 466 CdmWrapperModule() : pp::Module() {} |
| 321 virtual ~MyModule() {} | 467 virtual ~CdmWrapperModule() {} |
| 322 | 468 |
| 323 virtual pp::Instance* CreateInstance(PP_Instance instance) { | 469 virtual pp::Instance* CreateInstance(PP_Instance instance) { |
| 324 return new CdmWrapper(instance, this); | 470 return new CdmWrapper(instance, this); |
| 325 } | 471 } |
| 326 }; | 472 }; |
| 327 | 473 |
| 328 } // namespace webkit_media | 474 } // namespace webkit_media |
| 329 | 475 |
| 330 namespace pp { | 476 namespace pp { |
| 331 | 477 |
| 332 // Factory function for your specialization of the Module object. | 478 // Factory function for your specialization of the Module object. |
| 333 Module* CreateModule() { | 479 Module* CreateModule() { |
| 334 return new webkit_media::MyModule(); | 480 return new webkit_media::CdmWrapperModule(); |
| 335 } | 481 } |
| 336 | 482 |
| 337 } // namespace pp | 483 } // namespace pp |
| OLD | NEW |