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

Unified Diff: webkit/media/crypto/proxy_decryptor.cc

Issue 10822026: Implement "Key Presence" step in "Encrypted Block Encounted" algorithm in EME. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webkit/media/crypto/proxy_decryptor.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/media/crypto/proxy_decryptor.cc
diff --git a/webkit/media/crypto/proxy_decryptor.cc b/webkit/media/crypto/proxy_decryptor.cc
index 0b786552b577ea199d042517195a2a20ffb05cb1..a8a20210c039aaf4db092fcec5b7d16a69e9d04f 100644
--- a/webkit/media/crypto/proxy_decryptor.cc
+++ b/webkit/media/crypto/proxy_decryptor.cc
@@ -4,7 +4,9 @@
#include "webkit/media/crypto/proxy_decryptor.h"
+#include "base/bind.h"
#include "base/logging.h"
+#include "base/message_loop.h"
#include "media/base/decoder_buffer.h"
#include "media/base/decryptor_client.h"
#include "media/crypto/aes_decryptor.h"
@@ -20,6 +22,9 @@
// Fix include order here when the bug is fixed.
#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient.h"
+using media::Decryptor;
+using media::DecoderBuffer;
+
namespace webkit_media {
static scoped_refptr<webkit::ppapi::PluginInstance> CreatePluginInstance(
@@ -41,6 +46,20 @@ static scoped_refptr<webkit::ppapi::PluginInstance> CreatePluginInstance(
return ppapi_plugin->instance();
}
+// TODO(xhwang): Simplify this function. This is mostly caused by the fact that
+// we need to copy a scoped_array<uint8>.
+static void FireNeedKey(media::DecryptorClient* client,
+ const scoped_refptr<DecoderBuffer>& encrypted) {
+ DCHECK(client);
+ DCHECK(encrypted);
+ DCHECK(encrypted->GetDecryptConfig());
+ const uint8* key_id = encrypted->GetDecryptConfig()->key_id();
+ const int key_id_size = encrypted->GetDecryptConfig()->key_id_size();
+ scoped_array<uint8> key_id_array(new uint8[key_id_size]);
+ memcpy(key_id_array.get(), key_id, key_id_size);
+ client->NeedKey("", "", key_id_array.Pass(), key_id_size);
+}
+
ProxyDecryptor::ProxyDecryptor(
media::DecryptorClient* decryptor_client,
WebKit::WebMediaPlayerClient* web_media_player_client,
@@ -58,14 +77,15 @@ void ProxyDecryptor::GenerateKeyRequest(const std::string& key_system,
int init_data_length) {
// We do not support run-time switching of decryptors. GenerateKeyRequest()
// only creates a new decryptor when |decryptor_| is not initialized.
+ DVLOG(1) << "GenerateKeyRequest: key_system = " << key_system;
if (!decryptor_.get()) {
- base::AutoLock auto_lock(lock_);
+ base::AutoLock auto_lock(decryptor_lock_);
decryptor_ = CreateDecryptor(key_system);
}
- DCHECK(client_);
if (!decryptor_.get()) {
- client_->KeyError(key_system, "", media::Decryptor::kUnknownError, 0);
+ DCHECK(client_);
+ client_->KeyError(key_system, "", Decryptor::kUnknownError, 0);
return;
}
@@ -78,38 +98,67 @@ void ProxyDecryptor::AddKey(const std::string& key_system,
const uint8* init_data,
int init_data_length,
const std::string& session_id) {
+ DVLOG(1) << "AddKey()";
+
// WebMediaPlayerImpl ensures GenerateKeyRequest() has been called.
DCHECK(decryptor_.get());
decryptor_->AddKey(key_system, key, key_length, init_data, init_data_length,
session_id);
+
+ std::vector<base::Closure> closures_to_run;
+ {
+ base::AutoLock auto_lock(pending_decrypt_closures_lock_);
+ std::swap(pending_decrypt_closures_, closures_to_run);
scherkus (not reviewing) 2012/07/26 00:13:50 so if I queue a bunch of closures requiring key A
xhwang 2012/07/26 00:53:00 This is a feature not a bug. According to ddorwin@
+ }
+
+ for (std::vector<base::Closure>::iterator iter = closures_to_run.begin();
+ iter != closures_to_run.end();
+ ++iter) {
+ iter->Run();
+ }
}
void ProxyDecryptor::CancelKeyRequest(const std::string& key_system,
const std::string& session_id) {
+ DVLOG(1) << "CancelKeyRequest()";
scherkus (not reviewing) 2012/07/26 00:13:50 do we need to commit these?
xhwang 2012/07/26 00:53:00 I am trying to add logs to calls from WebKit to he
+
// WebMediaPlayerImpl ensures GenerateKeyRequest() has been called.
DCHECK(decryptor_.get());
decryptor_->CancelKeyRequest(key_system, session_id);
}
void ProxyDecryptor::Decrypt(
- const scoped_refptr<media::DecoderBuffer>& encrypted,
+ const scoped_refptr<DecoderBuffer>& encrypted,
const DecryptCB& decrypt_cb) {
+ DVLOG(2) << "Decrypt()";
+
// This is safe as we do not replace/delete an existing decryptor at run-time.
- media::Decryptor* decryptor = NULL;
+ Decryptor* decryptor = NULL;
{
- base::AutoLock auto_lock(lock_);
+ base::AutoLock auto_lock(decryptor_lock_);
decryptor = decryptor_.get();
}
+
if (!decryptor) {
scherkus (not reviewing) 2012/07/26 00:13:50 when would this happen?
xhwang 2012/07/26 00:53:00 This could happen when the encrypted media file is
DVLOG(1) << "ProxyDecryptor::Decrypt(): decryptor not initialized.";
- decrypt_cb.Run(kError, NULL);
+ {
+ base::AutoLock auto_lock(pending_decrypt_closures_lock_);
+ pending_decrypt_closures_.push_back(base::Bind(
+ &ProxyDecryptor::DecryptOnMessageLoop, base::Unretained(this),
+ MessageLoop::current(), encrypted, decrypt_cb));
+ }
+ // TODO(xhwang): The same NeedKey may be fired here and multiple times in
+ // OnBufferDecrypted(). While the spec says only one NeedKey should be
+ // fired. Leave them as is since the spec about this may change.
+ FireNeedKey(client_, encrypted);
return;
}
- decryptor->Decrypt(encrypted, decrypt_cb);
+ decryptor->Decrypt(encrypted, base::Bind(&ProxyDecryptor::OnBufferDecrypted,
+ base::Unretained(this), MessageLoop::current(), encrypted, decrypt_cb));
scherkus (not reviewing) 2012/07/26 00:13:50 this should be MessageLoopProxy
xhwang 2012/07/26 00:53:00 Done.
}
-scoped_ptr<media::Decryptor> ProxyDecryptor::CreatePpapiDecryptor(
+scoped_ptr<Decryptor> ProxyDecryptor::CreatePpapiDecryptor(
const std::string& key_system) {
DCHECK(client_);
DCHECK(web_media_player_client_);
@@ -121,19 +170,18 @@ scoped_ptr<media::Decryptor> ProxyDecryptor::CreatePpapiDecryptor(
CreatePluginInstance(plugin_type, web_media_player_client_, web_frame_);
if (!plugin_instance) {
DVLOG(1) << "PpapiDecryptor: plugin instance creation failed.";
- return scoped_ptr<media::Decryptor>();
+ return scoped_ptr<Decryptor>();
}
- return scoped_ptr<media::Decryptor>(new PpapiDecryptor(client_,
- plugin_instance));
+ return scoped_ptr<Decryptor>(new PpapiDecryptor(client_, plugin_instance));
}
-scoped_ptr<media::Decryptor> ProxyDecryptor::CreateDecryptor(
+scoped_ptr<Decryptor> ProxyDecryptor::CreateDecryptor(
const std::string& key_system) {
DCHECK(client_);
if (CanUseAesDecryptor(key_system))
- return scoped_ptr<media::Decryptor>(new media::AesDecryptor(client_));
+ return scoped_ptr<Decryptor>(new media::AesDecryptor(client_));
// We only support AesDecryptor and PpapiDecryptor. So if we cannot
// use the AesDecryptor, then we'll try to create a PpapiDecryptor for given
@@ -141,4 +189,49 @@ scoped_ptr<media::Decryptor> ProxyDecryptor::CreateDecryptor(
return CreatePpapiDecryptor(key_system);
}
+void ProxyDecryptor::DecryptOnMessageLoop(
+ MessageLoop* message_loop,
+ const scoped_refptr<DecoderBuffer>& encrypted,
+ const Decryptor::DecryptCB& decrypt_cb) {
+ DVLOG(2) << "DecryptOnMessageLoop()";
+ DCHECK(decryptor_.get());
+
+ if (MessageLoop::current() != message_loop) {
+ message_loop->PostTask(FROM_HERE, base::Bind(
+ &ProxyDecryptor::DecryptOnMessageLoop, base::Unretained(this),
+ message_loop, encrypted, decrypt_cb));
+ return;
+ }
+
+ decryptor_->Decrypt(encrypted, base::Bind(&ProxyDecryptor::OnBufferDecrypted,
+ base::Unretained(this), message_loop, encrypted, decrypt_cb));
+}
+
+void ProxyDecryptor::OnBufferDecrypted(
+ MessageLoop* message_loop,
+ const scoped_refptr<DecoderBuffer>& encrypted,
+ const Decryptor::DecryptCB& decrypt_cb,
+ Decryptor::DecryptStatus status,
+ const scoped_refptr<DecoderBuffer>& decrypted) {
+ DVLOG(2) << "OnBufferDecrypted()";
+
+ if (status == Decryptor::kSuccess || status == Decryptor::kError) {
+ decrypt_cb.Run(status, decrypted);
+ return;
+ }
+
+ DCHECK_EQ(status, Decryptor::kNoKey);
+ DVLOG(1) << "OnBufferDecrypted(): kNoKey fired";
+ {
+ base::AutoLock auto_lock(pending_decrypt_closures_lock_);
+ pending_decrypt_closures_.push_back(base::Bind(
+ &ProxyDecryptor::DecryptOnMessageLoop, base::Unretained(this),
+ message_loop, encrypted, decrypt_cb));
+ }
+ // TODO(xhwang): The same NeedKey may be fired multiple times here and also
+ // in Decrypt(). While the spec says only one NeedKey should be fired. Leave
+ // them as is since the spec about this may change.
+ FireNeedKey(client_, encrypted);
+}
+
} // namespace webkit_media
« no previous file with comments | « webkit/media/crypto/proxy_decryptor.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698