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

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: Refactored... quite a bit. Sorry for rebase noise on top of everything else! 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>
ddorwin 2012/09/07 09:48:48 not used
Tom Finegan 2012/09/08 01:02:47 Done.
6 #include <vector> 7 #include <vector>
7 8
8 #include "base/compiler_specific.h" // For OVERRIDE. 9 #include "base/compiler_specific.h" // For OVERRIDE.
10 #include "base/hash_tables.h"
11 #include "base/logging.h"
12 #include "base/stl_util.h"
9 #include "ppapi/c/pp_errors.h" 13 #include "ppapi/c/pp_errors.h"
10 #include "ppapi/c/pp_stdint.h" 14 #include "ppapi/c/pp_stdint.h"
15 #include "ppapi/c/dev/ppb_buffer_dev.h"
ddorwin 2012/09/07 09:48:48 Remove
Tom Finegan 2012/09/08 01:02:47 Done.
11 #include "ppapi/c/private/pp_content_decryptor.h" 16 #include "ppapi/c/private/pp_content_decryptor.h"
12 #include "ppapi/cpp/completion_callback.h" 17 #include "ppapi/cpp/completion_callback.h"
13 #include "ppapi/cpp/core.h" 18 #include "ppapi/cpp/core.h"
14 #include "ppapi/cpp/instance.h" 19 #include "ppapi/cpp/instance.h"
15 #include "ppapi/cpp/logging.h" 20 #include "ppapi/cpp/logging.h"
16 #include "ppapi/cpp/module.h" 21 #include "ppapi/cpp/module.h"
17 #include "ppapi/cpp/pass_ref.h" 22 #include "ppapi/cpp/pass_ref.h"
18 #include "ppapi/cpp/resource.h" 23 #include "ppapi/cpp/resource.h"
19 #include "ppapi/cpp/var.h" 24 #include "ppapi/cpp/var.h"
20 #include "ppapi/cpp/var_array_buffer.h" 25 #include "ppapi/cpp/var_array_buffer.h"
(...skipping 27 matching lines...) Expand all
48 if (IsMainThread()) 53 if (IsMainThread())
49 cb.Run(PP_OK); 54 cb.Run(PP_OK);
50 else 55 else
51 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK); 56 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK);
52 } 57 }
53 58
54 } // namespace 59 } // namespace
55 60
56 namespace webkit_media { 61 namespace webkit_media {
57 62
63 class CdmAllocatorImpl : public cdm::CdmAllocator {
64 public:
65 explicit CdmAllocatorImpl(pp::Instance* instance);
66 virtual ~CdmAllocatorImpl();
67
68 // CdmAllocator methods.
69 // Creates a pp::Buffer_Dev, stores it in |buffer_map_|, and returns the
70 // buffer identifier, pointer, and size wrapped in a CdmBuffer. Upon success,
71 // the returned CdmBuffer will contain non-zero buffer pointer, identifier,
72 // and size values. Otherwise, all values will be 0.
73 virtual cdm::CdmBuffer Allocate(int32_t size) OVERRIDE;
74
75 // Relinquishes buffer ownership by removing it from |buffer_map_|.
76 virtual bool ReleaseBuffer(const cdm::CdmBuffer& buffer) OVERRIDE;
77
78 private:
79 typedef base::hash_map<int32_t, pp::Buffer_Dev> BufferMap;
ddorwin 2012/09/07 09:48:48 Why not use the PP_Resource type? Inserting will c
dmichael (off chromium) 2012/09/07 16:43:43 pp::Buffer_Dev is only a handle to the buffer. Cop
Tom Finegan 2012/09/08 01:02:47 Changed int32_t in the typedef to PP_Resource for
80
81 pp::Instance* instance_;
82 BufferMap buffer_map_;
83 };
84
58 // A wrapper class for abstracting away PPAPI interaction and threading for a 85 // A wrapper class for abstracting away PPAPI interaction and threading for a
59 // Content Decryption Module (CDM). 86 // Content Decryption Module (CDM).
60 class CdmWrapper : public pp::Instance, 87 class CdmWrapper : public pp::Instance,
61 public pp::ContentDecryptor_Private { 88 public pp::ContentDecryptor_Private {
62 public: 89 public:
63 CdmWrapper(PP_Instance instance, pp::Module* module); 90 CdmWrapper(PP_Instance instance, pp::Module* module);
64 virtual ~CdmWrapper(); 91 virtual ~CdmWrapper();
65
66 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { 92 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
67 return true; 93 return true;
68 } 94 }
69 95
70 // PPP_ContentDecryptor_Private methods 96 // PPP_ContentDecryptor_Private methods
71 // Note: As per comments in PPP_ContentDecryptor_Private, these calls should 97 // 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 98 // 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 99 // true otherwise. Once the call reaches the CDM, the call result/status
74 // should be reported through the PPB_ContentDecryptor_Private interface. 100 // should be reported through the PPB_ContentDecryptor_Private interface.
75 virtual bool GenerateKeyRequest(const std::string& key_system, 101 virtual bool GenerateKeyRequest(const std::string& key_system,
(...skipping 20 matching lines...) Expand all
96 // <code>callback_factory_</code> to ensure that calls into 122 // <code>callback_factory_</code> to ensure that calls into
97 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. 123 // <code>PPP_ContentDecryptor_Private</code> are asynchronous.
98 void KeyAdded(int32_t result, const std::string& session_id); 124 void KeyAdded(int32_t result, const std::string& session_id);
99 void KeyMessage(int32_t result, cdm::KeyMessage& key_message); 125 void KeyMessage(int32_t result, cdm::KeyMessage& key_message);
100 void KeyError(int32_t result, const std::string& session_id); 126 void KeyError(int32_t result, const std::string& session_id);
101 void DeliverBlock(int32_t result, 127 void DeliverBlock(int32_t result,
102 const cdm::Status& status, 128 const cdm::Status& status,
103 cdm::OutputBuffer& output_buffer, 129 cdm::OutputBuffer& output_buffer,
104 const PP_DecryptTrackingInfo& tracking_info); 130 const PP_DecryptTrackingInfo& tracking_info);
105 131
132 CdmAllocatorImpl cdm_allocator_;
106 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; 133 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_;
107 cdm::ContentDecryptionModule* cdm_; 134 cdm::ContentDecryptionModule* cdm_;
108 std::string key_system_; 135 std::string key_system_;
109 }; 136 };
110 137
138 CdmAllocatorImpl::CdmAllocatorImpl(pp::Instance* instance)
139 : instance_(instance) {
140 }
141
142 CdmAllocatorImpl::~CdmAllocatorImpl() {
143 }
144
145 cdm::CdmBuffer CdmAllocatorImpl::Allocate(int32_t size) {
146 PP_DCHECK(size > 0);
147
148 pp::Buffer_Dev buffer(instance_, size);
149 if (buffer.is_null())
150 return cdm::CdmBuffer();
151
152 if (ContainsKey(buffer_map_, buffer.pp_resource()))
153 return cdm::CdmBuffer();
154
155 typedef std::pair<int32_t, pp::Buffer_Dev> BufferPair;
156 BufferPair pair = std::make_pair(buffer.pp_resource(), buffer);
ddorwin 2012/09/07 09:48:48 Creates a copy of the Buffer_Dev. Is that costly?
dmichael (off chromium) 2012/09/07 16:43:43 No, it's just a handle. There's just reference cou
157 buffer_map_.insert(pair);
dmichael (off chromium) 2012/09/07 16:43:43 You could just insert unconditionally, then check
Tom Finegan 2012/09/08 01:02:47 Done.
158
159 return cdm::CdmBuffer(reinterpret_cast<uint8_t*>(buffer.data()),
ddorwin 2012/09/07 09:48:48 Create PpbCdmBuffer
Tom Finegan 2012/09/08 01:02:47 Do you want me to add a CreateBuffer method to Ppb
160 buffer.pp_resource(),
161 buffer.size());
162 }
163
164 bool CdmAllocatorImpl::ReleaseBuffer(const cdm::CdmBuffer& buffer) {
165 bool result = false;
ddorwin 2012/09/07 09:48:48 Why do we need this here instead of just returning
Tom Finegan 2012/09/08 01:02:47 Done.
166 PP_DCHECK(buffer.id());
167 if (ContainsKey(buffer_map_, buffer.id())) {
168 buffer_map_.erase(buffer.id());
169 result = true;
170 }
171 return result;
172 }
173
111 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module) 174 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module)
112 : pp::Instance(instance), 175 : pp::Instance(instance),
113 pp::ContentDecryptor_Private(this), 176 pp::ContentDecryptor_Private(this),
177 cdm_allocator_(this),
114 cdm_(NULL) { 178 cdm_(NULL) {
115 callback_factory_.Initialize(this); 179 callback_factory_.Initialize(this);
116 } 180 }
117 181
118 CdmWrapper::~CdmWrapper() { 182 CdmWrapper::~CdmWrapper() {
119 if (cdm_) 183 if (cdm_)
120 DestroyCdmInstance(cdm_); 184 DestroyCdmInstance(cdm_);
121 } 185 }
122 186
123 bool CdmWrapper::GenerateKeyRequest(const std::string& key_system, 187 bool CdmWrapper::GenerateKeyRequest(const std::string& key_system,
124 pp::VarArrayBuffer init_data) { 188 pp::VarArrayBuffer init_data) {
125 PP_DCHECK(!key_system.empty()); 189 PP_DCHECK(!key_system.empty());
126 190
127 if (!cdm_) { 191 if (!cdm_) {
128 cdm_ = CreateCdmInstance(); 192 cdm_ = CreateCdmInstance(&cdm_allocator_);
129 if (!cdm_) 193 if (!cdm_)
130 return false; 194 return false;
131 } 195 }
132 196
133 cdm::KeyMessage key_request; 197 cdm::KeyMessage key_request;
134 cdm::Status status = cdm_->GenerateKeyRequest( 198 cdm::Status status = cdm_->GenerateKeyRequest(
135 reinterpret_cast<const uint8_t*>(init_data.Map()), 199 reinterpret_cast<const uint8_t*>(init_data.Map()),
136 init_data.ByteLength(), 200 init_data.ByteLength(),
137 &key_request); 201 &key_request);
138 202
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 pp::ContentDecryptor_Private::KeyError(key_system_, 349 pp::ContentDecryptor_Private::KeyError(key_system_,
286 session_id, 350 session_id,
287 kUnknownError, 351 kUnknownError,
288 0); 352 0);
289 } 353 }
290 354
291 void CdmWrapper::DeliverBlock(int32_t result, 355 void CdmWrapper::DeliverBlock(int32_t result,
292 const cdm::Status& status, 356 const cdm::Status& status,
293 cdm::OutputBuffer& output_buffer, 357 cdm::OutputBuffer& output_buffer,
294 const PP_DecryptTrackingInfo& tracking_info) { 358 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; 359 PP_DecryptedBlockInfo decrypted_block_info;
298 decrypted_block_info.tracking_info.request_id = tracking_info.request_id; 360 decrypted_block_info.tracking_info.request_id = tracking_info.request_id;
299 decrypted_block_info.tracking_info.timestamp = output_buffer.timestamp; 361 decrypted_block_info.tracking_info.timestamp = output_buffer.timestamp;
300 362
301 switch (status) { 363 switch (status) {
302 case cdm::kSuccess: 364 case cdm::kSuccess:
303 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS; 365 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS;
304 break; 366 break;
305 case cdm::kNoKey: 367 case cdm::kNoKey:
306 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY; 368 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY;
307 break; 369 break;
308 default: 370 default:
309 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR; 371 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR;
310 } 372 }
311 373
312 pp::ContentDecryptor_Private::DeliverBlock(decrypted_buffer, 374 pp::ContentDecryptor_Private::DeliverBlock(output_buffer.buffer_id,
ddorwin 2012/09/07 09:48:48 OutputBuffer should contain a CdmBuffer (pointer).
Tom Finegan 2012/09/08 01:02:47 Went w/static_cast<PpbCdmbuffer>.
313 decrypted_block_info); 375 decrypted_block_info);
314 376 if (!cdm_allocator_.ReleaseBuffer(cdm::CdmBuffer(output_buffer.buffer_id))) {
315 // TODO(xhwang): Fix this. This is not always safe as the memory is allocated 377 LOG(ERROR) << "CdmWrapper::DeliverBlock: buffer_id="
ddorwin 2012/09/07 09:48:48 DLOG. DCHECK? This should never happen, right? Yo
dmichael (off chromium) 2012/09/07 16:43:43 Does logging work here? (Maybe you want PP_DCHECK)
Tom Finegan 2012/09/08 01:02:47 Logging works, but I've removed the LOG usage-- it
316 // in another shared object. 378 << output_buffer.buffer_id << " not found!";
317 delete [] output_buffer.data; 379 }
318 output_buffer.data = NULL; 380 output_buffer.data = NULL;
319 } 381 }
320 382
321 // This object is the global object representing this plugin library as long 383 // This object is the global object representing this plugin library as long
322 // as it is loaded. 384 // as it is loaded.
323 class MyModule : public pp::Module { 385 class MyModule : public pp::Module {
324 public: 386 public:
325 MyModule() : pp::Module() {} 387 MyModule() : pp::Module() {}
326 virtual ~MyModule() {} 388 virtual ~MyModule() {}
327 389
328 virtual pp::Instance* CreateInstance(PP_Instance instance) { 390 virtual pp::Instance* CreateInstance(PP_Instance instance) {
329 return new CdmWrapper(instance, this); 391 return new CdmWrapper(instance, this);
330 } 392 }
331 }; 393 };
332 394
333 } // namespace webkit_media 395 } // namespace webkit_media
334 396
335 namespace pp { 397 namespace pp {
336 398
337 // Factory function for your specialization of the Module object. 399 // Factory function for your specialization of the Module object.
338 Module* CreateModule() { 400 Module* CreateModule() {
339 return new webkit_media::MyModule(); 401 return new webkit_media::MyModule();
340 } 402 }
341 403
342 } // namespace pp 404 } // namespace pp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698