Index: webkit/media/crypto/proxy_decryptor.cc |
diff --git a/webkit/media/crypto/proxy_decryptor.cc b/webkit/media/crypto/proxy_decryptor.cc |
index e20f8eeb4adfd05d0dcb37f57a47fefb1949c7db..e05fc57196bc80fce939a7e8b0e828a6260c43b5 100644 |
--- a/webkit/media/crypto/proxy_decryptor.cc |
+++ b/webkit/media/crypto/proxy_decryptor.cc |
@@ -4,6 +4,8 @@ |
#include "webkit/media/crypto/proxy_decryptor.h" |
+#include <algorithm> |
+ |
#include "base/bind.h" |
#include "base/location.h" |
#include "base/logging.h" |
@@ -23,9 +25,6 @@ |
// 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( |
@@ -50,15 +49,14 @@ static scoped_refptr<webkit::ppapi::PluginInstance> CreatePluginInstance( |
// 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) { |
+ const scoped_refptr<media::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); |
+ std::string key_id = encrypted->GetDecryptConfig()->key_id(); |
+ scoped_array<uint8> key_id_array(new uint8[key_id.size()]); |
+ memcpy(key_id_array.get(), key_id.data(), key_id.size()); |
+ client->NeedKey("", "", key_id_array.Pass(), key_id.size()); |
} |
ProxyDecryptor::ProxyDecryptor( |
@@ -67,7 +65,8 @@ ProxyDecryptor::ProxyDecryptor( |
WebKit::WebFrame* web_frame) |
: client_(decryptor_client), |
web_media_player_client_(web_media_player_client), |
- web_frame_(web_frame) { |
+ web_frame_(web_frame), |
+ is_shutting_down_(false) { |
} |
ProxyDecryptor::~ProxyDecryptor() { |
@@ -80,13 +79,12 @@ void ProxyDecryptor::GenerateKeyRequest(const std::string& key_system, |
// only creates a new decryptor when |decryptor_| is not initialized. |
DVLOG(1) << "GenerateKeyRequest: key_system = " << key_system; |
if (!decryptor_.get()) { |
- base::AutoLock auto_lock(decryptor_lock_); |
+ base::AutoLock auto_lock(lock_); |
decryptor_ = CreateDecryptor(key_system); |
} |
if (!decryptor_.get()) { |
- DCHECK(client_); |
- client_->KeyError(key_system, "", Decryptor::kUnknownError, 0); |
+ client_->KeyError(key_system, "", media::Decryptor::kUnknownError, 0); |
return; |
} |
@@ -108,10 +106,12 @@ void ProxyDecryptor::AddKey(const std::string& key_system, |
std::vector<base::Closure> closures_to_run; |
{ |
- base::AutoLock auto_lock(pending_decrypt_closures_lock_); |
+ base::AutoLock auto_lock(lock_); |
std::swap(pending_decrypt_closures_, closures_to_run); |
} |
+ // Fire all pending callbacks here because only the |decryptor_| knows if the |
+ // pending buffers can be decrypted or not. |
for (std::vector<base::Closure>::iterator iter = closures_to_run.begin(); |
iter != closures_to_run.end(); |
++iter) { |
@@ -129,30 +129,31 @@ void ProxyDecryptor::CancelKeyRequest(const std::string& key_system, |
} |
void ProxyDecryptor::Decrypt( |
- const scoped_refptr<DecoderBuffer>& encrypted, |
+ const scoped_refptr<media::DecoderBuffer>& encrypted, |
const DecryptCB& decrypt_cb) { |
- DVLOG(2) << "Decrypt()"; |
- |
// This is safe as we do not replace/delete an existing decryptor at run-time. |
- Decryptor* decryptor = NULL; |
+ media::Decryptor* decryptor = NULL; |
{ |
- base::AutoLock auto_lock(decryptor_lock_); |
+ base::AutoLock auto_lock(lock_); |
+ if (is_shutting_down_) { |
+ DVLOG(1) << "Decrypt(): fire decrypt callbacks with kError."; |
+ decrypt_cb.Run(kError, NULL); |
+ return; |
+ } |
decryptor = decryptor_.get(); |
- } |
- |
- if (!decryptor) { |
- DVLOG(1) << "ProxyDecryptor::Decrypt(): decryptor not initialized."; |
- { |
- 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)); |
+ if (!decryptor) { |
+ DVLOG(1) << "ProxyDecryptor::Decrypt(): decryptor not initialized."; |
+ 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; |
} |
- // 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, base::Bind( |
@@ -160,7 +161,26 @@ void ProxyDecryptor::Decrypt( |
base::MessageLoopProxy::current(), encrypted, decrypt_cb)); |
} |
-scoped_ptr<Decryptor> ProxyDecryptor::CreatePpapiDecryptor( |
+void ProxyDecryptor::Stop() { |
+ DVLOG(1) << "AddKey()"; |
+ |
+ std::vector<base::Closure> closures_to_run; |
+ { |
+ base::AutoLock auto_lock(lock_); |
+ if (decryptor_.get()) |
+ decryptor_->Stop(); |
+ is_shutting_down_ = true; |
+ 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(); |
+ } |
+} |
+ |
+scoped_ptr<media::Decryptor> ProxyDecryptor::CreatePpapiDecryptor( |
const std::string& key_system) { |
DCHECK(client_); |
DCHECK(web_media_player_client_); |
@@ -172,18 +192,19 @@ scoped_ptr<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<Decryptor>(); |
+ return scoped_ptr<media::Decryptor>(); |
} |
- return scoped_ptr<Decryptor>(new PpapiDecryptor(client_, plugin_instance)); |
+ return scoped_ptr<media::Decryptor>(new PpapiDecryptor(client_, |
+ plugin_instance)); |
} |
-scoped_ptr<Decryptor> ProxyDecryptor::CreateDecryptor( |
+scoped_ptr<media::Decryptor> ProxyDecryptor::CreateDecryptor( |
const std::string& key_system) { |
DCHECK(client_); |
if (CanUseAesDecryptor(key_system)) |
- return scoped_ptr<Decryptor>(new media::AesDecryptor(client_)); |
+ return scoped_ptr<media::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 |
@@ -193,9 +214,8 @@ scoped_ptr<Decryptor> ProxyDecryptor::CreateDecryptor( |
void ProxyDecryptor::DecryptOnMessageLoop( |
const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy, |
- const scoped_refptr<DecoderBuffer>& encrypted, |
- const Decryptor::DecryptCB& decrypt_cb) { |
- DVLOG(2) << "DecryptOnMessageLoop()"; |
+ const scoped_refptr<media::DecoderBuffer>& encrypted, |
+ const media::Decryptor::DecryptCB& decrypt_cb) { |
DCHECK(decryptor_.get()); |
if (!message_loop_proxy->BelongsToCurrentThread()) { |
@@ -205,27 +225,40 @@ void ProxyDecryptor::DecryptOnMessageLoop( |
return; |
} |
+ { |
+ base::AutoLock auto_lock(lock_); |
+ if (is_shutting_down_) { |
+ DVLOG(1) << "DecryptOnMessageLoop(): fire decrypt callbacks with kError."; |
+ decrypt_cb.Run(kError, NULL); |
+ return; |
+ } |
+ } |
+ |
decryptor_->Decrypt(encrypted, base::Bind(&ProxyDecryptor::OnBufferDecrypted, |
scherkus (not reviewing)
2012/08/02 18:05:32
nit: technically this is mixing style: params on n
xhwang
2012/08/03 20:08:10
Done.
|
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) { |
+ const scoped_refptr<media::DecoderBuffer>& encrypted, |
+ const media::Decryptor::DecryptCB& decrypt_cb, |
+ media::Decryptor::DecryptStatus status, |
+ const scoped_refptr<media::DecoderBuffer>& decrypted) { |
+ if (status == media::Decryptor::kSuccess || |
+ status == media::Decryptor::kError) { |
decrypt_cb.Run(status, decrypted); |
return; |
} |
- DCHECK_EQ(status, Decryptor::kNoKey); |
+ DCHECK_EQ(status, media::Decryptor::kNoKey); |
DVLOG(1) << "OnBufferDecrypted(): kNoKey fired"; |
{ |
- base::AutoLock auto_lock(pending_decrypt_closures_lock_); |
+ base::AutoLock auto_lock(lock_); |
+ if (is_shutting_down_) { |
+ DVLOG(1) << "OnBufferDecrypted(): fire decrypt callbacks with kError."; |
+ decrypt_cb.Run(kError, NULL); |
+ return; |
+ } |
pending_decrypt_closures_.push_back(base::Bind( |
&ProxyDecryptor::DecryptOnMessageLoop, base::Unretained(this), |
message_loop_proxy, encrypted, decrypt_cb)); |