diff options
author | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-29 03:05:34 +0000 |
---|---|---|
committer | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-29 03:05:34 +0000 |
commit | a888463d8945509170ec3be8243a988b25bea62c (patch) | |
tree | 8c73511e2beb4beffd7cc85a60188d956b73af00 /webkit/media | |
parent | 85a61eb46a3f1b93e19cded05773e6784ed1adb7 (diff) | |
download | chromium_src-a888463d8945509170ec3be8243a988b25bea62c.zip chromium_src-a888463d8945509170ec3be8243a988b25bea62c.tar.gz chromium_src-a888463d8945509170ec3be8243a988b25bea62c.tar.bz2 |
Add ProxyDecryptor which wraps concrete Decryptor implementations.
For now it only wraps AesDecryptor. In the future it will also wrap
PpapiDecryptor.
BUG=123260
TEST=media_unittests, media layout tests.
Review URL: https://chromiumcodereview.appspot.com/10575026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@144869 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/media')
-rw-r--r-- | webkit/media/crypto/key_systems.cc (renamed from webkit/media/key_systems.cc) | 11 | ||||
-rw-r--r-- | webkit/media/crypto/key_systems.h (renamed from webkit/media/key_systems.h) | 18 | ||||
-rw-r--r-- | webkit/media/crypto/proxy_decryptor.cc | 69 | ||||
-rw-r--r-- | webkit/media/crypto/proxy_decryptor.h | 60 | ||||
-rw-r--r-- | webkit/media/webkit_media.gypi | 6 | ||||
-rw-r--r-- | webkit/media/webmediaplayer_impl.cc | 49 | ||||
-rw-r--r-- | webkit/media/webmediaplayer_impl.h | 10 |
7 files changed, 201 insertions, 22 deletions
diff --git a/webkit/media/key_systems.cc b/webkit/media/crypto/key_systems.cc index 7efbb9e..b4aeb90 100644 --- a/webkit/media/key_systems.cc +++ b/webkit/media/crypto/key_systems.cc @@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "webkit/media/key_systems.h" +#include "webkit/media/crypto/key_systems.h" +#include "media/base/decryptor.h" +#include "media/crypto/aes_decryptor.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" namespace webkit_media { @@ -75,4 +77,11 @@ bool IsSupportedKeySystemWithMediaMimeType( return true; } +scoped_ptr<media::Decryptor> CreateDecryptor(const std::string& key_system, + media::DecryptorClient* client) { + if (key_system == kClearKeyKeySystem) + return scoped_ptr<media::Decryptor>(new media::AesDecryptor(client)); + return scoped_ptr<media::Decryptor>(); +} + } // namespace webkit_media diff --git a/webkit/media/key_systems.h b/webkit/media/crypto/key_systems.h index dedd279..1822507 100644 --- a/webkit/media/key_systems.h +++ b/webkit/media/crypto/key_systems.h @@ -2,16 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef WEBKIT_MEDIA_KEY_SYSTEMS_H_ -#define WEBKIT_MEDIA_KEY_SYSTEMS_H_ +#ifndef WEBKIT_MEDIA_CRYPTO_KEY_SYSTEMS_H_ +#define WEBKIT_MEDIA_CRYPTO_KEY_SYSTEMS_H_ #include <string> #include <vector> +#include "base/memory/scoped_ptr.h" + namespace WebKit { class WebString; } +namespace media { +class Decryptor; +class DecryptorClient; +} + namespace webkit_media { // Returns whether |key_sytem| is supported at all. @@ -25,6 +32,11 @@ bool IsSupportedKeySystemWithMediaMimeType( const std::vector<std::string>& codecs, const std::string& key_system); +// Creates and returns a decryptor that corresponds to the |key_system|. +// Returns NULL if the |key_system| is not supported. +scoped_ptr<media::Decryptor> CreateDecryptor(const std::string& key_system, + media::DecryptorClient* client); + } // namespace webkit_media -#endif // WEBKIT_MEDIA_KEY_SYSTEMS_H_ +#endif // WEBKIT_MEDIA_CRYPTO_KEY_SYSTEMS_H_ diff --git a/webkit/media/crypto/proxy_decryptor.cc b/webkit/media/crypto/proxy_decryptor.cc new file mode 100644 index 0000000..e44e6f4 --- /dev/null +++ b/webkit/media/crypto/proxy_decryptor.cc @@ -0,0 +1,69 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/media/crypto/proxy_decryptor.h" + +#include "base/logging.h" +#include "media/base/decoder_buffer.h" +#include "media/base/decryptor_client.h" +#include "media/crypto/aes_decryptor.h" +#include "webkit/media/crypto/key_systems.h" + +namespace webkit_media { + +ProxyDecryptor::ProxyDecryptor(media::DecryptorClient* client) + : client_(client) { +} + +ProxyDecryptor::~ProxyDecryptor() { +} + +void ProxyDecryptor::GenerateKeyRequest(const std::string& key_system, + const uint8* init_data, + int init_data_length) { + // We do not support run-time switching of decryptors. GenerateKeyRequest() + // only creates a new decryptor when |decryptor_| is not initialized. + if (!decryptor_.get()) { + base::AutoLock auto_lock(lock_); + decryptor_ = CreateDecryptor(key_system, client_); + } + + DCHECK(decryptor_.get()); + decryptor_->GenerateKeyRequest(key_system, init_data, init_data_length); +} + +void ProxyDecryptor::AddKey(const std::string& key_system, + const uint8* key, + int key_length, + const uint8* init_data, + int init_data_length, + const std::string& session_id) { + // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. + DCHECK(decryptor_.get()); + decryptor_->AddKey(key_system, key, key_length, init_data, init_data_length, + session_id); +} + +void ProxyDecryptor::CancelKeyRequest(const std::string& key_system, + const std::string& session_id) { + // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. + DCHECK(decryptor_.get()); + decryptor_->CancelKeyRequest(key_system, session_id); +} + +scoped_refptr<media::DecoderBuffer> ProxyDecryptor::Decrypt( + const scoped_refptr<media::DecoderBuffer>& input) { + // This is safe as we do not replace/delete an existing decryptor at run-time. + Decryptor* decryptor = NULL; + { + base::AutoLock auto_lock(lock_); + decryptor = decryptor_.get(); + } + if (!decryptor) + return NULL; + + return decryptor->Decrypt(input); +} + +} // namespace webkit_media diff --git a/webkit/media/crypto/proxy_decryptor.h b/webkit/media/crypto/proxy_decryptor.h new file mode 100644 index 0000000..e1672e1 --- /dev/null +++ b/webkit/media/crypto/proxy_decryptor.h @@ -0,0 +1,60 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_ +#define WEBKIT_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_ + +#include <string> + +#include "base/memory/scoped_ptr.h" +#include "base/synchronization/lock.h" +#include "media/base/decryptor.h" + +namespace media { +class DecryptorClient; +} + +namespace webkit_media { + +// A decryptor proxy that creates a real decryptor object on demand and +// forwards decryptor calls to it. +// TODO(xhwang): Currently we don't support run-time switching among decryptor +// objects. Fix this when needed. +class ProxyDecryptor : public media::Decryptor { + public: + explicit ProxyDecryptor(media::DecryptorClient* client); + virtual ~ProxyDecryptor(); + + // media::Decryptor implementation. + virtual void GenerateKeyRequest(const std::string& key_system, + const uint8* init_data, + int init_data_length) OVERRIDE; + virtual void AddKey(const std::string& key_system, + const uint8* key, + int key_length, + const uint8* init_data, + int init_data_length, + const std::string& session_id) OVERRIDE; + virtual void CancelKeyRequest(const std::string& key_system, + const std::string& session_id) OVERRIDE; + virtual scoped_refptr<media::DecoderBuffer> Decrypt( + const scoped_refptr<media::DecoderBuffer>& input) OVERRIDE; + + private: + media::DecryptorClient* const client_; + // Protects the |decryptor_|. The Decryptor interface specifies that the + // Decrypt() function will be called on the decoder thread and all other + // methods on the renderer thread. The |decryptor_| itself is thread safe + // when this rule is obeyed. This lock is solely to prevent the race condition + // between setting the |decryptor_| in GenerateKeyRequest() and using it in + // Decrypt(). + base::Lock lock_; + scoped_ptr<media::Decryptor> decryptor_; // Protected by the |lock_|. + + DISALLOW_COPY_AND_ASSIGN(ProxyDecryptor); +}; + +} // namespace webkit_media + +#endif // WEBKIT_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_ diff --git a/webkit/media/webkit_media.gypi b/webkit/media/webkit_media.gypi index 111b5ef..702031a 100644 --- a/webkit/media/webkit_media.gypi +++ b/webkit/media/webkit_media.gypi @@ -32,10 +32,12 @@ 'buffered_resource_loader.h', 'cache_util.cc', 'cache_util.h', + 'crypto/key_systems.cc', + 'crypto/key_systems.h', + 'crypto/proxy_decryptor.cc', + 'crypto/proxy_decryptor.h', 'filter_helpers.cc', 'filter_helpers.h', - 'key_systems.cc', - 'key_systems.h', 'media_stream_client.h', 'preload.h', 'skcanvas_video_renderer.cc', diff --git a/webkit/media/webmediaplayer_impl.cc b/webkit/media/webmediaplayer_impl.cc index 5707a7b..41bcf11 100644 --- a/webkit/media/webmediaplayer_impl.cc +++ b/webkit/media/webmediaplayer_impl.cc @@ -22,7 +22,6 @@ #include "media/base/media_switches.h" #include "media/base/pipeline.h" #include "media/base/video_frame.h" -#include "media/crypto/aes_decryptor.h" #include "media/filters/audio_renderer_impl.h" #include "media/filters/video_renderer_base.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebVideoFrame.h" @@ -34,7 +33,6 @@ #include "v8/include/v8.h" #include "webkit/media/buffered_data_source.h" #include "webkit/media/filter_helpers.h" -#include "webkit/media/key_systems.h" #include "webkit/media/webmediaplayer_delegate.h" #include "webkit/media/webmediaplayer_proxy.h" #include "webkit/media/webmediaplayer_util.h" @@ -82,9 +80,9 @@ const float kMaxRate = 16.0f; namespace webkit_media { -#define COMPILE_ASSERT_MATCHING_ENUM(name) \ +#define COMPILE_ASSERT_MATCHING_ENUM(name) \ COMPILE_ASSERT(static_cast<int>(WebKit::WebMediaPlayer::CORSMode ## name) == \ - static_cast<int>(BufferedResourceLoader::k ## name), \ + static_cast<int>(BufferedResourceLoader::k ## name), \ mismatching_enums) COMPILE_ASSERT_MATCHING_ENUM(Unspecified); COMPILE_ASSERT_MATCHING_ENUM(Anonymous); @@ -130,7 +128,8 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( accelerated_compositing_reported_(false), incremented_externally_allocated_memory_(false), audio_source_provider_(audio_source_provider), - is_local_source_(false) { + is_local_source_(false), + decryptor_(proxy_.get()) { media_log_->AddEvent( media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); @@ -164,8 +163,6 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( // Create default audio renderer. filter_collection_->AddAudioRenderer( new media::AudioRendererImpl(new media::NullAudioSink())); - - decryptor_.reset(new media::AesDecryptor(proxy_.get())); } WebMediaPlayerImpl::~WebMediaPlayerImpl() { @@ -245,7 +242,7 @@ void WebMediaPlayerImpl::load(const WebKit::WebURL& url, CORSMode cors_mode) { if (BuildMediaSourceCollection(url, GetClient()->sourceURL(), proxy_, message_loop_factory_.get(), filter_collection_.get(), - decryptor_.get(), + &decryptor_, &video_decoder)) { proxy_->set_video_decoder(video_decoder); StartPipeline(); @@ -268,7 +265,7 @@ void WebMediaPlayerImpl::load(const WebKit::WebURL& url, CORSMode cors_mode) { BuildDefaultCollection(proxy_->data_source(), message_loop_factory_.get(), filter_collection_.get(), - decryptor_.get(), + &decryptor_, &video_decoder); proxy_->set_video_decoder(video_decoder); } @@ -710,12 +707,18 @@ WebMediaPlayerImpl::generateKeyRequest(const WebString& key_system, if (!IsSupportedKeySystem(key_system)) return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; + // We do not support run-time switching between key systems for now. + if (current_key_system_.isEmpty()) + current_key_system_ = key_system; + else if (key_system != current_key_system_) + return WebKit::WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; + DVLOG(1) << "generateKeyRequest: " << key_system.utf8().data() << ": " << std::string(reinterpret_cast<const char*>(init_data), static_cast<size_t>(init_data_length)); - decryptor_->GenerateKeyRequest(key_system.utf8(), - init_data, init_data_length); + decryptor_.GenerateKeyRequest(key_system.utf8(), + init_data, init_data_length); return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; } @@ -732,6 +735,9 @@ WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::addKey( if (!IsSupportedKeySystem(key_system)) return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; + if (current_key_system_.isEmpty() || key_system != current_key_system_) + return WebKit::WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; + DVLOG(1) << "addKey: " << key_system.utf8().data() << ": " << std::string(reinterpret_cast<const char*>(key), static_cast<size_t>(key_length)) << ", " @@ -739,8 +745,8 @@ WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::addKey( static_cast<size_t>(init_data_length)) << " [" << session_id.utf8().data() << "]"; - decryptor_->AddKey(key_system.utf8(), key, key_length, - init_data, init_data_length, session_id.utf8()); + decryptor_.AddKey(key_system.utf8(), key, key_length, + init_data, init_data_length, session_id.utf8()); return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; } @@ -750,7 +756,10 @@ WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::cancelKeyRequest( if (!IsSupportedKeySystem(key_system)) return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; - decryptor_->CancelKeyRequest(key_system.utf8(), session_id.utf8()); + if (current_key_system_.isEmpty() || key_system != current_key_system_) + return WebKit::WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; + + decryptor_.CancelKeyRequest(key_system.utf8(), session_id.utf8()); return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; } @@ -891,6 +900,18 @@ void WebMediaPlayerImpl::OnNeedKey(const std::string& key_system, init_data_size); } +#define COMPILE_ASSERT_MATCHING_ENUM(name) \ + COMPILE_ASSERT(static_cast<int>(WebKit::WebMediaPlayerClient::name) == \ + static_cast<int>(media::Decryptor::k ## name), \ + mismatching_enums) +COMPILE_ASSERT_MATCHING_ENUM(UnknownError); +COMPILE_ASSERT_MATCHING_ENUM(ClientError); +COMPILE_ASSERT_MATCHING_ENUM(ServiceError); +COMPILE_ASSERT_MATCHING_ENUM(OutputError); +COMPILE_ASSERT_MATCHING_ENUM(HardwareChangeError); +COMPILE_ASSERT_MATCHING_ENUM(DomainError); +#undef COMPILE_ASSERT_MATCHING_ENUM + void WebMediaPlayerImpl::OnKeyError(const std::string& key_system, const std::string& session_id, media::Decryptor::KeyError error_code, diff --git a/webkit/media/webmediaplayer_impl.h b/webkit/media/webmediaplayer_impl.h index c19e006..376c10f 100644 --- a/webkit/media/webmediaplayer_impl.h +++ b/webkit/media/webmediaplayer_impl.h @@ -64,6 +64,8 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebAudioSourceProvider.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayer.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient.h" +#include "webkit/media/crypto/key_systems.h" +#include "webkit/media/crypto/proxy_decryptor.h" class RenderAudioSourceProvider; @@ -292,8 +294,9 @@ class WebMediaPlayerImpl scoped_refptr<media::Pipeline> pipeline_; bool started_; - // The decryptor that manages decryption keys and decrypts encrypted frames. - scoped_ptr<media::Decryptor> decryptor_; + // The currently selected key system. Empty string means that no key system + // has been selected. + WebKit::WebString current_key_system_; scoped_ptr<media::MessageLoopFactory> message_loop_factory_; @@ -339,6 +342,9 @@ class WebMediaPlayerImpl bool is_local_source_; + // The decryptor that manages decryption keys and decrypts encrypted frames. + ProxyDecryptor decryptor_; + DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl); }; |