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

Side by Side Diff: webkit/media/crypto/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: Resolve comments. Created 8 years, 4 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/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 (unsigned int i = 0; i < input_buffer.num_subsamples; ++i) {
ddorwin 2012/08/16 05:00:35 unit32_t. No reason to mix type synonyms and risks
xhwang 2012/08/16 17:19:01 Done.
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),
ddorwin 2012/08/16 05:00:35 Can we avoid a copy with StringPiece?
xhwang 2012/08/16 17:19:01 DecryptConfig's ctor takes std::string. I think th
31 input_buffer.key_id_size),
32 std::string(reinterpret_cast<const char*>(input_buffer.iv),
33 input_buffer.key_id_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::FromMilliseconds(input_buffer.timestamp));
42 output_buffer->SetDuration(
43 base::TimeDelta::FromMilliseconds(input_buffer.duration));
44
45 return output_buffer;
46 }
47
48 template<typename Type>
49 class ScopedResetter {
50 public:
51 explicit ScopedResetter(Type* object) : object_(object) {}
52 ~ScopedResetter() {
53 object_->Reset();
54 }
55
56 private:
57 Type* const object_;
58 };
59
60 template<typename Type>
61 static Type* AllocateAndCopy(const Type* data, int size) {
62 COMPILE_ASSERT(sizeof(Type) == 1, type_size_is_not_one);
63 Type* copy = new Type[size];
64 memcpy(copy, data, size);
65 return copy;
66 }
67
68 cdm::ContentDecryptionModule* CdmCreateInstance() {
69 return new webkit_media::ClearKeyCdm();
70 }
71
72 void CdmDestroyInstance(cdm::ContentDecryptionModule* instance) {
73 delete instance;
74 }
75
76 const char* CdmGetVersion() {
77 return kClearKeyCdmVersion;
78 }
79
80 namespace webkit_media {
81
82 ClearKeyCdm::Client::Client() : status_(kKeyError), key_message_length_(0) {}
83
84 ClearKeyCdm::Client::~Client() {}
85
86 void ClearKeyCdm::Client::Reset() {
87 status_ = kKeyError;
88 session_id_.clear();
89 key_message_.reset();
90 key_message_length_ = 0;
91 default_url_.clear();
92 }
93
94 void ClearKeyCdm::Client::KeyAdded(const std::string& key_system,
95 const std::string& session_id) {
96 status_ = kKeyAdded;
97 session_id_ = session_id;
98 }
99
100 void ClearKeyCdm::Client::KeyError(const std::string& key_system,
101 const std::string& session_id,
102 media::Decryptor::KeyError error_code,
103 int system_code) {
104 status_ = kKeyError;
105 session_id_ = session_id;
106 }
107
108 void ClearKeyCdm::Client::KeyMessage(const std::string& key_system,
109 const std::string& session_id,
110 scoped_array<uint8> message,
111 int message_length,
112 const std::string& default_url) {
113 status_ = kKeyMessage;
114 session_id_ = session_id;
115 key_message_ = message.Pass();
116 key_message_length_ = message_length;
117 }
118
119 void ClearKeyCdm::Client::NeedKey(const std::string& key_system,
120 const std::string& session_id,
121 scoped_array<uint8> init_data,
122 int init_data_length) {
123 NOTREACHED();
ddorwin 2012/08/16 05:00:35 Comment why. TODO?
xhwang 2012/08/16 17:19:01 Done.
124 }
125
126 ClearKeyCdm::ClearKeyCdm() : decryptor_(&client_) {}
127
128 ClearKeyCdm::~ClearKeyCdm() {}
129
130 ClearKeyCdm::Status ClearKeyCdm::GenerateKeyRequest(const uint8_t* init_data,
131 int init_data_size,
132 char** session_id,
133 int* session_id_size,
134 uint8_t** key_request,
135 int* key_request_size,
136 char** default_url,
137 int* default_url_size) {
138 ScopedResetter<Client> auto_resetter(&client_);
139 decryptor_.GenerateKeyRequest("", init_data, init_data_size);
ddorwin 2012/08/16 05:00:35 What happened to the key system? We should be pass
xhwang 2012/08/16 17:19:01 Key system is needed here if one CDM needs to supp
140
141 if (client_.status() != Client::kKeyMessage)
142 return kErrorUnknown;
143
144 *session_id_size = client_.session_id().size();
145 *session_id = AllocateAndCopy(client_.session_id().data(), *session_id_size);
146 *key_request_size = client_.key_message_length();
147 *key_request = AllocateAndCopy(client_.key_message(), *key_request_size);
148 *default_url_size = client_.default_url().size();
149 *default_url = AllocateAndCopy(client_.default_url().data(),
150 *default_url_size);
151 return kSuccess;
152 }
153
154 ClearKeyCdm::Status ClearKeyCdm::AddKey(const char* session_id,
155 int session_id_size,
156 const uint8_t* key,
157 int key_size) {
158 ScopedResetter<Client> auto_resetter(&client_);
159 decryptor_.AddKey("", key, key_size, NULL, 0,
ddorwin 2012/08/16 05:00:35 How are you associating the key with the key ID? (
xhwang 2012/08/16 17:19:01 Done.
160 std::string(session_id, session_id_size));
161 if (client_.status() != Client::kKeyAdded)
162 return kErrorUnknown;
163
164 return kSuccess;
165 }
166
167 ClearKeyCdm::Status ClearKeyCdm::CancelKeyRequest(const char* session_id,
168 int session_id_size) {
169 ScopedResetter<Client> auto_resetter(&client_);
170 decryptor_.CancelKeyRequest("", std::string(session_id, session_id_size));
171 return kSuccess;
172 }
173
174 static void CopyDecryptResult(
175 media::Decryptor::Status* status_copy,
176 scoped_refptr<media::DecoderBuffer>* buffer_copy,
177 media::Decryptor::Status status,
178 const scoped_refptr<media::DecoderBuffer>& buffer) {
179 *status_copy = status;
180 *buffer_copy = buffer;
181 }
182
183 ClearKeyCdm::Status ClearKeyCdm::Decrypt(
184 const char* session_id,
185 int session_id_size,
186 const cdm::InputBuffer& encrypted_buffer,
187 cdm::OutputBuffer* decrypted_buffer) {
188 scoped_refptr<media::DecoderBuffer> decoder_buffer =
189 CopyDecoderBufferFrom(encrypted_buffer);
190
ddorwin 2012/08/16 05:00:35 // Callback is called synchronously, so we can use
xhwang 2012/08/16 17:19:01 Done.
191 media::Decryptor::Status status;
192 scoped_refptr<media::DecoderBuffer> buffer;
193 decryptor_.Decrypt(decoder_buffer,
194 base::Bind(&CopyDecryptResult, &status, &buffer));
195
196 if (status == media::Decryptor::kError)
197 return kErrorUnknown;
198
199 if (status == media::Decryptor::kNoKey)
200 return kErrorNoKey;
201
202 DCHECK(buffer);
203 int data_size = buffer->GetDataSize();
204 decrypted_buffer->data = AllocateAndCopy(buffer->GetData(), data_size);
205 decrypted_buffer->data_size = data_size;
206 decrypted_buffer->timestamp = buffer->GetTimestamp().InMilliseconds();
207 decrypted_buffer->duration = buffer->GetDuration().InMilliseconds();
208 return kSuccess;
209 }
210
211 } // namespace webkit_media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698