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

Side by Side Diff: webkit/media/crypto/ppapi/clear_key_cdm.cc

Issue 10837252: Update CDM interface and add clear key CDM. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge "ppapi_cdm_wrapper" target into "clearkeycdmplugin". 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "webkit/media/crypto/ppapi/clear_key_cdm.h"
6
7 #include <vector>
8
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/time.h"
12 #include "media/base/decoder_buffer.h"
13
14 static const char kClearKeyCdmVersion[] = "0.1.0.0";
15
16 static scoped_refptr<media::DecoderBuffer> CopyDecoderBufferFrom(
17 const cdm::InputBuffer& input_buffer) {
18 scoped_refptr<media::DecoderBuffer> output_buffer =
19 media::DecoderBuffer::CopyFrom(input_buffer.data, input_buffer.data_size);
20
21 std::vector<media::SubsampleEntry> subsamples;
22 for (uint32_t i = 0; i < input_buffer.num_subsamples; ++i) {
23 media::SubsampleEntry subsample;
24 subsample.clear_bytes = input_buffer.subsamples[i].clear_bytes;
25 subsample.cypher_bytes = input_buffer.subsamples[i].cipher_bytes;
26 subsamples.push_back(subsample);
27 }
28
29 scoped_ptr<media::DecryptConfig> decrypt_config(new media::DecryptConfig(
30 std::string(reinterpret_cast<const char*>(input_buffer.key_id),
31 input_buffer.key_id_size),
32 std::string(reinterpret_cast<const char*>(input_buffer.iv),
33 input_buffer.iv_size),
34 std::string(reinterpret_cast<const char*>(input_buffer.checksum),
35 input_buffer.checksum_size),
36 input_buffer.data_offset,
37 subsamples));
38
39 output_buffer->SetDecryptConfig(decrypt_config.Pass());
40 output_buffer->SetTimestamp(
41 base::TimeDelta::FromMicroseconds(input_buffer.timestamp));
42
43 return output_buffer;
44 }
45
46 template<typename Type>
47 class ScopedResetter {
48 public:
49 explicit ScopedResetter(Type* object) : object_(object) {}
50 ~ScopedResetter() {
51 object_->Reset();
52 }
53
54 private:
55 Type* const object_;
56 };
57
58 template<typename Type>
59 static Type* AllocateAndCopy(const Type* data, int size) {
60 COMPILE_ASSERT(sizeof(Type) == 1, type_size_is_not_one);
61 Type* copy = new Type[size];
62 memcpy(copy, data, size);
63 return copy;
64 }
65
66 cdm::ContentDecryptionModule* CreateCdmInstance() {
67 return new webkit_media::ClearKeyCdm();
68 }
69
70 void DestroyCdmInstance(cdm::ContentDecryptionModule* instance) {
71 delete instance;
72 }
73
74 const char* GetCdmVersion() {
75 return kClearKeyCdmVersion;
76 }
77
78 namespace webkit_media {
79
80 ClearKeyCdm::Client::Client() : status_(kKeyError), key_message_length_(0) {}
81
82 ClearKeyCdm::Client::~Client() {}
83
84 void ClearKeyCdm::Client::Reset() {
85 status_ = kKeyError;
86 session_id_.clear();
87 key_message_.reset();
88 key_message_length_ = 0;
89 default_url_.clear();
90 }
91
92 void ClearKeyCdm::Client::KeyAdded(const std::string& key_system,
93 const std::string& session_id) {
94 status_ = kKeyAdded;
95 session_id_ = session_id;
96 }
97
98 void ClearKeyCdm::Client::KeyError(const std::string& key_system,
99 const std::string& session_id,
100 media::Decryptor::KeyError error_code,
101 int system_code) {
102 status_ = kKeyError;
103 session_id_ = session_id;
104 }
105
106 void ClearKeyCdm::Client::KeyMessage(const std::string& key_system,
107 const std::string& session_id,
108 scoped_array<uint8> message,
109 int message_length,
110 const std::string& default_url) {
111 status_ = kKeyMessage;
112 session_id_ = session_id;
113 key_message_ = message.Pass();
114 key_message_length_ = message_length;
115 }
116
117 void ClearKeyCdm::Client::NeedKey(const std::string& key_system,
118 const std::string& session_id,
119 scoped_array<uint8> init_data,
120 int init_data_length) {
121 // In the current implementation of AesDecryptor, NeedKey is not used.
122 // If no key is available to decrypt an input buffer, it returns kNoKey to
123 // the caller instead of firing NeedKey.
124 NOTREACHED();
125 }
126
127 ClearKeyCdm::ClearKeyCdm() : decryptor_(&client_) {}
128
129 ClearKeyCdm::~ClearKeyCdm() {}
130
131 cdm::Status ClearKeyCdm::GenerateKeyRequest(const uint8_t* init_data,
132 int init_data_size,
133 cdm::KeyMessage* key_request) {
134 DVLOG(1) << "GenerateKeyRequest()";
135 base::AutoLock auto_lock(client_lock_);
136 ScopedResetter<Client> auto_resetter(&client_);
137 decryptor_.GenerateKeyRequest("", init_data, init_data_size);
138
139 if (client_.status() != Client::kKeyMessage)
140 return cdm::kErrorUnknown;
141
142 DCHECK(key_request);
143 key_request->session_id = AllocateAndCopy(client_.session_id().data(),
144 client_.session_id().size());
145 key_request->session_id_size = client_.session_id().size();
146 key_request->message = AllocateAndCopy(client_.key_message(),
147 client_.key_message_length());
148 key_request->message_size = client_.key_message_length();
149 key_request->default_url = AllocateAndCopy(client_.default_url().data(),
150 client_.default_url().size());
151 key_request->default_url_size = client_.default_url().size();
152 return cdm::kSuccess;
153 }
154
155 cdm::Status ClearKeyCdm::AddKey(const char* session_id,
156 int session_id_size,
157 const uint8_t* key,
158 int key_size,
159 const uint8_t* key_id,
160 int key_id_size) {
161 DVLOG(1) << "AddKey()";
162 base::AutoLock auto_lock(client_lock_);
163 ScopedResetter<Client> auto_resetter(&client_);
164 decryptor_.AddKey("", key, key_size, key_id, key_id_size,
165 std::string(session_id, session_id_size));
166
167 if (client_.status() != Client::kKeyAdded)
168 return cdm::kErrorUnknown;
169
170 return cdm::kSuccess;
171 }
172
173 cdm::Status ClearKeyCdm::CancelKeyRequest(const char* session_id,
174 int session_id_size) {
175 DVLOG(1) << "CancelKeyRequest()";
176 base::AutoLock auto_lock(client_lock_);
177 ScopedResetter<Client> auto_resetter(&client_);
178 decryptor_.CancelKeyRequest("", std::string(session_id, session_id_size));
179 return cdm::kSuccess;
180 }
181
182 static void CopyDecryptResults(
183 media::Decryptor::Status* status_copy,
184 scoped_refptr<media::DecoderBuffer>* buffer_copy,
185 media::Decryptor::Status status,
186 const scoped_refptr<media::DecoderBuffer>& buffer) {
187 *status_copy = status;
188 *buffer_copy = buffer;
189 }
190
191 cdm::Status ClearKeyCdm::Decrypt(
192 const cdm::InputBuffer& encrypted_buffer,
193 cdm::OutputBuffer* decrypted_buffer) {
194 DVLOG(1) << "Decrypt()";
195
196 scoped_refptr<media::DecoderBuffer> decoder_buffer =
197 CopyDecoderBufferFrom(encrypted_buffer);
198
199 // Callback is called synchronously, so we can use variables on the stack.
200 media::Decryptor::Status status;
201 scoped_refptr<media::DecoderBuffer> buffer;
202 decryptor_.Decrypt(decoder_buffer,
203 base::Bind(&CopyDecryptResults, &status, &buffer));
204
205 if (status == media::Decryptor::kError)
206 return cdm::kErrorUnknown;
207
208 if (status == media::Decryptor::kNoKey)
209 return cdm::kErrorNoKey;
210
211 DCHECK(buffer);
212 int data_size = buffer->GetDataSize();
213 decrypted_buffer->data = AllocateAndCopy(buffer->GetData(), data_size);
214 decrypted_buffer->data_size = data_size;
215 decrypted_buffer->timestamp = buffer->GetTimestamp().InMicroseconds();
216 return cdm::kSuccess;
217 }
218
219 } // namespace webkit_media
OLDNEW
« no previous file with comments | « webkit/media/crypto/ppapi/clear_key_cdm.h ('k') | webkit/media/crypto/ppapi/content_decryption_module.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698