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

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: Fix gyp file (remove cdm_allocator.h). 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 "base/hash_tables.h"
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"
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"
17 #include "ppapi/cpp/pass_ref.h" 18 #include "ppapi/cpp/pass_ref.h"
18 #include "ppapi/cpp/resource.h" 19 #include "ppapi/cpp/resource.h"
(...skipping 29 matching lines...) Expand all
48 if (IsMainThread()) 49 if (IsMainThread())
49 cb.Run(PP_OK); 50 cb.Run(PP_OK);
50 else 51 else
51 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK); 52 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK);
52 } 53 }
53 54
54 } // namespace 55 } // namespace
55 56
56 namespace webkit_media { 57 namespace webkit_media {
57 58
59 class PpbCdmBuffer : public cdm::Buffer {
60 public:
61 // Constructs an empty buffer.
62 PpbCdmBuffer() : buffer_(NULL), size_(0), id_(0) {}
63
64 // Constructs a buffer object containing all information necessary for a
65 // writable buffer.
66 PpbCdmBuffer(uint8_t* buffer, int32_t size, PP_Resource id)
67 : buffer_(buffer), size_(size), id_(id) {}
68
69 virtual ~PpbCdmBuffer() {}
70
71 uint8_t* buffer() const OVERRIDE { return buffer_; }
72 int32_t size() const OVERRIDE { return size_; }
73 PP_Resource id() const { return id_; }
74
75 private:
76 uint8_t* const buffer_;
77 const int32_t size_;
78 const PP_Resource id_;
79 };
dmichael (off chromium) 2012/09/10 16:10:35 It kind of looks like you don't expect this class
Tom Finegan 2012/09/11 02:58:06 Done.
80
81 class CdmAllocatorImpl : public cdm::Allocator {
82 public:
83 explicit CdmAllocatorImpl(pp::Instance* instance);
84 virtual ~CdmAllocatorImpl();
85
86 // CdmAllocator methods.
87 // Creates a pp::Buffer_Dev, stores it in |buffer_map_|, and returns the
88 // buffer identifier, pointer, and size wrapped in a cdm::Buffer*. Returns
89 // NULL on failure.
90 virtual cdm::Buffer* Allocate(int32_t size) OVERRIDE;
91
92 // Relinquishes buffer ownership by removing it from |buffer_map_|.
dmichael (off chromium) 2012/09/10 16:10:35 Maybe point out that |buffer|'s internal data is p
Tom Finegan 2012/09/11 02:58:06 Done, added mention that the buffer memory will be
93 virtual void ReleaseBuffer(const cdm::Buffer& buffer) OVERRIDE;
94
95 private:
96 typedef base::hash_map<PP_Resource, pp::Buffer_Dev> BufferMap;
97
98 pp::Instance* instance_;
99 BufferMap buffer_map_;
100 };
101
58 // A wrapper class for abstracting away PPAPI interaction and threading for a 102 // A wrapper class for abstracting away PPAPI interaction and threading for a
59 // Content Decryption Module (CDM). 103 // Content Decryption Module (CDM).
60 class CdmWrapper : public pp::Instance, 104 class CdmWrapper : public pp::Instance,
61 public pp::ContentDecryptor_Private { 105 public pp::ContentDecryptor_Private {
62 public: 106 public:
63 CdmWrapper(PP_Instance instance, pp::Module* module); 107 CdmWrapper(PP_Instance instance, pp::Module* module);
64 virtual ~CdmWrapper(); 108 virtual ~CdmWrapper();
65
66 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { 109 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
67 return true; 110 return true;
68 } 111 }
69 112
70 // PPP_ContentDecryptor_Private methods 113 // PPP_ContentDecryptor_Private methods
71 // Note: As per comments in PPP_ContentDecryptor_Private, these calls should 114 // 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 115 // 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 116 // true otherwise. Once the call reaches the CDM, the call result/status
74 // should be reported through the PPB_ContentDecryptor_Private interface. 117 // should be reported through the PPB_ContentDecryptor_Private interface.
75 virtual bool GenerateKeyRequest(const std::string& key_system, 118 virtual bool GenerateKeyRequest(const std::string& key_system,
(...skipping 20 matching lines...) Expand all
96 // <code>callback_factory_</code> to ensure that calls into 139 // <code>callback_factory_</code> to ensure that calls into
97 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. 140 // <code>PPP_ContentDecryptor_Private</code> are asynchronous.
98 void KeyAdded(int32_t result, const std::string& session_id); 141 void KeyAdded(int32_t result, const std::string& session_id);
99 void KeyMessage(int32_t result, cdm::KeyMessage& key_message); 142 void KeyMessage(int32_t result, cdm::KeyMessage& key_message);
100 void KeyError(int32_t result, const std::string& session_id); 143 void KeyError(int32_t result, const std::string& session_id);
101 void DeliverBlock(int32_t result, 144 void DeliverBlock(int32_t result,
102 const cdm::Status& status, 145 const cdm::Status& status,
103 cdm::OutputBuffer& output_buffer, 146 cdm::OutputBuffer& output_buffer,
104 const PP_DecryptTrackingInfo& tracking_info); 147 const PP_DecryptTrackingInfo& tracking_info);
105 148
149 CdmAllocatorImpl allocator_;
106 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; 150 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_;
107 cdm::ContentDecryptionModule* cdm_; 151 cdm::ContentDecryptionModule* cdm_;
108 std::string key_system_; 152 std::string key_system_;
109 }; 153 };
110 154
155 CdmAllocatorImpl::CdmAllocatorImpl(pp::Instance* instance)
156 : instance_(instance) {
157 }
158
159 CdmAllocatorImpl::~CdmAllocatorImpl() {
160 }
161
162 cdm::Buffer* CdmAllocatorImpl::Allocate(int32_t size) {
163 PP_DCHECK(size > 0);
164
165 pp::Buffer_Dev buffer(instance_, size);
166 if (buffer.is_null())
167 return NULL;
168
169 if (!buffer_map_.insert(std::make_pair(buffer.pp_resource(), buffer)).second)
170 return NULL;
171
172 return new PpbCdmBuffer(reinterpret_cast<uint8_t*>(buffer.data()),
173 buffer.size(),
174 buffer.pp_resource());
175 }
176
177 void CdmAllocatorImpl::ReleaseBuffer(const cdm::Buffer& buffer) {
178 const PpbCdmBuffer* cdm_buffer = static_cast<const PpbCdmBuffer*>(&buffer);
179 buffer_map_.erase(cdm_buffer->id());
180 }
181
111 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module) 182 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module)
112 : pp::Instance(instance), 183 : pp::Instance(instance),
113 pp::ContentDecryptor_Private(this), 184 pp::ContentDecryptor_Private(this),
185 allocator_(this),
114 cdm_(NULL) { 186 cdm_(NULL) {
115 callback_factory_.Initialize(this); 187 callback_factory_.Initialize(this);
116 } 188 }
117 189
118 CdmWrapper::~CdmWrapper() { 190 CdmWrapper::~CdmWrapper() {
119 if (cdm_) 191 if (cdm_)
120 DestroyCdmInstance(cdm_); 192 DestroyCdmInstance(cdm_);
121 } 193 }
122 194
123 bool CdmWrapper::GenerateKeyRequest(const std::string& key_system, 195 bool CdmWrapper::GenerateKeyRequest(const std::string& key_system,
124 pp::VarArrayBuffer init_data) { 196 pp::VarArrayBuffer init_data) {
125 PP_DCHECK(!key_system.empty()); 197 PP_DCHECK(!key_system.empty());
126 198
127 if (!cdm_) { 199 if (!cdm_) {
128 cdm_ = CreateCdmInstance(); 200 cdm_ = CreateCdmInstance(&allocator_);
129 if (!cdm_) 201 if (!cdm_)
130 return false; 202 return false;
131 } 203 }
132 204
133 cdm::KeyMessage key_request; 205 cdm::KeyMessage key_request;
134 cdm::Status status = cdm_->GenerateKeyRequest( 206 cdm::Status status = cdm_->GenerateKeyRequest(
135 reinterpret_cast<const uint8_t*>(init_data.Map()), 207 reinterpret_cast<const uint8_t*>(init_data.Map()),
136 init_data.ByteLength(), 208 init_data.ByteLength(),
137 &key_request); 209 &key_request);
138 210
(...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) { 292 for (uint32_t i = 0; i < encrypted_block_info.num_subsamples; ++i) {
221 subsamples.push_back(cdm::SubsampleEntry( 293 subsamples.push_back(cdm::SubsampleEntry(
222 encrypted_block_info.subsamples[i].clear_bytes, 294 encrypted_block_info.subsamples[i].clear_bytes,
223 encrypted_block_info.subsamples[i].cipher_bytes)); 295 encrypted_block_info.subsamples[i].cipher_bytes));
224 } 296 }
225 input_buffer.subsamples = &subsamples[0]; 297 input_buffer.subsamples = &subsamples[0];
226 input_buffer.timestamp = encrypted_block_info.tracking_info.timestamp; 298 input_buffer.timestamp = encrypted_block_info.tracking_info.timestamp;
227 299
228 cdm::OutputBuffer output_buffer; 300 cdm::OutputBuffer output_buffer;
229 cdm::Status status = cdm_->Decrypt(input_buffer, &output_buffer); 301 cdm::Status status = cdm_->Decrypt(input_buffer, &output_buffer);
302 PP_DCHECK(status == cdm::kSuccess);
230 303
231 CallOnMain(callback_factory_.NewCallback( 304 CallOnMain(callback_factory_.NewCallback(
232 &CdmWrapper::DeliverBlock, 305 &CdmWrapper::DeliverBlock,
233 status, 306 status,
234 output_buffer, 307 output_buffer,
235 encrypted_block_info.tracking_info)); 308 encrypted_block_info.tracking_info));
236 return true; 309 return true;
237 } 310 }
238 311
239 bool CdmWrapper::DecryptAndDecode( 312 bool CdmWrapper::DecryptAndDecode(
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 pp::ContentDecryptor_Private::KeyError(key_system_, 358 pp::ContentDecryptor_Private::KeyError(key_system_,
286 session_id, 359 session_id,
287 kUnknownError, 360 kUnknownError,
288 0); 361 0);
289 } 362 }
290 363
291 void CdmWrapper::DeliverBlock(int32_t result, 364 void CdmWrapper::DeliverBlock(int32_t result,
292 const cdm::Status& status, 365 const cdm::Status& status,
293 cdm::OutputBuffer& output_buffer, 366 cdm::OutputBuffer& output_buffer,
294 const PP_DecryptTrackingInfo& tracking_info) { 367 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; 368 PP_DecryptedBlockInfo decrypted_block_info;
298 decrypted_block_info.tracking_info.request_id = tracking_info.request_id; 369 decrypted_block_info.tracking_info.request_id = tracking_info.request_id;
299 decrypted_block_info.tracking_info.timestamp = output_buffer.timestamp; 370 decrypted_block_info.tracking_info.timestamp = output_buffer.timestamp;
300 371
301 switch (status) { 372 switch (status) {
302 case cdm::kSuccess: 373 case cdm::kSuccess:
303 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS; 374 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS;
304 break; 375 break;
305 case cdm::kNoKey: 376 case cdm::kNoKey:
306 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY; 377 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY;
307 break; 378 break;
308 default: 379 default:
309 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR; 380 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR;
310 } 381 }
311 382
312 pp::ContentDecryptor_Private::DeliverBlock(decrypted_buffer, 383 const PpbCdmBuffer* const cdm_buffer =
313 decrypted_block_info); 384 static_cast<PpbCdmBuffer*>(output_buffer.buffer);
385 PP_DCHECK(cdm_buffer);
314 386
315 // TODO(xhwang): Fix this. This is not always safe as the memory is allocated 387 pp::ContentDecryptor_Private::DeliverBlock(
316 // in another shared object. 388 pp::Buffer_Dev(pp::PassRef(), cdm_buffer->id()),
dmichael (off chromium) 2012/09/10 16:10:35 Is PassRef() the right thing here? Best I can tell
Tom Finegan 2012/09/11 02:58:06 Done, and thanks for catching this one! I took t
317 delete [] output_buffer.data; 389 decrypted_block_info);
318 output_buffer.data = NULL; 390 allocator_.ReleaseBuffer(*cdm_buffer);
391 delete cdm_buffer;
319 } 392 }
320 393
321 // This object is the global object representing this plugin library as long 394 // This object is the global object representing this plugin library as long
322 // as it is loaded. 395 // as it is loaded.
323 class MyModule : public pp::Module { 396 class CdmWrapperModule : public pp::Module {
324 public: 397 public:
325 MyModule() : pp::Module() {} 398 CdmWrapperModule() : pp::Module() {}
326 virtual ~MyModule() {} 399 virtual ~CdmWrapperModule() {}
327 400
328 virtual pp::Instance* CreateInstance(PP_Instance instance) { 401 virtual pp::Instance* CreateInstance(PP_Instance instance) {
329 return new CdmWrapper(instance, this); 402 return new CdmWrapper(instance, this);
330 } 403 }
331 }; 404 };
332 405
333 } // namespace webkit_media 406 } // namespace webkit_media
334 407
335 namespace pp { 408 namespace pp {
336 409
337 // Factory function for your specialization of the Module object. 410 // Factory function for your specialization of the Module object.
338 Module* CreateModule() { 411 Module* CreateModule() {
339 return new webkit_media::MyModule(); 412 return new webkit_media::CdmWrapperModule();
340 } 413 }
341 414
342 } // namespace pp 415 } // 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