Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 std::memcpy. | 5 #include <cstring> // For memcpy. |
| 6 #include <vector> | |
| 6 | 7 |
| 7 #include "base/compiler_specific.h" // For OVERRIDE. | 8 #include "base/compiler_specific.h" // For OVERRIDE. |
| 8 #include "ppapi/c/pp_errors.h" | 9 #include "ppapi/c/pp_errors.h" |
| 9 #include "ppapi/c/pp_stdint.h" | 10 #include "ppapi/c/pp_stdint.h" |
| 10 #include "ppapi/c/private/pp_content_decryptor.h" | 11 #include "ppapi/c/private/pp_content_decryptor.h" |
| 11 #include "ppapi/cpp/completion_callback.h" | 12 #include "ppapi/cpp/completion_callback.h" |
| 12 #include "ppapi/cpp/core.h" | 13 #include "ppapi/cpp/core.h" |
| 13 #include "ppapi/cpp/instance.h" | 14 #include "ppapi/cpp/instance.h" |
| 14 #include "ppapi/cpp/logging.h" | 15 #include "ppapi/cpp/logging.h" |
| 15 #include "ppapi/cpp/module.h" | 16 #include "ppapi/cpp/module.h" |
| 16 #include "ppapi/cpp/pass_ref.h" | 17 #include "ppapi/cpp/pass_ref.h" |
| 17 #include "ppapi/cpp/resource.h" | 18 #include "ppapi/cpp/resource.h" |
| 18 #include "ppapi/cpp/var.h" | 19 #include "ppapi/cpp/var.h" |
| 19 #include "ppapi/cpp/var_array_buffer.h" | 20 #include "ppapi/cpp/var_array_buffer.h" |
| 20 #include "ppapi/cpp/dev/buffer_dev.h" | 21 #include "ppapi/cpp/dev/buffer_dev.h" |
| 21 #include "ppapi/cpp/private/content_decryptor_private.h" | 22 #include "ppapi/cpp/private/content_decryptor_private.h" |
| 22 #include "ppapi/utility/completion_callback_factory.h" | 23 #include "ppapi/utility/completion_callback_factory.h" |
| 24 #include "webkit/media/crypto/ppapi/content_decryption_module.h" | |
| 23 | 25 |
| 24 namespace { | 26 namespace { |
| 25 | 27 |
| 26 struct DecryptorMessage { | 28 // This needs to be consistent with media::Decryptor::KeyError! |
|
Tom Finegan
2012/08/22 16:54:31
s/needs to/must/
dmichael (off chromium)
2012/08/23 18:11:29
Should these be defined in the API? If they were,
xhwang
2012/08/24 22:01:59
Done.
xhwang
2012/08/24 22:01:59
Good point, added a TODO to add a PP_MediaKeyError
| |
| 27 DecryptorMessage() : media_error(0), system_code(0) {} | 29 enum KeyError { |
|
dmichael (off chromium)
2012/08/23 18:11:29
How about a different name, like KeyErrorCode, to
xhwang
2012/08/24 22:01:59
Renamed to MediaKeyError to be consistent to the s
| |
| 28 std::string key_system; | 30 kUnknownError = 1, |
| 29 std::string session_id; | 31 kClientError, |
| 30 std::string default_url; | 32 kServiceError, |
| 31 std::string message_data; | 33 kOutputError, |
| 32 int32_t media_error; | 34 kHardwareChangeError, |
| 33 int32_t system_code; | 35 kDomainError |
| 34 }; | |
| 35 | |
| 36 struct DecryptedBlock { | |
| 37 DecryptedBlock() { | |
| 38 std::memset(reinterpret_cast<void*>(&decrypted_block_info), | |
| 39 0, | |
| 40 sizeof(decrypted_block_info)); | |
| 41 } | |
| 42 std::string decrypted_data; | |
| 43 PP_DecryptedBlockInfo decrypted_block_info; | |
| 44 }; | 36 }; |
| 45 | 37 |
| 46 bool IsMainThread() { | 38 bool IsMainThread() { |
| 47 return pp::Module::Get()->core()->IsMainThread(); | 39 return pp::Module::Get()->core()->IsMainThread(); |
| 48 } | 40 } |
| 49 | 41 |
| 50 void CallOnMain(pp::CompletionCallback cb) { | 42 void CallOnMain(pp::CompletionCallback cb) { |
| 51 // TODO(tomfinegan): This is only necessary because PPAPI doesn't allow calls | 43 // TODO(tomfinegan): This is only necessary because PPAPI doesn't allow calls |
| 52 // off the main thread yet. Remove this once the change lands. | 44 // off the main thread yet. Remove this once the change lands. |
| 53 if (IsMainThread()) | 45 if (IsMainThread()) |
| 54 cb.Run(PP_OK); | 46 cb.Run(PP_OK); |
| 55 else | 47 else |
| 56 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK); | 48 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK); |
| 57 } | 49 } |
| 58 | 50 |
| 59 } // namespace | 51 } // namespace |
| 60 | 52 |
| 53 namespace webkit_media { | |
| 61 | 54 |
| 62 // A wrapper class for abstracting away PPAPI interaction and threading for a | 55 // A wrapper class for abstracting away PPAPI interaction and threading for a |
| 63 // Content Decryption Module (CDM). | 56 // Content Decryption Module (CDM). |
| 64 class CDMWrapper : public pp::Instance, | 57 class CdmWrapper : public pp::Instance, |
| 65 public pp::ContentDecryptor_Private { | 58 public pp::ContentDecryptor_Private { |
| 66 public: | 59 public: |
| 67 CDMWrapper(PP_Instance instance, pp::Module* module); | 60 CdmWrapper(PP_Instance instance, pp::Module* module); |
| 68 virtual ~CDMWrapper() {} | 61 virtual ~CdmWrapper(); |
| 62 | |
| 63 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { | |
| 64 return true; | |
| 65 } | |
| 69 | 66 |
| 70 // PPP_ContentDecryptor_Private methods | 67 // PPP_ContentDecryptor_Private methods |
| 71 virtual bool GenerateKeyRequest(const std::string& key_system, | 68 virtual bool GenerateKeyRequest(const std::string& key_system, |
| 72 pp::VarArrayBuffer init_data) OVERRIDE; | 69 pp::VarArrayBuffer init_data) OVERRIDE; |
| 73 virtual bool AddKey(const std::string& session_id, | 70 virtual bool AddKey(const std::string& session_id, |
| 74 pp::VarArrayBuffer key, | 71 pp::VarArrayBuffer key, |
| 75 pp::VarArrayBuffer init_data) OVERRIDE; | 72 pp::VarArrayBuffer init_data) OVERRIDE; |
| 76 virtual bool CancelKeyRequest(const std::string& session_id) OVERRIDE; | 73 virtual bool CancelKeyRequest(const std::string& session_id) OVERRIDE; |
| 77 virtual bool Decrypt( | 74 virtual bool Decrypt( |
| 78 pp::Buffer_Dev encrypted_buffer, | 75 pp::Buffer_Dev encrypted_buffer, |
| 79 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; | 76 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; |
| 80 | |
| 81 virtual bool DecryptAndDecode( | 77 virtual bool DecryptAndDecode( |
| 82 pp::Buffer_Dev encrypted_buffer, | 78 pp::Buffer_Dev encrypted_buffer, |
| 83 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE { | 79 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; |
| 84 return false; | |
| 85 } | |
| 86 | |
| 87 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { | |
| 88 return true; | |
| 89 } | |
| 90 | 80 |
| 91 private: | 81 private: |
| 92 PP_Resource StringToBufferResource(const std::string& str); | 82 PP_Resource MakeBufferResource(const uint8_t* data, uint32_t data_size); |
| 93 | 83 |
| 94 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to | 84 // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to |
| 95 // <code>callback_factory_</code> to ensure that calls into | 85 // <code>callback_factory_</code> to ensure that calls into |
| 96 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. | 86 // <code>PPP_ContentDecryptor_Private</code> are asynchronous. |
| 97 void NeedKey(int32_t result, const DecryptorMessage& decryptor_message); | 87 void KeyAdded(int32_t result, const std::string& session_id); |
|
ddorwin
2012/08/22 18:25:54
result is never used. Do we need it?
xhwang
2012/08/24 22:01:59
Even if we don't use the result, I think this is r
| |
| 98 void KeyAdded(int32_t result, const DecryptorMessage& decryptor_message); | 88 void KeyMessage(int32_t result, const cdm::KeyMessage& key_message); |
| 99 void KeyMessage(int32_t result, const DecryptorMessage& decryptor_message); | 89 void KeyError(int32_t result, const std::string& session_id); |
|
ddorwin
2012/08/22 18:25:54
Should have the two error values as parameters too
xhwang
2012/08/24 22:01:59
For now we really don't need it. If we need it in
| |
| 100 void KeyError(int32_t result, const DecryptorMessage& decryptor_message); | 90 void DeliverBlock(int32_t result, |
| 101 void DeliverBlock(int32_t result, const DecryptedBlock& decrypted_block); | 91 const cdm::Status& status, |
| 102 | 92 const cdm::OutputBuffer& output_buffer, |
| 103 pp::CompletionCallbackFactory<CDMWrapper> callback_factory_; | 93 const PP_DecryptTrackingInfo& tracking_info); |
| 94 | |
| 95 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; | |
| 96 cdm::ContentDecryptionModule* cdm_; | |
| 97 std::string key_system_; | |
| 104 }; | 98 }; |
| 105 | 99 |
| 106 CDMWrapper::CDMWrapper(PP_Instance instance, | 100 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module) |
| 107 pp::Module* module) | |
| 108 : pp::Instance(instance), | 101 : pp::Instance(instance), |
| 109 pp::ContentDecryptor_Private(this) { | 102 pp::ContentDecryptor_Private(this), |
| 103 cdm_(NULL) { | |
| 110 callback_factory_.Initialize(this); | 104 callback_factory_.Initialize(this); |
| 111 } | 105 } |
| 112 | 106 |
| 113 bool CDMWrapper::GenerateKeyRequest(const std::string& key_system, | 107 CdmWrapper::~CdmWrapper() { |
| 108 if (cdm_) | |
| 109 DestroyCdmInstance(cdm_); | |
| 110 } | |
| 111 | |
| 112 bool CdmWrapper::GenerateKeyRequest(const std::string& key_system, | |
| 114 pp::VarArrayBuffer init_data) { | 113 pp::VarArrayBuffer init_data) { |
| 115 PP_DCHECK(!key_system.empty() && init_data.ByteLength()); | 114 PP_DCHECK(!key_system.empty()); |
| 116 | 115 |
| 117 DecryptorMessage decryptor_message; | 116 if (!cdm_) { |
| 118 decryptor_message.key_system = key_system; | 117 cdm_ = CreateCdmInstance(); |
| 119 decryptor_message.session_id = "0"; | 118 if (!cdm_) { |
| 120 decryptor_message.default_url = "http://www.google.com"; | 119 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError, |
| 121 decryptor_message.message_data = "GenerateKeyRequest"; | 120 std::string())); |
|
dmichael (off chromium)
2012/08/23 18:11:29
You don't have to CallOnMainThread for this, do yo
xhwang
2012/08/24 22:01:59
See reply below.
| |
| 122 | 121 return true; |
| 123 CallOnMain(callback_factory_.NewCallback(&CDMWrapper::KeyMessage, | 122 } |
| 124 decryptor_message)); | 123 } |
| 125 return true; | 124 |
| 126 } | 125 cdm::KeyMessage key_request; |
| 127 | 126 cdm::Status status = cdm_->GenerateKeyRequest( |
| 128 bool CDMWrapper::AddKey(const std::string& session_id, | 127 reinterpret_cast<const uint8_t*>(init_data.Map()), |
| 128 init_data.ByteLength(), | |
| 129 &key_request); | |
| 130 | |
| 131 if (status != cdm::kSuccess || | |
| 132 !key_request.message || | |
| 133 key_request.message_size == 0) { | |
| 134 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError, | |
|
ddorwin
2012/08/22 18:25:54
We need to pass cdm::Status to the error. Eventual
dmichael (off chromium)
2012/08/23 18:11:29
CallOnMain isn't necessary here either (it's proba
xhwang
2012/08/24 22:01:59
As per offline discussion with dmichael@:
If runn
xhwang
2012/08/24 22:01:59
Agreed, added a TODO.
| |
| 135 std::string())); | |
|
Tom Finegan
2012/08/22 16:54:31
Seems kind of unfriendly to pass an empty string b
ddorwin
2012/08/22 18:25:54
it's the session ID, which doesn't exist yet.
| |
| 136 return true; | |
| 137 } | |
| 138 | |
| 139 key_system_ = key_system; | |
| 140 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyMessage, | |
| 141 key_request)); | |
| 142 | |
| 143 return true; | |
| 144 } | |
| 145 | |
| 146 bool CdmWrapper::AddKey(const std::string& session_id, | |
| 129 pp::VarArrayBuffer key, | 147 pp::VarArrayBuffer key, |
| 130 pp::VarArrayBuffer init_data) { | 148 pp::VarArrayBuffer init_data) { |
| 131 const std::string key_string(reinterpret_cast<char*>(key.Map()), | 149 PP_DCHECK(key.Map() && key.ByteLength() > 0); |
| 132 key.ByteLength()); | 150 PP_DCHECK(init_data.Map() && init_data.ByteLength() > 0); |
|
dmichael (off chromium)
2012/08/23 18:11:29
Please don't do Map() inside of a DCHECK. It can h
| |
| 133 const std::string init_data_string(reinterpret_cast<char*>(init_data.Map()), | 151 PP_DCHECK(cdm_); |
| 134 init_data.ByteLength()); | 152 |
| 135 | 153 cdm::Status status = cdm_->AddKey( |
| 136 PP_DCHECK(!session_id.empty() && !key_string.empty()); | 154 session_id.data(), |
| 137 | 155 session_id.size(), |
|
Tom Finegan
2012/08/22 16:54:31
I still think we should get rid of the size param
ddorwin
2012/08/22 18:25:54
This is consistent with the other parameters, and
dmichael (off chromium)
2012/08/23 18:11:29
It also makes it easier to use stuff like memcpy o
| |
| 138 DecryptorMessage decryptor_message; | 156 reinterpret_cast<const uint8_t*>(key.Map()), |
| 139 decryptor_message.key_system = "AddKey"; | 157 key.ByteLength(), |
| 140 decryptor_message.session_id = "0"; | 158 reinterpret_cast<const uint8_t*>(init_data.Map()), |
| 141 decryptor_message.default_url = "http://www.google.com"; | 159 init_data.ByteLength()); |
| 142 decryptor_message.message_data = "AddKey"; | 160 |
| 143 CallOnMain(callback_factory_.NewCallback(&CDMWrapper::KeyAdded, | 161 if (status != cdm::kSuccess) { |
| 144 decryptor_message)); | 162 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError, |
| 145 return true; | 163 session_id)); |
| 146 } | 164 return true; |
| 147 | 165 } |
| 148 bool CDMWrapper::CancelKeyRequest(const std::string& session_id) { | 166 |
| 149 // TODO(tomfinegan): cancel pending key request in CDM. | 167 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyAdded, session_id)); |
| 150 | 168 return true; |
| 151 PP_DCHECK(!session_id.empty()); | 169 } |
| 152 | 170 |
| 153 DecryptorMessage decryptor_message; | 171 bool CdmWrapper::CancelKeyRequest(const std::string& session_id) { |
| 154 decryptor_message.key_system = "CancelKeyRequest"; | 172 PP_DCHECK(cdm_); |
| 155 decryptor_message.session_id = "0"; | 173 |
| 156 decryptor_message.default_url = "http://www.google.com"; | 174 cdm::Status status = cdm_->CancelKeyRequest(session_id.data(), |
| 157 decryptor_message.message_data = "CancelKeyRequest"; | 175 session_id.size()); |
|
dmichael (off chromium)
2012/08/23 18:11:29
Could maybe be one line?
| |
| 158 | 176 |
| 159 CallOnMain(callback_factory_.NewCallback(&CDMWrapper::KeyMessage, | 177 if (status != cdm::kSuccess) { |
| 160 decryptor_message)); | 178 CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError, |
|
dmichael (off chromium)
2012/08/23 18:11:29
could be one line? (esp. since probably doesn't ne
| |
| 161 return true; | 179 session_id)); |
| 162 } | 180 return false; |
| 163 | 181 } |
| 164 bool CDMWrapper::Decrypt(pp::Buffer_Dev encrypted_buffer, | 182 |
| 183 // TODO(xhwang): Need to do anything here? Spec says TBD. | |
|
ddorwin
2012/08/22 18:25:54
I think this TBD belongs in the CDMs, not here. Th
xhwang
2012/08/24 22:01:59
Done.
| |
| 184 return true; | |
| 185 } | |
| 186 | |
| 187 bool CdmWrapper::Decrypt(pp::Buffer_Dev encrypted_buffer, | |
| 165 const PP_EncryptedBlockInfo& encrypted_block_info) { | 188 const PP_EncryptedBlockInfo& encrypted_block_info) { |
| 166 PP_DCHECK(!encrypted_buffer.is_null()); | 189 PP_DCHECK(!encrypted_buffer.is_null()); |
| 167 | 190 PP_DCHECK(cdm_); |
| 168 DecryptedBlock decrypted_block; | 191 |
| 169 decrypted_block.decrypted_data = "Pretend I'm decrypted data!"; | 192 // TODO(xhwang): Simplify the following data conversion. |
| 170 decrypted_block.decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS; | 193 cdm::InputBuffer input_buffer; |
| 171 decrypted_block.decrypted_block_info.tracking_info = | 194 input_buffer.data = reinterpret_cast<uint8_t*>(encrypted_buffer.data()); |
| 172 encrypted_block_info.tracking_info; | 195 input_buffer.data_size = encrypted_buffer.size(); |
| 173 | 196 input_buffer.data_offset = encrypted_block_info.data_offset; |
| 174 // TODO(tomfinegan): This would end up copying a lot of data in the real | 197 input_buffer.key_id = encrypted_block_info.key_id; |
| 175 // implementation if we continue passing std::strings around. It *might* not | 198 input_buffer.key_id_size = encrypted_block_info.key_id_size; |
| 176 // be such a big deal w/a real CDM. We may be able to simply pass a pointer | 199 input_buffer.iv = encrypted_block_info.iv; |
| 177 // into the CDM. Otherwise we could look into using std::tr1::shared_ptr | 200 input_buffer.iv_size = encrypted_block_info.iv_size; |
| 178 // instead of passing a giant std::string filled with encrypted data. | 201 input_buffer.checksum = encrypted_block_info.checksum; |
| 179 CallOnMain(callback_factory_.NewCallback(&CDMWrapper::DeliverBlock, | 202 input_buffer.checksum_size = encrypted_block_info.checksum_size; |
| 180 decrypted_block)); | 203 input_buffer.num_subsamples = encrypted_block_info.num_subsamples; |
| 181 return true; | 204 std::vector<cdm::SubsampleEntry> subsamples; |
| 182 } | 205 for (uint32_t i = 0; i < encrypted_block_info.num_subsamples; ++i) { |
| 183 | 206 subsamples.push_back(cdm::SubsampleEntry( |
| 184 PP_Resource CDMWrapper::StringToBufferResource(const std::string& str) { | 207 encrypted_block_info.subsamples[i].clear_bytes, |
| 185 if (str.empty()) | 208 encrypted_block_info.subsamples[i].cipher_bytes)); |
| 209 } | |
| 210 input_buffer.subsamples = &subsamples[0]; | |
| 211 input_buffer.timestamp = encrypted_block_info.tracking_info.timestamp; | |
| 212 | |
| 213 cdm::OutputBuffer output_buffer; | |
| 214 cdm::Status status = cdm_->Decrypt(input_buffer, &output_buffer); | |
|
Tom Finegan
2012/08/22 16:54:31
I think we should check this status here, and retu
ddorwin
2012/08/22 18:25:54
I've changed my mind (since our conversation) abou
xhwang
2012/08/24 22:01:59
The reason I add the comments in the IDL is to avo
xhwang
2012/08/24 22:01:59
As per the spec: 5.1. Encrypted Block Encountered:
| |
| 215 | |
| 216 CallOnMain(callback_factory_.NewCallback( | |
| 217 &CdmWrapper::DeliverBlock, | |
| 218 status, | |
| 219 output_buffer, | |
| 220 encrypted_block_info.tracking_info)); | |
| 221 | |
| 222 return true; | |
| 223 } | |
| 224 | |
| 225 bool CdmWrapper::DecryptAndDecode( | |
| 226 pp::Buffer_Dev encrypted_buffer, | |
| 227 const PP_EncryptedBlockInfo& encrypted_block_info) { | |
| 228 return false; | |
| 229 } | |
| 230 | |
|
Tom Finegan
2012/08/22 16:54:31
A comment here that this returns a resource with a
xhwang
2012/08/24 22:01:59
Done.
ddorwin
2012/08/27 17:33:54
Where is it?
xhwang
2012/08/27 18:07:26
http://codereview.chromium.org/10876014/diff/1006/
| |
| 231 PP_Resource CdmWrapper::MakeBufferResource(const uint8_t* data, | |
| 232 uint32_t data_size) { | |
|
dmichael (off chromium)
2012/08/23 18:11:29
nit: looks like data_size could fit on the previou
xhwang
2012/08/24 22:01:59
Unfortunately it doesn't fit :(
| |
| 233 if (!data || data_size == 0) | |
| 186 return 0; | 234 return 0; |
| 187 | 235 |
| 188 pp::Buffer_Dev buffer(this, str.size()); | 236 pp::Buffer_Dev buffer(this, data_size); |
| 189 if (!buffer.data()) | 237 if (!buffer.data()) |
| 190 return 0; | 238 return 0; |
| 191 | 239 |
| 192 std::memcpy(buffer.data(), str.data(), str.size()); | 240 memcpy(buffer.data(), data, data_size); |
| 241 | |
| 193 return buffer.detach(); | 242 return buffer.detach(); |
| 194 } | 243 } |
| 195 | 244 |
| 196 void CDMWrapper::NeedKey(int32_t result, | 245 void CdmWrapper::KeyAdded(int32_t result, const std::string& session_id) { |
| 197 const DecryptorMessage& decryptor_message) { | 246 pp::ContentDecryptor_Private::KeyAdded(key_system_, session_id); |
| 198 const std::string& message_data = decryptor_message.message_data; | 247 } |
| 199 pp::VarArrayBuffer init_data(message_data.size()); | 248 |
| 200 std::memcpy(init_data.Map(), message_data.data(), message_data.size()); | 249 void CdmWrapper::KeyMessage(int32_t result, |
| 201 pp::ContentDecryptor_Private::NeedKey(decryptor_message.key_system, | 250 const cdm::KeyMessage& key_message) { |
| 202 decryptor_message.session_id, | 251 pp::Buffer_Dev message_buffer(MakeBufferResource(key_message.message, |
| 203 init_data); | 252 key_message.message_size)); |
| 204 } | 253 pp::ContentDecryptor_Private::KeyMessage( |
| 205 | 254 key_system_, |
| 206 void CDMWrapper::KeyAdded(int32_t result, | 255 std::string(key_message.session_id, key_message.session_id_size), |
| 207 const DecryptorMessage& decryptor_message) { | 256 message_buffer, |
| 208 pp::ContentDecryptor_Private::KeyAdded(decryptor_message.key_system, | 257 std::string(key_message.default_url, key_message.default_url_size)); |
| 209 decryptor_message.session_id); | 258 |
| 210 } | 259 // TODO(xhwang): Fix this. This is not safe as the memory is allocated in |
|
ddorwin
2012/08/22 18:25:54
"not _always_ safe"
It works for now...
xhwang
2012/08/24 22:01:59
Done.
| |
| 211 | 260 // another object. |
|
Tom Finegan
2012/08/22 16:54:31
s/object/object that runs in a different thread/ ?
ddorwin
2012/08/22 18:25:54
It's really a different shared object. I'm sure th
xhwang
2012/08/24 22:01:59
Done.
| |
| 212 void CDMWrapper::KeyMessage(int32_t result, | 261 delete [] key_message.session_id; |
| 213 const DecryptorMessage& decryptor_message) { | 262 delete [] key_message.message; |
| 214 pp::Buffer_Dev message_buffer( | 263 delete [] key_message.default_url; |
|
dmichael (off chromium)
2012/08/23 18:11:29
Can you make cdm::KeyMessage smarter or something?
xhwang
2012/08/24 22:01:59
We have a plan which is not trivial. The above TOD
| |
| 215 StringToBufferResource(decryptor_message.message_data)); | 264 } |
| 216 pp::ContentDecryptor_Private::KeyMessage(decryptor_message.key_system, | 265 |
| 217 decryptor_message.session_id, | 266 void CdmWrapper::KeyError(int32_t result, const std::string& session_id) { |
| 218 message_buffer, | 267 pp::ContentDecryptor_Private::KeyError(key_system_, |
| 219 decryptor_message.default_url); | 268 session_id, |
| 220 } | 269 kUnknownError, |
| 221 | 270 0); |
| 222 void CDMWrapper::KeyError(int32_t result, | 271 } |
| 223 const DecryptorMessage& decryptor_message) { | 272 |
| 224 pp::ContentDecryptor_Private::KeyError(decryptor_message.key_system, | 273 void CdmWrapper::DeliverBlock(int32_t result, |
| 225 decryptor_message.session_id, | 274 const cdm::Status& status, |
| 226 decryptor_message.media_error, | 275 const cdm::OutputBuffer& output_buffer, |
|
ddorwin
2012/08/22 18:25:54
can't be const if we're deleting a member.
xhwang
2012/08/24 22:01:59
Done.
| |
| 227 decryptor_message.system_code); | 276 const PP_DecryptTrackingInfo& tracking_info) { |
| 228 } | 277 pp::Buffer_Dev decrypted_buffer(MakeBufferResource(output_buffer.data, |
| 229 | 278 output_buffer.data_size)); |
| 230 void CDMWrapper::DeliverBlock(int32_t result, | 279 |
| 231 const DecryptedBlock& decrypted_block) { | 280 PP_DecryptedBlockInfo decrypted_block_info; |
| 232 pp::Buffer_Dev decrypted_buffer( | 281 decrypted_block_info.tracking_info.request_id = tracking_info.request_id; |
| 233 StringToBufferResource(decrypted_block.decrypted_data)); | 282 decrypted_block_info.tracking_info.timestamp = output_buffer.timestamp; |
| 234 pp::ContentDecryptor_Private::DeliverBlock( | 283 |
| 235 decrypted_buffer, | 284 if (status == cdm::kSuccess) |
|
ddorwin
2012/08/22 18:25:54
switch statement? esp. useful when we have more er
xhwang
2012/08/24 22:01:59
Done.
| |
| 236 decrypted_block.decrypted_block_info); | 285 decrypted_block_info.result = PP_DECRYPTRESULT_SUCCESS; |
| 286 else if (status == cdm::kErrorNoKey) | |
| 287 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_NOKEY; | |
| 288 else // if (status == cdm::kErrorUnknown) | |
| 289 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR; | |
| 290 | |
| 291 pp::ContentDecryptor_Private::DeliverBlock(decrypted_buffer, | |
| 292 decrypted_block_info); | |
| 293 | |
| 294 // TODO(xhwang): Fix this. This is not safe as the memory is allocated in | |
| 295 // another object. | |
| 296 delete [] output_buffer.data; | |
|
ddorwin
2012/08/22 18:25:54
How do we guarantee output_buffer is not being use
xhwang
2012/08/24 22:01:59
I am not sure what's the problem? The output_buffe
ddorwin
2012/08/27 17:33:54
That answers my question. Would be nice if we coul
| |
| 237 } | 297 } |
| 238 | 298 |
| 239 // This object is the global object representing this plugin library as long | 299 // This object is the global object representing this plugin library as long |
| 240 // as it is loaded. | 300 // as it is loaded. |
| 241 class MyModule : public pp::Module { | 301 class MyModule : public pp::Module { |
| 242 public: | 302 public: |
| 243 MyModule() : pp::Module() {} | 303 MyModule() : pp::Module() {} |
| 244 virtual ~MyModule() {} | 304 virtual ~MyModule() {} |
| 245 | 305 |
| 246 virtual pp::Instance* CreateInstance(PP_Instance instance) { | 306 virtual pp::Instance* CreateInstance(PP_Instance instance) { |
| 247 return new CDMWrapper(instance, this); | 307 return new CdmWrapper(instance, this); |
| 248 } | 308 } |
| 249 }; | 309 }; |
| 250 | 310 |
| 311 } // namespace webkit_media | |
| 312 | |
| 251 namespace pp { | 313 namespace pp { |
| 252 | 314 |
| 253 // Factory function for your specialization of the Module object. | 315 // Factory function for your specialization of the Module object. |
| 254 Module* CreateModule() { | 316 Module* CreateModule() { |
| 255 return new MyModule(); | 317 return new webkit_media::MyModule(); |
| 256 } | 318 } |
| 257 | 319 |
| 258 } // namespace pp | 320 } // namespace pp |
| OLD | NEW |