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

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: Use message_loop_proxy. 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
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..e20f8eeb4adfd05d0dcb37f57a47fefb1949c7db 100644
--- a/webkit/media/crypto/proxy_decryptor.cc
+++ b/webkit/media/crypto/proxy_decryptor.cc
@@ -4,7 +4,10 @@
#include "webkit/media/crypto/proxy_decryptor.h"
+#include "base/bind.h"
+#include "base/location.h"
#include "base/logging.h"
+#include "base/message_loop_proxy.h"
#include "media/base/decoder_buffer.h"
#include "media/base/decryptor_client.h"
#include "media/crypto/aes_decryptor.h"
@@ -20,6 +23,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 +47,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 +78,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_);
scherkus (not reviewing) 2012/07/26 02:06:38 dcheck not needed
xhwang 2012/07/26 22:16:04 Done.
+ client_->KeyError(key_system, "", Decryptor::kUnknownError, 0);
return;
}
@@ -78,38 +99,68 @@ 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);
+ }
+
+ 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()";
+
// 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) {
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),
+ base::MessageLoopProxy::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),
+ base::MessageLoopProxy::current(), encrypted, decrypt_cb));
}
-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 +172,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 +191,49 @@ scoped_ptr<media::Decryptor> ProxyDecryptor::CreateDecryptor(
return CreatePpapiDecryptor(key_system);
}
+void ProxyDecryptor::DecryptOnMessageLoop(
+ const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy,
+ const scoped_refptr<DecoderBuffer>& encrypted,
+ const Decryptor::DecryptCB& decrypt_cb) {
+ DVLOG(2) << "DecryptOnMessageLoop()";
+ DCHECK(decryptor_.get());
+
+ if (!message_loop_proxy->BelongsToCurrentThread()) {
+ message_loop_proxy->PostTask(FROM_HERE, base::Bind(
+ &ProxyDecryptor::DecryptOnMessageLoop, base::Unretained(this),
+ message_loop_proxy, encrypted, decrypt_cb));
+ return;
+ }
+
+ decryptor_->Decrypt(encrypted, base::Bind(&ProxyDecryptor::OnBufferDecrypted,
+ base::Unretained(this), message_loop_proxy, encrypted, decrypt_cb));
+}
+
+void ProxyDecryptor::OnBufferDecrypted(
+ const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy,
+ 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_proxy, 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
« webkit/media/crypto/proxy_decryptor.h ('K') | « webkit/media/crypto/proxy_decryptor.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698