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

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: Some iteratative work plus work related to xhwang's comments. 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 <queue>
6 #include <vector> 7 #include <vector>
7 8
8 #include "base/compiler_specific.h" // For OVERRIDE. 9 #include "base/compiler_specific.h" // For OVERRIDE.
9 #include "ppapi/c/pp_errors.h" 10 #include "ppapi/c/pp_errors.h"
10 #include "ppapi/c/pp_stdint.h" 11 #include "ppapi/c/pp_stdint.h"
12 #include "ppapi/c/dev/ppb_buffer_dev.h"
ddorwin 2012/09/04 09:53:15 Why not use cpp?
Tom Finegan 2012/09/07 00:46:36 Done, using it now.
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/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 CdmAllocator,
dmichael (off chromium) 2012/09/04 18:06:01 Is there any reason to have CdmWrapper implement t
Tom Finegan 2012/09/07 00:46:36 Done.
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 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
66 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
67 return true;
68 }
69 70
70 // PPP_ContentDecryptor_Private methods 71 // PPP_ContentDecryptor_Private methods
71 // Note: As per comments in PPP_ContentDecryptor_Private, these calls should 72 // 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 73 // 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 74 // true otherwise. Once the call reaches the CDM, the call result/status
74 // should be reported through the PPB_ContentDecryptor_Private interface. 75 // should be reported through the PPB_ContentDecryptor_Private interface.
75 virtual bool GenerateKeyRequest(const std::string& key_system, 76 virtual bool GenerateKeyRequest(const std::string& key_system,
76 pp::VarArrayBuffer init_data) OVERRIDE; 77 pp::VarArrayBuffer init_data) OVERRIDE;
77 virtual bool AddKey(const std::string& session_id, 78 virtual bool AddKey(const std::string& session_id,
78 pp::VarArrayBuffer key, 79 pp::VarArrayBuffer key,
79 pp::VarArrayBuffer init_data) OVERRIDE; 80 pp::VarArrayBuffer init_data) OVERRIDE;
80 virtual bool CancelKeyRequest(const std::string& session_id) OVERRIDE; 81 virtual bool CancelKeyRequest(const std::string& session_id) OVERRIDE;
81 virtual bool Decrypt( 82 virtual bool Decrypt(
82 pp::Buffer_Dev encrypted_buffer, 83 pp::Buffer_Dev encrypted_buffer,
83 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; 84 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE;
84 virtual bool DecryptAndDecode( 85 virtual bool DecryptAndDecode(
85 pp::Buffer_Dev encrypted_buffer, 86 pp::Buffer_Dev encrypted_buffer,
86 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; 87 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE;
87 88
89 // CdmAllocator methods.
90 virtual uint8_t* Allocate(int32_t size, int32_t* id) OVERRIDE;
91
88 private: 92 private:
89 // Creates a PP_Resource containing a PPB_Buffer_Impl, copies |data| into the 93 // 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 94 // 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 95 // ID of 0 on failure. Upon success, the returned Buffer resource has a
92 // reference count of 1. 96 // reference count of 1.
93 PP_Resource MakeBufferResource(const uint8_t* data, uint32_t data_size); 97 PP_Resource MakeBufferResource(const uint8_t* data, uint32_t data_size);
94 98
95 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to 99 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to
96 // <code>callback_factory_</code> to ensure that calls into 100 // <code>callback_factory_</code> to ensure that calls into
97 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. 101 // <code>PPP_ContentDecryptor_Private</code> are asynchronous.
98 void KeyAdded(int32_t result, const std::string& session_id); 102 void KeyAdded(int32_t result, const std::string& session_id);
99 void KeyMessage(int32_t result, cdm::KeyMessage& key_message); 103 void KeyMessage(int32_t result, cdm::KeyMessage& key_message);
100 void KeyError(int32_t result, const std::string& session_id); 104 void KeyError(int32_t result, const std::string& session_id);
101 void DeliverBlock(int32_t result, 105 void DeliverBlock(int32_t result,
102 const cdm::Status& status, 106 const cdm::Status& status,
103 cdm::OutputBuffer& output_buffer, 107 cdm::OutputBuffer& output_buffer,
104 const PP_DecryptTrackingInfo& tracking_info); 108 const PP_DecryptTrackingInfo& tracking_info);
105 109
110 const PPB_Buffer_Dev* buffer_iface_;
ddorwin 2012/09/04 09:53:15 Might be nice to keep all the raw pointers togethe
Tom Finegan 2012/09/07 00:46:36 Removed this.
106 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; 111 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_;
107 cdm::ContentDecryptionModule* cdm_; 112 cdm::ContentDecryptionModule* cdm_;
108 std::string key_system_; 113 std::string key_system_;
109 }; 114 };
110 115
111 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module) 116 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module)
112 : pp::Instance(instance), 117 : pp::Instance(instance),
113 pp::ContentDecryptor_Private(this), 118 pp::ContentDecryptor_Private(this),
119 buffer_iface_(NULL),
114 cdm_(NULL) { 120 cdm_(NULL) {
115 callback_factory_.Initialize(this); 121 callback_factory_.Initialize(this);
116 } 122 }
117 123
118 CdmWrapper::~CdmWrapper() { 124 CdmWrapper::~CdmWrapper() {
119 if (cdm_) 125 if (cdm_)
120 DestroyCdmInstance(cdm_); 126 DestroyCdmInstance(cdm_);
121 } 127 }
122 128
129 bool CdmWrapper::Init(uint32_t argc, const char* argn[], const char* argv[]) {
130 buffer_iface_ = static_cast<const PPB_Buffer_Dev*>(
ddorwin 2012/09/04 09:53:15 Why not just use the C++ object?
Tom Finegan 2012/09/07 00:46:36 Done.
131 pp::Module::Get()->GetBrowserInterface(PPB_BUFFER_DEV_INTERFACE));
132 PP_DCHECK(buffer_iface_);
133 return true;
134 }
135
123 bool CdmWrapper::GenerateKeyRequest(const std::string& key_system, 136 bool CdmWrapper::GenerateKeyRequest(const std::string& key_system,
124 pp::VarArrayBuffer init_data) { 137 pp::VarArrayBuffer init_data) {
125 PP_DCHECK(!key_system.empty()); 138 PP_DCHECK(!key_system.empty());
126 139
127 if (!cdm_) { 140 if (!cdm_) {
128 cdm_ = CreateCdmInstance(); 141 cdm_ = CreateCdmInstance();
129 if (!cdm_) 142 if (!cdm_ || !cdm_->Initialize(this))
130 return false; 143 return false;
131 } 144 }
132 145
133 cdm::KeyMessage key_request; 146 cdm::KeyMessage key_request;
134 cdm::Status status = cdm_->GenerateKeyRequest( 147 cdm::Status status = cdm_->GenerateKeyRequest(
135 reinterpret_cast<const uint8_t*>(init_data.Map()), 148 reinterpret_cast<const uint8_t*>(init_data.Map()),
136 init_data.ByteLength(), 149 init_data.ByteLength(),
137 &key_request); 150 &key_request);
138 151
139 if (status != cdm::kSuccess || 152 if (status != cdm::kSuccess ||
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 249
237 return true; 250 return true;
238 } 251 }
239 252
240 bool CdmWrapper::DecryptAndDecode( 253 bool CdmWrapper::DecryptAndDecode(
241 pp::Buffer_Dev encrypted_buffer, 254 pp::Buffer_Dev encrypted_buffer,
242 const PP_EncryptedBlockInfo& encrypted_block_info) { 255 const PP_EncryptedBlockInfo& encrypted_block_info) {
243 return false; 256 return false;
244 } 257 }
245 258
259 // This method uses the C buffer interface (PPB_Buffer_Dev) because callers
260 // require that the buffer is mapped.
ddorwin 2012/09/04 09:53:15 This might be clearer wrt transferring ownership (
Tom Finegan 2012/09/07 00:46:36 Done.
261 uint8_t* CdmWrapper::Allocate(int32_t size, int32_t* id) {
262 PP_DCHECK(size > 0);
263 PP_DCHECK(id);
264
265 PP_Resource buffer_resource = buffer_iface_->Create(pp_instance(), size);
dmichael (off chromium) 2012/09/04 18:06:01 You don't *have* to use the C interface. The alter
Tom Finegan 2012/09/07 00:46:36 Done.
266 PP_DCHECK(buffer_resource);
267 PP_DCHECK(id);
ddorwin 2012/09/04 09:53:15 delete
Tom Finegan 2012/09/07 00:46:36 Done.
268
269 void* buffer = buffer_iface_->Map(buffer_resource);
ddorwin 2012/09/04 09:53:15 Can this not fail? Seems there should either be a
Tom Finegan 2012/09/07 00:46:36 Done.
270 *id = buffer_resource;
271
272 return reinterpret_cast<uint8_t*>(buffer);
273 }
274
246 PP_Resource CdmWrapper::MakeBufferResource(const uint8_t* data, 275 PP_Resource CdmWrapper::MakeBufferResource(const uint8_t* data,
247 uint32_t data_size) { 276 uint32_t data_size) {
248 if (!data || !data_size) 277 if (!data || !data_size)
249 return 0; 278 return 0;
250 279
251 pp::Buffer_Dev buffer(this, data_size); 280 pp::Buffer_Dev buffer(this, data_size);
252 if (!buffer.data()) 281 if (!buffer.data())
253 return 0; 282 return 0;
254 283
255 memcpy(buffer.data(), data, data_size); 284 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_, 316 pp::ContentDecryptor_Private::KeyError(key_system_,
288 session_id, 317 session_id,
289 kUnknownError, 318 kUnknownError,
290 0); 319 0);
291 } 320 }
292 321
293 void CdmWrapper::DeliverBlock(int32_t result, 322 void CdmWrapper::DeliverBlock(int32_t result,
294 const cdm::Status& status, 323 const cdm::Status& status,
295 cdm::OutputBuffer& output_buffer, 324 cdm::OutputBuffer& output_buffer,
296 const PP_DecryptTrackingInfo& tracking_info) { 325 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; 326 PP_DecryptedBlockInfo decrypted_block_info;
301 decrypted_block_info.tracking_info.request_id = tracking_info.request_id; 327 decrypted_block_info.tracking_info.request_id = tracking_info.request_id;
302 decrypted_block_info.tracking_info.timestamp = output_buffer.timestamp; 328 decrypted_block_info.tracking_info.timestamp = output_buffer.timestamp;
303 329
304 switch (status) { 330 switch (status) {
305 case cdm::kSuccess: 331 case cdm::kSuccess:
306 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS; 332 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS;
307 break; 333 break;
308 case cdm::kErrorNoKey: 334 case cdm::kErrorNoKey:
309 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY; 335 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY;
310 break; 336 break;
311 default: 337 default:
312 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR; 338 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR;
313 } 339 }
314 340
315 pp::ContentDecryptor_Private::DeliverBlock(decrypted_buffer, 341 pp::ContentDecryptor_Private::DeliverBlock(output_buffer.buffer_id,
ddorwin 2012/09/04 09:53:15 This might be clearer wrt transferring ownership (
Tom Finegan 2012/09/07 00:46:36 Done.
316 decrypted_block_info); 342 decrypted_block_info);
ddorwin 2012/09/04 09:53:15 Who is dereferencing the buffer? There should be c
Tom Finegan 2012/09/07 00:46:36 I think we're OK here. The buffer has one ref in D
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; 343 output_buffer.data = NULL;
322 } 344 }
323 345
324 // This object is the global object representing this plugin library as long 346 // This object is the global object representing this plugin library as long
325 // as it is loaded. 347 // as it is loaded.
326 class MyModule : public pp::Module { 348 class MyModule : public pp::Module {
327 public: 349 public:
328 MyModule() : pp::Module() {} 350 MyModule() : pp::Module() {}
329 virtual ~MyModule() {} 351 virtual ~MyModule() {}
330 352
331 virtual pp::Instance* CreateInstance(PP_Instance instance) { 353 virtual pp::Instance* CreateInstance(PP_Instance instance) {
332 return new CdmWrapper(instance, this); 354 return new CdmWrapper(instance, this);
333 } 355 }
334 }; 356 };
335 357
336 } // namespace webkit_media 358 } // namespace webkit_media
337 359
338 namespace pp { 360 namespace pp {
339 361
340 // Factory function for your specialization of the Module object. 362 // Factory function for your specialization of the Module object.
341 Module* CreateModule() { 363 Module* CreateModule() {
342 return new webkit_media::MyModule(); 364 return new webkit_media::MyModule();
343 } 365 }
344 366
345 } // namespace pp 367 } // namespace pp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698