Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: webkit/media/crypto/ppapi/cdm_wrapper.cc

Issue 10914028: Add CDM allocator interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: It works, and this removes a copy in Decrypt/DeliverBlock. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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> // For memcpy.
6 #include <vector> 6 #include <vector>
7 7
8 #include "base/compiler_specific.h" // For OVERRIDE. 8 #include "base/compiler_specific.h" // For OVERRIDE.
9 #include "ppapi/c/pp_errors.h" 9 #include "ppapi/c/pp_errors.h"
10 #include "ppapi/c/pp_stdint.h" 10 #include "ppapi/c/pp_stdint.h"
11 #include "ppapi/c/dev/ppb_buffer_dev.h"
11 #include "ppapi/c/private/pp_content_decryptor.h" 12 #include "ppapi/c/private/pp_content_decryptor.h"
12 #include "ppapi/cpp/completion_callback.h" 13 #include "ppapi/cpp/completion_callback.h"
13 #include "ppapi/cpp/core.h" 14 #include "ppapi/cpp/core.h"
14 #include "ppapi/cpp/instance.h" 15 #include "ppapi/cpp/instance.h"
15 #include "ppapi/cpp/logging.h" 16 #include "ppapi/cpp/logging.h"
16 #include "ppapi/cpp/module.h" 17 #include "ppapi/cpp/module.h"
18 #include "ppapi/cpp/module_impl.h"
Tom Finegan 2012/09/01 05:00:09 I might not need this-- was trying to use pp::get_
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/cdm_allocator.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 16 matching lines...) Expand all
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
58 // A wrapper class for abstracting away PPAPI interaction and threading for a 61 // A wrapper class for abstracting away PPAPI interaction and threading for a
59 // Content Decryption Module (CDM). 62 // Content Decryption Module (CDM).
60 class CdmWrapper : public pp::Instance, 63 class CdmWrapper : public CdmAllocatorInterface,
xhwang 2012/09/01 13:49:09 Instead of making the CdmWrapper a CdmAllocator, h
Tom Finegan 2012/09/01 21:32:49 It uses pp_instance(), and buffer_iface_ is now a
ddorwin 2012/09/04 09:53:15 Pass it into the constructor. Also, see my comment
64 public pp::Instance,
61 public pp::ContentDecryptor_Private { 65 public pp::ContentDecryptor_Private {
62 public: 66 public:
63 CdmWrapper(PP_Instance instance, pp::Module* module); 67 CdmWrapper(PP_Instance instance, pp::Module* module);
64 virtual ~CdmWrapper(); 68 virtual ~CdmWrapper();
65 69
66 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { 70 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
67 return true; 71 return true;
68 } 72 }
69 73
70 // PPP_ContentDecryptor_Private methods 74 // PPP_ContentDecryptor_Private methods
71 // Note: As per comments in PPP_ContentDecryptor_Private, these calls should 75 // 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 76 // 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 77 // true otherwise. Once the call reaches the CDM, the call result/status
74 // should be reported through the PPB_ContentDecryptor_Private interface. 78 // should be reported through the PPB_ContentDecryptor_Private interface.
75 virtual bool GenerateKeyRequest(const std::string& key_system, 79 virtual bool GenerateKeyRequest(const std::string& key_system,
76 pp::VarArrayBuffer init_data) OVERRIDE; 80 pp::VarArrayBuffer init_data) OVERRIDE;
77 virtual bool AddKey(const std::string& session_id, 81 virtual bool AddKey(const std::string& session_id,
78 pp::VarArrayBuffer key, 82 pp::VarArrayBuffer key,
79 pp::VarArrayBuffer init_data) OVERRIDE; 83 pp::VarArrayBuffer init_data) OVERRIDE;
80 virtual bool CancelKeyRequest(const std::string& session_id) OVERRIDE; 84 virtual bool CancelKeyRequest(const std::string& session_id) OVERRIDE;
81 virtual bool Decrypt( 85 virtual bool Decrypt(
82 pp::Buffer_Dev encrypted_buffer, 86 pp::Buffer_Dev encrypted_buffer,
83 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; 87 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE;
84 virtual bool DecryptAndDecode( 88 virtual bool DecryptAndDecode(
85 pp::Buffer_Dev encrypted_buffer, 89 pp::Buffer_Dev encrypted_buffer,
86 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; 90 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE;
87 91
92 uint8_t* Allocate(int32_t size, int32_t* id) OVERRIDE;
xhwang 2012/09/01 13:49:09 Add void Deallocate(uint8_t*, int32_t id)
Tom Finegan 2012/09/01 21:32:49 See comments in cdm_allocator.h
93
88 private: 94 private:
89 // Creates a PP_Resource containing a PPB_Buffer_Impl, copies |data| into the 95 // Creates a PP_Resource containing a PPB_Buffer_Impl, copies |data| into the
90 // buffer resource, and returns it. Returns a an invalid PP_Resource with an 96 // buffer resource, and returns it. Returns a an invalid PP_Resource with an
91 // ID of 0 on failure. Upon success, the returned Buffer resource has a 97 // ID of 0 on failure. Upon success, the returned Buffer resource has a
92 // reference count of 1. 98 // reference count of 1.
93 PP_Resource MakeBufferResource(const uint8_t* data, uint32_t data_size); 99 PP_Resource MakeBufferResource(const uint8_t* data, uint32_t data_size);
94 100
95 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to 101 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to
96 // <code>callback_factory_</code> to ensure that calls into 102 // <code>callback_factory_</code> to ensure that calls into
97 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. 103 // <code>PPP_ContentDecryptor_Private</code> are asynchronous.
(...skipping 23 matching lines...) Expand all
121 } 127 }
122 128
123 bool CdmWrapper::GenerateKeyRequest(const std::string& key_system, 129 bool CdmWrapper::GenerateKeyRequest(const std::string& key_system,
124 pp::VarArrayBuffer init_data) { 130 pp::VarArrayBuffer init_data) {
125 PP_DCHECK(!key_system.empty()); 131 PP_DCHECK(!key_system.empty());
126 132
127 if (!cdm_) { 133 if (!cdm_) {
128 cdm_ = CreateCdmInstance(); 134 cdm_ = CreateCdmInstance();
129 if (!cdm_) 135 if (!cdm_)
130 return false; 136 return false;
137 if (!cdm_->Initialize(this))
xhwang 2012/09/01 13:49:09 Merge these two if's to: if (!cdm_ || !cdm_->Initi
Tom Finegan 2012/09/01 21:32:49 Done.
138 return false;
131 } 139 }
132 140
133 cdm::KeyMessage key_request; 141 cdm::KeyMessage key_request;
134 cdm::Status status = cdm_->GenerateKeyRequest( 142 cdm::Status status = cdm_->GenerateKeyRequest(
135 reinterpret_cast<const uint8_t*>(init_data.Map()), 143 reinterpret_cast<const uint8_t*>(init_data.Map()),
136 init_data.ByteLength(), 144 init_data.ByteLength(),
137 &key_request); 145 &key_request);
138 146
139 if (status != cdm::kSuccess || 147 if (status != cdm::kSuccess ||
140 !key_request.message || 148 !key_request.message ||
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 244
237 return true; 245 return true;
238 } 246 }
239 247
240 bool CdmWrapper::DecryptAndDecode( 248 bool CdmWrapper::DecryptAndDecode(
241 pp::Buffer_Dev encrypted_buffer, 249 pp::Buffer_Dev encrypted_buffer,
242 const PP_EncryptedBlockInfo& encrypted_block_info) { 250 const PP_EncryptedBlockInfo& encrypted_block_info) {
243 return false; 251 return false;
244 } 252 }
245 253
254 // This method uses the C buffer interface (PPB_Buffer_Dev) because callers
255 // require that the buffer is mapped.
256 uint8_t* CdmWrapper::Allocate(int32_t size, int32_t* id) {
257 PP_DCHECK(size > 0);
258 PP_DCHECK(id);
259
260 const PPB_Buffer_Dev* buffer_iface = static_cast<const PPB_Buffer_Dev*>(
261 pp::Module::Get()->GetBrowserInterface(PPB_BUFFER_DEV_INTERFACE));
262 PP_DCHECK(buffer_iface);
Tom Finegan 2012/09/01 05:00:09 I'll move this to Init and make buffer_iface a mem
Tom Finegan 2012/09/01 21:32:49 Done.
263
264 PP_Resource buffer_resource = buffer_iface->Create(pp_instance(), size);
265 PP_DCHECK(buffer_resource);
266 PP_DCHECK(id);
267
268 void* buffer = buffer_iface->Map(buffer_resource);
269 *id = buffer_resource;
270
271 return reinterpret_cast<uint8_t*>(buffer);
272 }
273
246 PP_Resource CdmWrapper::MakeBufferResource(const uint8_t* data, 274 PP_Resource CdmWrapper::MakeBufferResource(const uint8_t* data,
247 uint32_t data_size) { 275 uint32_t data_size) {
248 if (!data || !data_size) 276 if (!data || !data_size)
249 return 0; 277 return 0;
250 278
251 pp::Buffer_Dev buffer(this, data_size); 279 pp::Buffer_Dev buffer(this, data_size);
252 if (!buffer.data()) 280 if (!buffer.data())
253 return 0; 281 return 0;
254 282
255 memcpy(buffer.data(), data, data_size); 283 memcpy(buffer.data(), data, data_size);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 pp::ContentDecryptor_Private::KeyError(key_system_, 315 pp::ContentDecryptor_Private::KeyError(key_system_,
288 session_id, 316 session_id,
289 kUnknownError, 317 kUnknownError,
290 0); 318 0);
291 } 319 }
292 320
293 void CdmWrapper::DeliverBlock(int32_t result, 321 void CdmWrapper::DeliverBlock(int32_t result,
294 const cdm::Status& status, 322 const cdm::Status& status,
295 cdm::OutputBuffer& output_buffer, 323 cdm::OutputBuffer& output_buffer,
296 const PP_DecryptTrackingInfo& tracking_info) { 324 const PP_DecryptTrackingInfo& tracking_info) {
297 pp::Buffer_Dev decrypted_buffer(MakeBufferResource(output_buffer.data,
298 output_buffer.data_size));
299
300 PP_DecryptedBlockInfo decrypted_block_info; 325 PP_DecryptedBlockInfo decrypted_block_info;
301 decrypted_block_info.tracking_info.request_id = tracking_info.request_id; 326 decrypted_block_info.tracking_info.request_id = tracking_info.request_id;
302 decrypted_block_info.tracking_info.timestamp = output_buffer.timestamp; 327 decrypted_block_info.tracking_info.timestamp = output_buffer.timestamp;
303 328
304 switch (status) { 329 switch (status) {
305 case cdm::kSuccess: 330 case cdm::kSuccess:
306 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS; 331 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS;
307 break; 332 break;
308 case cdm::kErrorNoKey: 333 case cdm::kErrorNoKey:
309 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY; 334 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY;
310 break; 335 break;
311 default: 336 default:
312 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR; 337 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR;
313 } 338 }
314 339
315 pp::ContentDecryptor_Private::DeliverBlock(decrypted_buffer, 340 pp::ContentDecryptor_Private::DeliverBlock(output_buffer.buffer_id,
316 decrypted_block_info); 341 decrypted_block_info);
317
318 // TODO(xhwang): Fix this. This is not always safe as the memory is allocated
319 // in another shared object.
320 delete [] output_buffer.data;
321 output_buffer.data = NULL; 342 output_buffer.data = NULL;
322 } 343 }
323 344
324 // This object is the global object representing this plugin library as long 345 // This object is the global object representing this plugin library as long
325 // as it is loaded. 346 // as it is loaded.
326 class MyModule : public pp::Module { 347 class MyModule : public pp::Module {
327 public: 348 public:
328 MyModule() : pp::Module() {} 349 MyModule() : pp::Module() {}
329 virtual ~MyModule() {} 350 virtual ~MyModule() {}
330 351
331 virtual pp::Instance* CreateInstance(PP_Instance instance) { 352 virtual pp::Instance* CreateInstance(PP_Instance instance) {
332 return new CdmWrapper(instance, this); 353 return new CdmWrapper(instance, this);
333 } 354 }
334 }; 355 };
335 356
336 } // namespace webkit_media 357 } // namespace webkit_media
337 358
338 namespace pp { 359 namespace pp {
339 360
340 // Factory function for your specialization of the Module object. 361 // Factory function for your specialization of the Module object.
341 Module* CreateModule() { 362 Module* CreateModule() {
342 return new webkit_media::MyModule(); 363 return new webkit_media::MyModule();
343 } 364 }
344 365
345 } // namespace pp 366 } // namespace pp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698