summaryrefslogtreecommitdiffstats
path: root/webkit/media
diff options
context:
space:
mode:
authorxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-29 03:05:34 +0000
committerxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-29 03:05:34 +0000
commita888463d8945509170ec3be8243a988b25bea62c (patch)
tree8c73511e2beb4beffd7cc85a60188d956b73af00 /webkit/media
parent85a61eb46a3f1b93e19cded05773e6784ed1adb7 (diff)
downloadchromium_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.cc69
-rw-r--r--webkit/media/crypto/proxy_decryptor.h60
-rw-r--r--webkit/media/webkit_media.gypi6
-rw-r--r--webkit/media/webmediaplayer_impl.cc49
-rw-r--r--webkit/media/webmediaplayer_impl.h10
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);
};