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

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: Address 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>
6 #include <vector> 6 #include <vector>
7 7
8 #include "base/compiler_specific.h" // For OVERRIDE. 8 #include "base/basictypes.h"
9 #include "base/compiler_specific.h"
10 #include "base/hash_tables.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"
(...skipping 29 matching lines...) Expand all
48 if (IsMainThread()) 50 if (IsMainThread())
49 cb.Run(PP_OK); 51 cb.Run(PP_OK);
50 else 52 else
51 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK); 53 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK);
52 } 54 }
53 55
54 } // namespace 56 } // namespace
55 57
56 namespace webkit_media { 58 namespace webkit_media {
57 59
60 class PpbCdmBuffer : public cdm::Buffer {
61 public:
62 // Constructs an empty buffer.
63 PpbCdmBuffer() : buffer_(NULL), size_(0), id_(0) {}
64
65 // Constructs a buffer object containing all information necessary for a
ddorwin 2012/09/12 23:53:01 This wording is a bit odd, especially such it does
Tom Finegan 2012/09/13 10:33:40 Removed. There's only one constructor now, and hop
66 // writable buffer.
67 PpbCdmBuffer(uint8_t* buffer, int32_t size, PP_Resource id)
68 : buffer_(buffer), size_(size), id_(id) {}
69
70 virtual ~PpbCdmBuffer() {}
71
72 uint8_t* buffer() const OVERRIDE { return buffer_; }
73 int32_t size() const OVERRIDE { return size_; }
74 PP_Resource id() const { return id_; }
ddorwin 2012/09/12 23:53:01 nit: Space to separate overrides.
Tom Finegan 2012/09/13 10:33:40 Done.
75
76 private:
77 uint8_t* const buffer_;
78 const int32_t size_;
79 const PP_Resource id_;
80
81 DISALLOW_COPY_AND_ASSIGN(PpbCdmBuffer);
82 };
83
84 class CdmAllocatorImpl : public cdm::Allocator {
85 public:
86 explicit CdmAllocatorImpl(pp::Instance* instance);
87 virtual ~CdmAllocatorImpl();
88
89 // CdmAllocator methods.
90 // Creates a pp::Buffer_Dev, stores it in |buffer_map_|, and returns the
91 // buffer identifier, pointer, and size wrapped in a cdm::Buffer*. Returns
92 // NULL on failure.
ddorwin 2012/09/12 23:53:01 Caller takes ownership?
Tom Finegan 2012/09/13 10:33:40 Done.
93 virtual cdm::Buffer* Allocate(int32_t size) OVERRIDE;
94
95 // Relinquishes buffer ownership by removing it from |buffer_map_|. The buffer
96 // memory will become invalid after this call returns when it results in a
97 // zero reference count on the pp::Buffer_Dev resource.
98 virtual void ReleaseBuffer(const cdm::Buffer& buffer) OVERRIDE;
99
100 private:
101 typedef base::hash_map<PP_Resource, pp::Buffer_Dev> BufferMap;
102
103 pp::Instance* instance_;
104 BufferMap buffer_map_;
ddorwin 2012/09/12 23:53:01 What do we need this map for? We only insert and r
Tom Finegan 2012/09/13 10:33:40 Removed.
105 };
106
58 // A wrapper class for abstracting away PPAPI interaction and threading for a 107 // A wrapper class for abstracting away PPAPI interaction and threading for a
59 // Content Decryption Module (CDM). 108 // Content Decryption Module (CDM).
60 class CdmWrapper : public pp::Instance, 109 class CdmWrapper : public pp::Instance,
61 public pp::ContentDecryptor_Private { 110 public pp::ContentDecryptor_Private {
62 public: 111 public:
63 CdmWrapper(PP_Instance instance, pp::Module* module); 112 CdmWrapper(PP_Instance instance, pp::Module* module);
64 virtual ~CdmWrapper(); 113 virtual ~CdmWrapper();
65
66 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { 114 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
67 return true; 115 return true;
68 } 116 }
69 117
70 // PPP_ContentDecryptor_Private methods 118 // PPP_ContentDecryptor_Private methods
71 // Note: As per comments in PPP_ContentDecryptor_Private, these calls should 119 // 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 120 // 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 121 // true otherwise. Once the call reaches the CDM, the call result/status
74 // should be reported through the PPB_ContentDecryptor_Private interface. 122 // should be reported through the PPB_ContentDecryptor_Private interface.
75 virtual bool GenerateKeyRequest(const std::string& key_system, 123 virtual bool GenerateKeyRequest(const std::string& key_system,
(...skipping 20 matching lines...) Expand all
96 // <code>callback_factory_</code> to ensure that calls into 144 // <code>callback_factory_</code> to ensure that calls into
97 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. 145 // <code>PPP_ContentDecryptor_Private</code> are asynchronous.
98 void KeyAdded(int32_t result, const std::string& session_id); 146 void KeyAdded(int32_t result, const std::string& session_id);
99 void KeyMessage(int32_t result, cdm::KeyMessage& key_message); 147 void KeyMessage(int32_t result, cdm::KeyMessage& key_message);
100 void KeyError(int32_t result, const std::string& session_id); 148 void KeyError(int32_t result, const std::string& session_id);
101 void DeliverBlock(int32_t result, 149 void DeliverBlock(int32_t result,
102 const cdm::Status& status, 150 const cdm::Status& status,
103 cdm::OutputBuffer& output_buffer, 151 cdm::OutputBuffer& output_buffer,
104 const PP_DecryptTrackingInfo& tracking_info); 152 const PP_DecryptTrackingInfo& tracking_info);
105 153
154 CdmAllocatorImpl allocator_;
106 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; 155 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_;
107 cdm::ContentDecryptionModule* cdm_; 156 cdm::ContentDecryptionModule* cdm_;
108 std::string key_system_; 157 std::string key_system_;
109 }; 158 };
110 159
160 CdmAllocatorImpl::CdmAllocatorImpl(pp::Instance* instance)
161 : instance_(instance) {
162 }
163
164 CdmAllocatorImpl::~CdmAllocatorImpl() {
165 }
166
167 cdm::Buffer* CdmAllocatorImpl::Allocate(int32_t size) {
168 PP_DCHECK(size > 0);
169
170 pp::Buffer_Dev buffer(instance_, size);
171 if (buffer.is_null())
172 return NULL;
173
174 if (!buffer_map_.insert(std::make_pair(buffer.pp_resource(), buffer)).second)
175 return NULL;
176
177 return new PpbCdmBuffer(reinterpret_cast<uint8_t*>(buffer.data()),
178 buffer.size(),
179 buffer.pp_resource());
180 }
181
182 void CdmAllocatorImpl::ReleaseBuffer(const cdm::Buffer& buffer) {
183 const PpbCdmBuffer* cdm_buffer = static_cast<const PpbCdmBuffer*>(&buffer);
184 buffer_map_.erase(cdm_buffer->id());
185 }
186
111 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module) 187 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module)
112 : pp::Instance(instance), 188 : pp::Instance(instance),
113 pp::ContentDecryptor_Private(this), 189 pp::ContentDecryptor_Private(this),
190 allocator_(this),
114 cdm_(NULL) { 191 cdm_(NULL) {
115 callback_factory_.Initialize(this); 192 callback_factory_.Initialize(this);
116 } 193 }
117 194
118 CdmWrapper::~CdmWrapper() { 195 CdmWrapper::~CdmWrapper() {
119 if (cdm_) 196 if (cdm_)
120 DestroyCdmInstance(cdm_); 197 DestroyCdmInstance(cdm_);
121 } 198 }
122 199
123 bool CdmWrapper::GenerateKeyRequest(const std::string& key_system, 200 bool CdmWrapper::GenerateKeyRequest(const std::string& key_system,
124 pp::VarArrayBuffer init_data) { 201 pp::VarArrayBuffer init_data) {
125 PP_DCHECK(!key_system.empty()); 202 PP_DCHECK(!key_system.empty());
126 203
127 if (!cdm_) { 204 if (!cdm_) {
128 cdm_ = CreateCdmInstance(); 205 cdm_ = CreateCdmInstance(&allocator_);
129 if (!cdm_) 206 if (!cdm_)
130 return false; 207 return false;
131 } 208 }
132 209
133 cdm::KeyMessage key_request; 210 cdm::KeyMessage key_request;
134 cdm::Status status = cdm_->GenerateKeyRequest( 211 cdm::Status status = cdm_->GenerateKeyRequest(
135 reinterpret_cast<const uint8_t*>(init_data.Map()), 212 reinterpret_cast<const uint8_t*>(init_data.Map()),
136 init_data.ByteLength(), 213 init_data.ByteLength(),
137 &key_request); 214 &key_request);
138 215
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 for (uint32_t i = 0; i < encrypted_block_info.num_subsamples; ++i) { 297 for (uint32_t i = 0; i < encrypted_block_info.num_subsamples; ++i) {
221 subsamples.push_back(cdm::SubsampleEntry( 298 subsamples.push_back(cdm::SubsampleEntry(
222 encrypted_block_info.subsamples[i].clear_bytes, 299 encrypted_block_info.subsamples[i].clear_bytes,
223 encrypted_block_info.subsamples[i].cipher_bytes)); 300 encrypted_block_info.subsamples[i].cipher_bytes));
224 } 301 }
225 input_buffer.subsamples = &subsamples[0]; 302 input_buffer.subsamples = &subsamples[0];
226 input_buffer.timestamp = encrypted_block_info.tracking_info.timestamp; 303 input_buffer.timestamp = encrypted_block_info.tracking_info.timestamp;
227 304
228 cdm::OutputBuffer output_buffer; 305 cdm::OutputBuffer output_buffer;
229 cdm::Status status = cdm_->Decrypt(input_buffer, &output_buffer); 306 cdm::Status status = cdm_->Decrypt(input_buffer, &output_buffer);
307 PP_DCHECK(status == cdm::kSuccess);
230 308
231 CallOnMain(callback_factory_.NewCallback( 309 CallOnMain(callback_factory_.NewCallback(
232 &CdmWrapper::DeliverBlock, 310 &CdmWrapper::DeliverBlock,
233 status, 311 status,
234 output_buffer, 312 output_buffer,
ddorwin 2012/09/12 23:53:01 The .buffer member (PpbCdmBuffer) will be leaked i
Tom Finegan 2012/09/13 10:33:40 I've moved things around a little so that OutputBu
ddorwin 2012/09/13 19:47:00 Correct, you need it. It could be deleted via the
235 encrypted_block_info.tracking_info)); 313 encrypted_block_info.tracking_info));
236 return true; 314 return true;
237 } 315 }
238 316
239 bool CdmWrapper::DecryptAndDecode( 317 bool CdmWrapper::DecryptAndDecode(
240 pp::Buffer_Dev encrypted_buffer, 318 pp::Buffer_Dev encrypted_buffer,
241 const PP_EncryptedBlockInfo& encrypted_block_info) { 319 const PP_EncryptedBlockInfo& encrypted_block_info) {
242 return false; 320 return false;
243 } 321 }
244 322
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 pp::ContentDecryptor_Private::KeyError(key_system_, 363 pp::ContentDecryptor_Private::KeyError(key_system_,
286 session_id, 364 session_id,
287 kUnknownError, 365 kUnknownError,
288 0); 366 0);
289 } 367 }
290 368
291 void CdmWrapper::DeliverBlock(int32_t result, 369 void CdmWrapper::DeliverBlock(int32_t result,
292 const cdm::Status& status, 370 const cdm::Status& status,
293 cdm::OutputBuffer& output_buffer, 371 cdm::OutputBuffer& output_buffer,
294 const PP_DecryptTrackingInfo& tracking_info) { 372 const PP_DecryptTrackingInfo& tracking_info) {
295 pp::Buffer_Dev decrypted_buffer(MakeBufferResource(output_buffer.data,
296 output_buffer.data_size));
297 PP_DecryptedBlockInfo decrypted_block_info; 373 PP_DecryptedBlockInfo decrypted_block_info;
298 decrypted_block_info.tracking_info.request_id = tracking_info.request_id; 374 decrypted_block_info.tracking_info.request_id = tracking_info.request_id;
299 decrypted_block_info.tracking_info.timestamp = output_buffer.timestamp; 375 decrypted_block_info.tracking_info.timestamp = output_buffer.timestamp;
300 376
301 switch (status) { 377 switch (status) {
302 case cdm::kSuccess: 378 case cdm::kSuccess:
303 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS; 379 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS;
304 break; 380 break;
305 case cdm::kNoKey: 381 case cdm::kNoKey:
306 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY; 382 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY;
307 break; 383 break;
308 default: 384 default:
309 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR; 385 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR;
310 } 386 }
311 387
312 pp::ContentDecryptor_Private::DeliverBlock(decrypted_buffer, 388 const PpbCdmBuffer* const cdm_buffer =
313 decrypted_block_info); 389 static_cast<PpbCdmBuffer*>(output_buffer.buffer);
390 PP_DCHECK(cdm_buffer);
314 391
315 // TODO(xhwang): Fix this. This is not always safe as the memory is allocated 392 pp::ContentDecryptor_Private::DeliverBlock(
316 // in another shared object. 393 pp::Buffer_Dev(cdm_buffer->id()),
317 delete [] output_buffer.data; 394 decrypted_block_info);
318 output_buffer.data = NULL; 395 allocator_.ReleaseBuffer(*cdm_buffer);
396 delete cdm_buffer;
319 } 397 }
320 398
321 // This object is the global object representing this plugin library as long 399 // This object is the global object representing this plugin library as long
322 // as it is loaded. 400 // as it is loaded.
323 class MyModule : public pp::Module { 401 class CdmWrapperModule : public pp::Module {
324 public: 402 public:
325 MyModule() : pp::Module() {} 403 CdmWrapperModule() : pp::Module() {}
326 virtual ~MyModule() {} 404 virtual ~CdmWrapperModule() {}
327 405
328 virtual pp::Instance* CreateInstance(PP_Instance instance) { 406 virtual pp::Instance* CreateInstance(PP_Instance instance) {
329 return new CdmWrapper(instance, this); 407 return new CdmWrapper(instance, this);
330 } 408 }
331 }; 409 };
332 410
333 } // namespace webkit_media 411 } // namespace webkit_media
334 412
335 namespace pp { 413 namespace pp {
336 414
337 // Factory function for your specialization of the Module object. 415 // Factory function for your specialization of the Module object.
338 Module* CreateModule() { 416 Module* CreateModule() {
339 return new webkit_media::MyModule(); 417 return new webkit_media::CdmWrapperModule();
340 } 418 }
341 419
342 } // namespace pp 420 } // namespace pp
OLDNEW
« no previous file with comments | « no previous file | webkit/media/crypto/ppapi/clear_key_cdm.h » ('j') | webkit/media/crypto/ppapi/content_decryption_module.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698