summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxhwang <xhwang@chromium.org>2014-11-18 16:16:34 -0800
committerCommit bot <commit-bot@chromium.org>2014-11-19 00:17:00 +0000
commit16ff136e88d757f4ca92291e8e221682cb1e8c63 (patch)
tree3ad793cf6fcdb61dd32139849798ba95557ef4ed
parentc69f9dc3d6256814736abcf5b3ef0df37c1406e2 (diff)
downloadchromium_src-16ff136e88d757f4ca92291e8e221682cb1e8c63.zip
chromium_src-16ff136e88d757f4ca92291e8e221682cb1e8c63.tar.gz
chromium_src-16ff136e88d757f4ca92291e8e221682cb1e8c63.tar.bz2
Move EncryptedMediaPlayerSupport and ProxyDecryptor from content to media.
Summary of changes: - Drop EncryptedMediaPlayerSupport interface. - Move EncryptedMediaPlayerSupportImpl to media and rename it to EncryptedMediaPlayerSupport. - Drop NullEncryptedMediaPlayerSupport. - Drop EncryptedMediaPlayerSupportCreateCB from WebMediaPlayerParams, and let WebMediaPlayerImpl always own a EncryptedMediaPlayerSupport. - EncryptedMediaPlayerSupport takes an external CdmFactory. - Pass a CdmFactory to WebMediaPlayerImpl's constructor. - Move ProxyDecryptor to media. BUG=422730 Review URL: https://codereview.chromium.org/737483002 Cr-Commit-Position: refs/heads/master@{#304712}
-rw-r--r--content/content_renderer.gypi5
-rw-r--r--content/renderer/BUILD.gn1
-rw-r--r--content/renderer/media/android/webmediaplayer_android.cc2
-rw-r--r--content/renderer/media/android/webmediaplayer_android.h4
-rw-r--r--content/renderer/media/crypto/encrypted_media_player_support_impl.cc475
-rw-r--r--content/renderer/media/crypto/encrypted_media_player_support_impl.h131
-rw-r--r--content/renderer/render_frame_impl.cc13
-rw-r--r--media/BUILD.gn2
-rw-r--r--media/blink/BUILD.gn4
-rw-r--r--media/blink/encrypted_media_player_support.cc435
-rw-r--r--media/blink/encrypted_media_player_support.h121
-rw-r--r--media/blink/media_blink.gyp4
-rw-r--r--media/blink/null_encrypted_media_player_support.cc86
-rw-r--r--media/blink/null_encrypted_media_player_support.h76
-rw-r--r--media/blink/webmediaplayer_impl.cc28
-rw-r--r--media/blink/webmediaplayer_impl.h6
-rw-r--r--media/blink/webmediaplayer_params.cc13
-rw-r--r--media/blink/webmediaplayer_params.h15
-rw-r--r--media/cdm/proxy_decryptor.cc (renamed from content/renderer/media/crypto/proxy_decryptor.cc)53
-rw-r--r--media/cdm/proxy_decryptor.h (renamed from content/renderer/media/crypto/proxy_decryptor.h)29
-rw-r--r--media/media.gyp2
-rw-r--r--mojo/services/html_viewer/webmediaplayer_factory.cc7
22 files changed, 608 insertions, 904 deletions
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index 0ea1a4d..414754d 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -248,15 +248,11 @@
'renderer/media/audio_message_filter.h',
'renderer/media/audio_renderer_mixer_manager.cc',
'renderer/media/audio_renderer_mixer_manager.h',
- 'renderer/media/crypto/encrypted_media_player_support_impl.cc',
- 'renderer/media/crypto/encrypted_media_player_support_impl.h',
'renderer/media/crypto/pepper_cdm_wrapper.h',
'renderer/media/crypto/pepper_cdm_wrapper_impl.cc',
'renderer/media/crypto/pepper_cdm_wrapper_impl.h',
'renderer/media/crypto/ppapi_decryptor.cc',
'renderer/media/crypto/ppapi_decryptor.h',
- 'renderer/media/crypto/proxy_decryptor.cc',
- 'renderer/media/crypto/proxy_decryptor.h',
'renderer/media/crypto/render_cdm_factory.cc',
'renderer/media/crypto/render_cdm_factory.h',
'renderer/media/media_stream_audio_level_calculator.cc',
@@ -744,7 +740,6 @@
['OS=="android"', {
'sources!': [
'renderer/media/audio_decoder.cc',
- 'renderer/media/crypto/encrypted_media_player_support_impl.cc',
],
'sources': [
'renderer/external_popup_menu.cc',
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 22acf49b..bfe9605 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -83,7 +83,6 @@ source_set("renderer") {
if (is_android) {
sources -= [
"media/audio_decoder.cc",
- "media/crypto/encrypted_media_player_support_impl.cc",
]
sources += [
"external_popup_menu.cc",
diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc
index 196b9a7..deb3417 100644
--- a/content/renderer/media/android/webmediaplayer_android.cc
+++ b/content/renderer/media/android/webmediaplayer_android.cc
@@ -1508,7 +1508,7 @@ WebMediaPlayerAndroid::GenerateKeyRequestInternal(
// We do not support run-time switching between key systems for now.
if (current_key_system_.empty()) {
if (!proxy_decryptor_) {
- proxy_decryptor_.reset(new ProxyDecryptor(
+ proxy_decryptor_.reset(new media::ProxyDecryptor(
base::Bind(&WebMediaPlayerAndroid::OnKeyAdded,
weak_factory_.GetWeakPtr()),
base::Bind(&WebMediaPlayerAndroid::OnKeyError,
diff --git a/content/renderer/media/android/webmediaplayer_android.h b/content/renderer/media/android/webmediaplayer_android.h
index 771074d..0da37eb 100644
--- a/content/renderer/media/android/webmediaplayer_android.h
+++ b/content/renderer/media/android/webmediaplayer_android.h
@@ -22,12 +22,12 @@
#include "content/renderer/media/android/media_info_loader.h"
#include "content/renderer/media/android/media_source_delegate.h"
#include "content/renderer/media/android/stream_texture_factory.h"
-#include "content/renderer/media/crypto/proxy_decryptor.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "media/base/android/media_player_android.h"
#include "media/base/demuxer_stream.h"
#include "media/base/media_keys.h"
#include "media/base/time_delta_interpolator.h"
+#include "media/cdm/proxy_decryptor.h"
#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
#include "third_party/WebKit/public/platform/WebMediaPlayer.h"
#include "third_party/WebKit/public/platform/WebSize.h"
@@ -473,7 +473,7 @@ class WebMediaPlayerAndroid : public blink::WebMediaPlayer,
std::string init_data_type_;
// Manages decryption keys and decrypts encrypted frames.
- scoped_ptr<ProxyDecryptor> proxy_decryptor_;
+ scoped_ptr<media::ProxyDecryptor> proxy_decryptor_;
// Non-owned pointer to the CDM. Updated via calls to
// setContentDecryptionModule().
diff --git a/content/renderer/media/crypto/encrypted_media_player_support_impl.cc b/content/renderer/media/crypto/encrypted_media_player_support_impl.cc
deleted file mode 100644
index 86e3329..0000000
--- a/content/renderer/media/crypto/encrypted_media_player_support_impl.cc
+++ /dev/null
@@ -1,475 +0,0 @@
-// Copyright 2014 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 "content/renderer/media/crypto/encrypted_media_player_support_impl.h"
-
-#include <string>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/metrics/histogram.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "content/renderer/media/crypto/render_cdm_factory.h"
-#include "media/base/bind_to_current_loop.h"
-#include "media/base/key_systems.h"
-#include "media/blink/encrypted_media_player_support.h"
-#include "media/blink/webcontentdecryptionmodule_impl.h"
-#include "third_party/WebKit/public/platform/WebContentDecryptionModule.h"
-#include "third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h"
-#include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
-#include "third_party/WebKit/public/web/WebDocument.h"
-#include "third_party/WebKit/public/web/WebLocalFrame.h"
-#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
-
-#if defined(ENABLE_PEPPER_CDMS)
-#include "content/renderer/media/crypto/pepper_cdm_wrapper_impl.h"
-#elif defined(ENABLE_BROWSER_CDMS)
-#error Browser side CDM in WMPI for prefixed EME API not supported yet.
-#endif
-
-using blink::WebMediaPlayer;
-using blink::WebMediaPlayerClient;
-using blink::WebString;
-
-namespace content {
-
-#define BIND_TO_RENDER_LOOP(function) \
- (media::BindToCurrentLoop(base::Bind(function, AsWeakPtr())))
-
-#define BIND_TO_RENDER_LOOP1(function, arg1) \
- (media::BindToCurrentLoop(base::Bind(function, AsWeakPtr(), arg1)))
-
-// Prefix for histograms related to Encrypted Media Extensions.
-static const char* kMediaEme = "Media.EME.";
-
-// Used for calls to decryptor_ready_cb where the result can be ignored.
-static void DoNothing(bool success) {
-}
-
-// Convert a WebString to ASCII, falling back on an empty string in the case
-// of a non-ASCII string.
-static std::string ToASCIIOrEmpty(const WebString& string) {
- return base::IsStringASCII(string) ? base::UTF16ToASCII(string)
- : std::string();
-}
-
-// Helper functions to report media EME related stats to UMA. They follow the
-// convention of more commonly used macros UMA_HISTOGRAM_ENUMERATION and
-// UMA_HISTOGRAM_COUNTS. The reason that we cannot use those macros directly is
-// that UMA_* macros require the names to be constant throughout the process'
-// lifetime.
-static void EmeUMAHistogramEnumeration(const std::string& key_system,
- const std::string& method,
- int sample,
- int boundary_value) {
- base::LinearHistogram::FactoryGet(
- kMediaEme + media::GetKeySystemNameForUMA(key_system) + "." + method,
- 1, boundary_value, boundary_value + 1,
- base::Histogram::kUmaTargetedHistogramFlag)->Add(sample);
-}
-
-static void EmeUMAHistogramCounts(const std::string& key_system,
- const std::string& method,
- int sample) {
- // Use the same parameters as UMA_HISTOGRAM_COUNTS.
- base::Histogram::FactoryGet(
- kMediaEme + media::GetKeySystemNameForUMA(key_system) + "." + method,
- 1, 1000000, 50, base::Histogram::kUmaTargetedHistogramFlag)->Add(sample);
-}
-
-// Helper enum for reporting generateKeyRequest/addKey histograms.
-enum MediaKeyException {
- kUnknownResultId,
- kSuccess,
- kKeySystemNotSupported,
- kInvalidPlayerState,
- kMaxMediaKeyException
-};
-
-static MediaKeyException MediaKeyExceptionForUMA(
- WebMediaPlayer::MediaKeyException e) {
- switch (e) {
- case WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported:
- return kKeySystemNotSupported;
- case WebMediaPlayer::MediaKeyExceptionInvalidPlayerState:
- return kInvalidPlayerState;
- case WebMediaPlayer::MediaKeyExceptionNoError:
- return kSuccess;
- default:
- return kUnknownResultId;
- }
-}
-
-// Helper for converting |key_system| name and exception |e| to a pair of enum
-// values from above, for reporting to UMA.
-static void ReportMediaKeyExceptionToUMA(const std::string& method,
- const std::string& key_system,
- WebMediaPlayer::MediaKeyException e) {
- MediaKeyException result_id = MediaKeyExceptionForUMA(e);
- DCHECK_NE(result_id, kUnknownResultId) << e;
- EmeUMAHistogramEnumeration(
- key_system, method, result_id, kMaxMediaKeyException);
-}
-
-// Guess the type of |init_data|. This is only used to handle some corner cases
-// so we keep it as simple as possible without breaking major use cases.
-static std::string GuessInitDataType(const unsigned char* init_data,
- unsigned init_data_length) {
- // Most WebM files use KeyId of 16 bytes. CENC init data is always >16 bytes.
- if (init_data_length == 16)
- return "webm";
-
- return "cenc";
-}
-
-scoped_ptr<media::EncryptedMediaPlayerSupport>
-EncryptedMediaPlayerSupportImpl::Create(blink::WebMediaPlayerClient* client) {
- return scoped_ptr<EncryptedMediaPlayerSupport>(
- new EncryptedMediaPlayerSupportImpl(client));
-}
-
-EncryptedMediaPlayerSupportImpl::EncryptedMediaPlayerSupportImpl(
- blink::WebMediaPlayerClient* client)
- : client_(client),
- web_cdm_(NULL) {
-}
-
-EncryptedMediaPlayerSupportImpl::~EncryptedMediaPlayerSupportImpl() {
-}
-
-WebMediaPlayer::MediaKeyException
-EncryptedMediaPlayerSupportImpl::GenerateKeyRequest(
- blink::WebLocalFrame* frame,
- const WebString& key_system,
- const unsigned char* init_data,
- unsigned init_data_length) {
- DVLOG(1) << "generateKeyRequest: " << base::string16(key_system) << ": "
- << std::string(reinterpret_cast<const char*>(init_data),
- static_cast<size_t>(init_data_length));
-
- std::string ascii_key_system =
- media::GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
-
- WebMediaPlayer::MediaKeyException e =
- GenerateKeyRequestInternal(frame, ascii_key_system, init_data,
- init_data_length);
- ReportMediaKeyExceptionToUMA("generateKeyRequest", ascii_key_system, e);
- return e;
-}
-
-WebMediaPlayer::MediaKeyException
-EncryptedMediaPlayerSupportImpl::GenerateKeyRequestInternal(
- blink::WebLocalFrame* frame,
- const std::string& key_system,
- const unsigned char* init_data,
- unsigned init_data_length) {
- if (!media::IsConcreteSupportedKeySystem(key_system))
- return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
-
- // We do not support run-time switching between key systems for now.
- if (current_key_system_.empty()) {
- if (!proxy_decryptor_) {
- proxy_decryptor_.reset(new ProxyDecryptor(
- BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupportImpl::OnKeyAdded),
- BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupportImpl::OnKeyError),
- BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupportImpl::OnKeyMessage)));
- }
-
- GURL security_origin(frame->document().securityOrigin().toString());
-
-#if defined(ENABLE_PEPPER_CDMS)
- RenderCdmFactory cdm_factory(
- base::Bind(&PepperCdmWrapperImpl::Create, frame));
-#else
- RenderCdmFactory cdm_factory;
-#endif
-
- if (!proxy_decryptor_->InitializeCDM(&cdm_factory, key_system,
- security_origin)) {
- return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
- }
-
- if (proxy_decryptor_ && !decryptor_ready_cb_.is_null()) {
- base::ResetAndReturn(&decryptor_ready_cb_)
- .Run(proxy_decryptor_->GetDecryptor(), base::Bind(DoNothing));
- }
-
- current_key_system_ = key_system;
- } else if (key_system != current_key_system_) {
- return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
- }
-
- std::string init_data_type = init_data_type_;
- if (init_data_type.empty())
- init_data_type = GuessInitDataType(init_data, init_data_length);
-
- // TODO(xhwang): We assume all streams are from the same container (thus have
- // the same "type") for now. In the future, the "type" should be passed down
- // from the application.
- if (!proxy_decryptor_->GenerateKeyRequest(
- init_data_type, init_data, init_data_length)) {
- current_key_system_.clear();
- return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
- }
-
- return WebMediaPlayer::MediaKeyExceptionNoError;
-}
-
-WebMediaPlayer::MediaKeyException EncryptedMediaPlayerSupportImpl::AddKey(
- const WebString& key_system,
- const unsigned char* key,
- unsigned key_length,
- const unsigned char* init_data,
- unsigned init_data_length,
- const WebString& session_id) {
- DVLOG(1) << "addKey: " << base::string16(key_system) << ": "
- << std::string(reinterpret_cast<const char*>(key),
- static_cast<size_t>(key_length)) << ", "
- << std::string(reinterpret_cast<const char*>(init_data),
- static_cast<size_t>(init_data_length)) << " ["
- << base::string16(session_id) << "]";
-
- std::string ascii_key_system =
- media::GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
- std::string ascii_session_id = ToASCIIOrEmpty(session_id);
-
- WebMediaPlayer::MediaKeyException e = AddKeyInternal(ascii_key_system,
- key,
- key_length,
- init_data,
- init_data_length,
- ascii_session_id);
- ReportMediaKeyExceptionToUMA("addKey", ascii_key_system, e);
- return e;
-}
-
-WebMediaPlayer::MediaKeyException
-EncryptedMediaPlayerSupportImpl::AddKeyInternal(
- const std::string& key_system,
- const unsigned char* key,
- unsigned key_length,
- const unsigned char* init_data,
- unsigned init_data_length,
- const std::string& session_id) {
- DCHECK(key);
- DCHECK_GT(key_length, 0u);
-
- if (!media::IsConcreteSupportedKeySystem(key_system))
- return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
-
- if (current_key_system_.empty() || key_system != current_key_system_)
- return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
-
- proxy_decryptor_->AddKey(
- key, key_length, init_data, init_data_length, session_id);
- return WebMediaPlayer::MediaKeyExceptionNoError;
-}
-
-WebMediaPlayer::MediaKeyException
-EncryptedMediaPlayerSupportImpl::CancelKeyRequest(
- const WebString& key_system,
- const WebString& session_id) {
- DVLOG(1) << "cancelKeyRequest: " << base::string16(key_system) << ": "
- << " [" << base::string16(session_id) << "]";
-
- std::string ascii_key_system =
- media::GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
- std::string ascii_session_id = ToASCIIOrEmpty(session_id);
-
- WebMediaPlayer::MediaKeyException e =
- CancelKeyRequestInternal(ascii_key_system, ascii_session_id);
- ReportMediaKeyExceptionToUMA("cancelKeyRequest", ascii_key_system, e);
- return e;
-}
-
-WebMediaPlayer::MediaKeyException
-EncryptedMediaPlayerSupportImpl::CancelKeyRequestInternal(
- const std::string& key_system,
- const std::string& session_id) {
- if (!media::IsConcreteSupportedKeySystem(key_system))
- return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
-
- if (current_key_system_.empty() || key_system != current_key_system_)
- return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
-
- proxy_decryptor_->CancelKeyRequest(session_id);
- return WebMediaPlayer::MediaKeyExceptionNoError;
-}
-
-void EncryptedMediaPlayerSupportImpl::SetInitialContentDecryptionModule(
- blink::WebContentDecryptionModule* initial_cdm) {
- // Used when loading media and no pipeline/decoder attached yet.
- DCHECK(decryptor_ready_cb_.is_null());
-
- web_cdm_ = media::ToWebContentDecryptionModuleImpl(initial_cdm);
-}
-
-void EncryptedMediaPlayerSupportImpl::SetContentDecryptionModule(
- blink::WebContentDecryptionModule* cdm) {
- // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324
- if (!cdm)
- return;
-
- web_cdm_ = media::ToWebContentDecryptionModuleImpl(cdm);
-
- if (web_cdm_ && !decryptor_ready_cb_.is_null())
- base::ResetAndReturn(&decryptor_ready_cb_)
- .Run(web_cdm_->GetDecryptor(), base::Bind(DoNothing));
-}
-
-void EncryptedMediaPlayerSupportImpl::SetContentDecryptionModule(
- blink::WebContentDecryptionModule* cdm,
- blink::WebContentDecryptionModuleResult result) {
- // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324
- if (!cdm) {
- result.completeWithError(
- blink::WebContentDecryptionModuleExceptionNotSupportedError,
- 0,
- "Null MediaKeys object is not supported.");
- return;
- }
-
- web_cdm_ = media::ToWebContentDecryptionModuleImpl(cdm);
-
- if (web_cdm_ && !decryptor_ready_cb_.is_null()) {
- base::ResetAndReturn(&decryptor_ready_cb_)
- .Run(web_cdm_->GetDecryptor(), BIND_TO_RENDER_LOOP1(
- &EncryptedMediaPlayerSupportImpl::ContentDecryptionModuleAttached,
- result));
- } else {
- // No pipeline/decoder connected, so resolve the promise. When something
- // is connected, setting the CDM will happen in SetDecryptorReadyCB().
- ContentDecryptionModuleAttached(result, true);
- }
-}
-
-void EncryptedMediaPlayerSupportImpl::ContentDecryptionModuleAttached(
- blink::WebContentDecryptionModuleResult result,
- bool success) {
- if (success) {
- result.complete();
- return;
- }
-
- result.completeWithError(
- blink::WebContentDecryptionModuleExceptionNotSupportedError,
- 0,
- "Unable to set MediaKeys object");
-}
-
-media::SetDecryptorReadyCB
-EncryptedMediaPlayerSupportImpl::CreateSetDecryptorReadyCB() {
- return BIND_TO_RENDER_LOOP(
- &EncryptedMediaPlayerSupportImpl::SetDecryptorReadyCB);
-}
-
-media::Demuxer::NeedKeyCB
-EncryptedMediaPlayerSupportImpl::CreateNeedKeyCB() {
- return BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupportImpl::OnNeedKey);
-}
-
-void EncryptedMediaPlayerSupportImpl::OnPipelineDecryptError() {
- EmeUMAHistogramCounts(current_key_system_, "DecryptError", 1);
-}
-
-void EncryptedMediaPlayerSupportImpl::OnNeedKey(const std::string& type,
- const std::vector<uint8>& init_data) {
- // Do not fire NeedKey event if encrypted media is not enabled.
- if (!blink::WebRuntimeFeatures::isPrefixedEncryptedMediaEnabled() &&
- !blink::WebRuntimeFeatures::isEncryptedMediaEnabled()) {
- return;
- }
-
- UMA_HISTOGRAM_COUNTS(kMediaEme + std::string("NeedKey"), 1);
-
- DCHECK(init_data_type_.empty() || type.empty() || type == init_data_type_);
- if (init_data_type_.empty())
- init_data_type_ = type;
-
- const uint8* init_data_ptr = init_data.empty() ? NULL : &init_data[0];
- client_->encrypted(
- WebString::fromUTF8(type), init_data_ptr, init_data.size());
-}
-
-void EncryptedMediaPlayerSupportImpl::OnKeyAdded(
- const std::string& session_id) {
- EmeUMAHistogramCounts(current_key_system_, "KeyAdded", 1);
- client_->keyAdded(
- WebString::fromUTF8(media::GetPrefixedKeySystemName(current_key_system_)),
- WebString::fromUTF8(session_id));
-}
-
-void EncryptedMediaPlayerSupportImpl::OnKeyError(const std::string& session_id,
- media::MediaKeys::KeyError error_code,
- uint32 system_code) {
- EmeUMAHistogramEnumeration(current_key_system_, "KeyError",
- error_code, media::MediaKeys::kMaxKeyError);
-
- uint16 short_system_code = 0;
- if (system_code > std::numeric_limits<uint16>::max()) {
- LOG(WARNING) << "system_code exceeds unsigned short limit.";
- short_system_code = std::numeric_limits<uint16>::max();
- } else {
- short_system_code = static_cast<uint16>(system_code);
- }
-
- client_->keyError(
- WebString::fromUTF8(media::GetPrefixedKeySystemName(current_key_system_)),
- WebString::fromUTF8(session_id),
- static_cast<WebMediaPlayerClient::MediaKeyErrorCode>(error_code),
- short_system_code);
-}
-
-void EncryptedMediaPlayerSupportImpl::OnKeyMessage(
- const std::string& session_id,
- const std::vector<uint8>& message,
- const GURL& destination_url) {
- DCHECK(destination_url.is_empty() || destination_url.is_valid());
-
- client_->keyMessage(
- WebString::fromUTF8(media::GetPrefixedKeySystemName(current_key_system_)),
- WebString::fromUTF8(session_id),
- message.empty() ? NULL : &message[0],
- message.size(),
- destination_url);
-}
-
-void EncryptedMediaPlayerSupportImpl::SetDecryptorReadyCB(
- const media::DecryptorReadyCB& decryptor_ready_cb) {
- // Cancels the previous decryptor request.
- if (decryptor_ready_cb.is_null()) {
- if (!decryptor_ready_cb_.is_null()) {
- base::ResetAndReturn(&decryptor_ready_cb_)
- .Run(NULL, base::Bind(DoNothing));
- }
- return;
- }
-
- // TODO(xhwang): Support multiple decryptor notification request (e.g. from
- // video and audio). The current implementation is okay for the current
- // media pipeline since we initialize audio and video decoders in sequence.
- // But WebMediaPlayerImpl should not depend on media pipeline's implementation
- // detail.
- DCHECK(decryptor_ready_cb_.is_null());
-
- // Mixed use of prefixed and unprefixed EME APIs is disallowed by Blink.
- DCHECK(!proxy_decryptor_ || !web_cdm_);
-
- if (proxy_decryptor_) {
- decryptor_ready_cb.Run(proxy_decryptor_->GetDecryptor(),
- base::Bind(DoNothing));
- return;
- }
-
- if (web_cdm_) {
- decryptor_ready_cb.Run(web_cdm_->GetDecryptor(), base::Bind(DoNothing));
- return;
- }
-
- decryptor_ready_cb_ = decryptor_ready_cb;
-}
-
-} // namespace content
diff --git a/content/renderer/media/crypto/encrypted_media_player_support_impl.h b/content/renderer/media/crypto/encrypted_media_player_support_impl.h
deleted file mode 100644
index 88d55d1..0000000
--- a/content/renderer/media/crypto/encrypted_media_player_support_impl.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2014 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 CONTENT_RENDERER_MEDIA_CRYPTO_ENCRYPTED_MEDIA_PLAYER_SUPPORT_IMPL_H_
-#define CONTENT_RENDERER_MEDIA_CRYPTO_ENCRYPTED_MEDIA_PLAYER_SUPPORT_IMPL_H_
-
-#include <string>
-#include <vector>
-
-#include "base/memory/weak_ptr.h"
-#include "content/renderer/media/crypto/proxy_decryptor.h"
-#include "media/blink/encrypted_media_player_support.h"
-#include "media/blink/webcontentdecryptionmodule_impl.h"
-
-namespace blink {
-class WebMediaPlayerClient;
-}
-
-namespace content {
-
-class WebContentDecryptionModuleImpl;
-
-class EncryptedMediaPlayerSupportImpl
- : public media::EncryptedMediaPlayerSupport,
- public base::SupportsWeakPtr<EncryptedMediaPlayerSupportImpl> {
- public:
- static scoped_ptr<EncryptedMediaPlayerSupport> Create(
- blink::WebMediaPlayerClient* client);
-
- ~EncryptedMediaPlayerSupportImpl() override;
-
- // EncryptedMediaPlayerSupport implementation.
- blink::WebMediaPlayer::MediaKeyException GenerateKeyRequest(
- blink::WebLocalFrame* frame,
- const blink::WebString& key_system,
- const unsigned char* init_data,
- unsigned init_data_length) override;
-
- blink::WebMediaPlayer::MediaKeyException AddKey(
- const blink::WebString& key_system,
- const unsigned char* key,
- unsigned key_length,
- const unsigned char* init_data,
- unsigned init_data_length,
- const blink::WebString& session_id) override;
-
- blink::WebMediaPlayer::MediaKeyException CancelKeyRequest(
- const blink::WebString& key_system,
- const blink::WebString& session_id) override;
-
- void SetInitialContentDecryptionModule(
- blink::WebContentDecryptionModule* initial_cdm) override;
-
- void SetContentDecryptionModule(
- blink::WebContentDecryptionModule* cdm) override;
- void SetContentDecryptionModule(
- blink::WebContentDecryptionModule* cdm,
- blink::WebContentDecryptionModuleResult result) override;
-
- media::SetDecryptorReadyCB CreateSetDecryptorReadyCB() override;
- media::Demuxer::NeedKeyCB CreateNeedKeyCB() override;
-
- void OnPipelineDecryptError() override;
-
- private:
- explicit EncryptedMediaPlayerSupportImpl(blink::WebMediaPlayerClient* client);
-
- // Requests that this object notifies when a decryptor is ready through the
- // |decryptor_ready_cb| provided.
- // If |decryptor_ready_cb| is null, the existing callback will be fired with
- // NULL immediately and reset.
- void SetDecryptorReadyCB(const media::DecryptorReadyCB& decryptor_ready_cb);
-
- blink::WebMediaPlayer::MediaKeyException GenerateKeyRequestInternal(
- blink::WebLocalFrame* frame,
- const std::string& key_system,
- const unsigned char* init_data,
- unsigned init_data_length);
-
- blink::WebMediaPlayer::MediaKeyException AddKeyInternal(
- const std::string& key_system,
- const unsigned char* key,
- unsigned key_length,
- const unsigned char* init_data,
- unsigned init_data_length,
- const std::string& session_id);
-
- blink::WebMediaPlayer::MediaKeyException CancelKeyRequestInternal(
- const std::string& key_system,
- const std::string& session_id);
-
- void OnNeedKey(const std::string& type,
- const std::vector<uint8>& init_data);
-
- void OnKeyAdded(const std::string& session_id);
- void OnKeyError(const std::string& session_id,
- media::MediaKeys::KeyError error_code,
- uint32 system_code);
- void OnKeyMessage(const std::string& session_id,
- const std::vector<uint8>& message,
- const GURL& destination_url);
-
- void ContentDecryptionModuleAttached(
- blink::WebContentDecryptionModuleResult result,
- bool success);
-
- blink::WebMediaPlayerClient* client_;
-
- // The currently selected key system. Empty string means that no key system
- // has been selected.
- std::string current_key_system_;
-
- // Temporary for EME v0.1. In the future the init data type should be passed
- // through GenerateKeyRequest() directly from WebKit.
- std::string init_data_type_;
-
- // Manages decryption keys and decrypts encrypted frames.
- scoped_ptr<ProxyDecryptor> proxy_decryptor_;
-
- // Non-owned pointer to the CDM. Updated via calls to
- // setContentDecryptionModule().
- media::WebContentDecryptionModuleImpl* web_cdm_;
-
- media::DecryptorReadyCB decryptor_ready_cb_;
-
- DISALLOW_COPY_AND_ASSIGN(EncryptedMediaPlayerSupportImpl);
-};
-}
-
-#endif // CONTENT_RENDERER_MEDIA_CRYPTO_ENCRYPTED_MEDIA_PLAYER_SUPPORT_IMPL_H_
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 8e70202..8678b58 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -70,7 +70,6 @@
#include "content/renderer/internal_document_state_data.h"
#include "content/renderer/manifest/manifest_manager.h"
#include "content/renderer/media/audio_renderer_mixer_manager.h"
-#include "content/renderer/media/crypto/encrypted_media_player_support_impl.h"
#include "content/renderer/media/crypto/render_cdm_factory.h"
#include "content/renderer/media/media_stream_dispatcher.h"
#include "content/renderer/media/media_stream_renderer_factory.h"
@@ -97,6 +96,7 @@
#include "gin/modules/module_registry.h"
#include "media/base/audio_renderer_mixer_input.h"
#include "media/base/renderer.h"
+#include "media/blink/encrypted_media_player_support.h"
#include "media/blink/webcontentdecryptionmodule_impl.h"
#include "media/blink/webmediaplayer_impl.h"
#include "media/blink/webmediaplayer_params.h"
@@ -1773,15 +1773,22 @@ blink::WebMediaPlayer* RenderFrameImpl::createMediaPlayer(
render_thread->GetGpuFactories(),
render_thread->GetMediaThreadTaskRunner(),
render_thread->compositor_message_loop_proxy(),
- base::Bind(&EncryptedMediaPlayerSupportImpl::Create),
initial_cdm);
+#if defined(ENABLE_PEPPER_CDMS)
+ scoped_ptr<media::CdmFactory> cdm_factory(
+ new RenderCdmFactory(base::Bind(&PepperCdmWrapperImpl::Create, frame)));
+#else
+ scoped_ptr<media::CdmFactory> cdm_factory(new RenderCdmFactory());
+#endif
+
scoped_ptr<media::Renderer> media_renderer =
GetContentClient()->renderer()->CreateMediaRenderer(
this, render_thread->GetMediaThreadTaskRunner());
return new media::WebMediaPlayerImpl(
- frame, client, weak_factory_.GetWeakPtr(), media_renderer.Pass(), params);
+ frame, client, weak_factory_.GetWeakPtr(), media_renderer.Pass(),
+ cdm_factory.Pass(), params);
#endif // defined(OS_ANDROID)
}
diff --git a/media/BUILD.gn b/media/BUILD.gn
index 2496984..20f1eaa 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -73,6 +73,8 @@ component("media") {
"cdm/key_system_names.h",
"cdm/player_tracker_impl.cc",
"cdm/player_tracker_impl.h",
+ "cdm/proxy_decryptor.cc",
+ "cdm/proxy_decyrptor.h",
"ffmpeg/ffmpeg_deleters.h",
"filters/audio_clock.cc",
"filters/audio_clock.h",
diff --git a/media/blink/BUILD.gn b/media/blink/BUILD.gn
index e842fb1..fbf06dc 100644
--- a/media/blink/BUILD.gn
+++ b/media/blink/BUILD.gn
@@ -39,8 +39,6 @@ component("blink") {
"encrypted_media_player_support.h",
"new_session_cdm_result_promise.cc",
"new_session_cdm_result_promise.h",
- "null_encrypted_media_player_support.cc",
- "null_encrypted_media_player_support.h",
"texttrack_impl.cc",
"texttrack_impl.h",
"video_frame_compositor.cc",
@@ -68,6 +66,8 @@ component("blink") {
if (is_android) {
sources -= [
+ "encrypted_media_player_support.cc",
+ "encrypted_media_player_support.h",
"webmediaplayer_impl.cc",
"webmediaplayer_impl.h",
]
diff --git a/media/blink/encrypted_media_player_support.cc b/media/blink/encrypted_media_player_support.cc
index 663141f..0d91279 100644
--- a/media/blink/encrypted_media_player_support.cc
+++ b/media/blink/encrypted_media_player_support.cc
@@ -4,12 +4,445 @@
#include "media/blink/encrypted_media_player_support.h"
+#include <string>
+
+#include "base/bind.h"
+#include "base/callback_helpers.h"
+#include "base/metrics/histogram.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "media/base/bind_to_current_loop.h"
+#include "media/base/key_systems.h"
+#include "media/blink/webcontentdecryptionmodule_impl.h"
+#include "third_party/WebKit/public/platform/WebContentDecryptionModule.h"
+#include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
+#include "third_party/WebKit/public/web/WebDocument.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
+#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
+
+using blink::WebMediaPlayer;
+using blink::WebMediaPlayerClient;
+using blink::WebString;
+
namespace media {
-EncryptedMediaPlayerSupport::EncryptedMediaPlayerSupport() {
+#define BIND_TO_RENDER_LOOP(function) \
+ (BindToCurrentLoop(base::Bind(function, AsWeakPtr())))
+
+#define BIND_TO_RENDER_LOOP1(function, arg1) \
+ (BindToCurrentLoop(base::Bind(function, AsWeakPtr(), arg1)))
+
+// Prefix for histograms related to Encrypted Media Extensions.
+static const char* kMediaEme = "Media.EME.";
+
+// Used for calls to decryptor_ready_cb where the result can be ignored.
+static void DoNothing(bool success) {
+}
+
+// Convert a WebString to ASCII, falling back on an empty string in the case
+// of a non-ASCII string.
+static std::string ToASCIIOrEmpty(const WebString& string) {
+ return base::IsStringASCII(string) ? base::UTF16ToASCII(string)
+ : std::string();
+}
+
+// Helper functions to report media EME related stats to UMA. They follow the
+// convention of more commonly used macros UMA_HISTOGRAM_ENUMERATION and
+// UMA_HISTOGRAM_COUNTS. The reason that we cannot use those macros directly is
+// that UMA_* macros require the names to be constant throughout the process'
+// lifetime.
+static void EmeUMAHistogramEnumeration(const std::string& key_system,
+ const std::string& method,
+ int sample,
+ int boundary_value) {
+ base::LinearHistogram::FactoryGet(
+ kMediaEme + GetKeySystemNameForUMA(key_system) + "." + method,
+ 1, boundary_value, boundary_value + 1,
+ base::Histogram::kUmaTargetedHistogramFlag)->Add(sample);
+}
+
+static void EmeUMAHistogramCounts(const std::string& key_system,
+ const std::string& method,
+ int sample) {
+ // Use the same parameters as UMA_HISTOGRAM_COUNTS.
+ base::Histogram::FactoryGet(
+ kMediaEme + GetKeySystemNameForUMA(key_system) + "." + method,
+ 1, 1000000, 50, base::Histogram::kUmaTargetedHistogramFlag)->Add(sample);
+}
+
+// Helper enum for reporting generateKeyRequest/addKey histograms.
+enum MediaKeyException {
+ kUnknownResultId,
+ kSuccess,
+ kKeySystemNotSupported,
+ kInvalidPlayerState,
+ kMaxMediaKeyException
+};
+
+static MediaKeyException MediaKeyExceptionForUMA(
+ WebMediaPlayer::MediaKeyException e) {
+ switch (e) {
+ case WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported:
+ return kKeySystemNotSupported;
+ case WebMediaPlayer::MediaKeyExceptionInvalidPlayerState:
+ return kInvalidPlayerState;
+ case WebMediaPlayer::MediaKeyExceptionNoError:
+ return kSuccess;
+ default:
+ return kUnknownResultId;
+ }
+}
+
+// Helper for converting |key_system| name and exception |e| to a pair of enum
+// values from above, for reporting to UMA.
+static void ReportMediaKeyExceptionToUMA(const std::string& method,
+ const std::string& key_system,
+ WebMediaPlayer::MediaKeyException e) {
+ MediaKeyException result_id = MediaKeyExceptionForUMA(e);
+ DCHECK_NE(result_id, kUnknownResultId) << e;
+ EmeUMAHistogramEnumeration(
+ key_system, method, result_id, kMaxMediaKeyException);
+}
+
+// Guess the type of |init_data|. This is only used to handle some corner cases
+// so we keep it as simple as possible without breaking major use cases.
+static std::string GuessInitDataType(const unsigned char* init_data,
+ unsigned init_data_length) {
+ // Most WebM files use KeyId of 16 bytes. CENC init data is always >16 bytes.
+ if (init_data_length == 16)
+ return "webm";
+
+ return "cenc";
+}
+
+EncryptedMediaPlayerSupport::EncryptedMediaPlayerSupport(
+ scoped_ptr<CdmFactory> cdm_factory,
+ blink::WebMediaPlayerClient* client,
+ blink::WebContentDecryptionModule* initial_cdm)
+ : cdm_factory_(cdm_factory.Pass()),
+ client_(client),
+ web_cdm_(ToWebContentDecryptionModuleImpl(initial_cdm)) {
}
EncryptedMediaPlayerSupport::~EncryptedMediaPlayerSupport() {
}
+WebMediaPlayer::MediaKeyException
+EncryptedMediaPlayerSupport::GenerateKeyRequest(
+ blink::WebLocalFrame* frame,
+ const WebString& key_system,
+ const unsigned char* init_data,
+ unsigned init_data_length) {
+ DVLOG(1) << "generateKeyRequest: " << base::string16(key_system) << ": "
+ << std::string(reinterpret_cast<const char*>(init_data),
+ static_cast<size_t>(init_data_length));
+
+ std::string ascii_key_system =
+ GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
+
+ WebMediaPlayer::MediaKeyException e =
+ GenerateKeyRequestInternal(frame, ascii_key_system, init_data,
+ init_data_length);
+ ReportMediaKeyExceptionToUMA("generateKeyRequest", ascii_key_system, e);
+ return e;
+}
+
+WebMediaPlayer::MediaKeyException
+EncryptedMediaPlayerSupport::GenerateKeyRequestInternal(
+ blink::WebLocalFrame* frame,
+ const std::string& key_system,
+ const unsigned char* init_data,
+ unsigned init_data_length) {
+ if (!IsConcreteSupportedKeySystem(key_system))
+ return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
+
+ // We do not support run-time switching between key systems for now.
+ if (current_key_system_.empty()) {
+ if (!proxy_decryptor_) {
+ proxy_decryptor_.reset(new ProxyDecryptor(
+ BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupport::OnKeyAdded),
+ BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupport::OnKeyError),
+ BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupport::OnKeyMessage)));
+ }
+
+ GURL security_origin(frame->document().securityOrigin().toString());
+
+ if (!cdm_factory_.get() ||
+ !proxy_decryptor_->InitializeCDM(cdm_factory_.get(), key_system,
+ security_origin)) {
+ return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
+ }
+
+ if (proxy_decryptor_ && !decryptor_ready_cb_.is_null()) {
+ base::ResetAndReturn(&decryptor_ready_cb_)
+ .Run(proxy_decryptor_->GetDecryptor(), base::Bind(DoNothing));
+ }
+
+ current_key_system_ = key_system;
+ } else if (key_system != current_key_system_) {
+ return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
+ }
+
+ std::string init_data_type = init_data_type_;
+ if (init_data_type.empty())
+ init_data_type = GuessInitDataType(init_data, init_data_length);
+
+ // TODO(xhwang): We assume all streams are from the same container (thus have
+ // the same "type") for now. In the future, the "type" should be passed down
+ // from the application.
+ if (!proxy_decryptor_->GenerateKeyRequest(
+ init_data_type, init_data, init_data_length)) {
+ current_key_system_.clear();
+ return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
+ }
+
+ return WebMediaPlayer::MediaKeyExceptionNoError;
+}
+
+WebMediaPlayer::MediaKeyException EncryptedMediaPlayerSupport::AddKey(
+ const WebString& key_system,
+ const unsigned char* key,
+ unsigned key_length,
+ const unsigned char* init_data,
+ unsigned init_data_length,
+ const WebString& session_id) {
+ DVLOG(1) << "addKey: " << base::string16(key_system) << ": "
+ << std::string(reinterpret_cast<const char*>(key),
+ static_cast<size_t>(key_length)) << ", "
+ << std::string(reinterpret_cast<const char*>(init_data),
+ static_cast<size_t>(init_data_length)) << " ["
+ << base::string16(session_id) << "]";
+
+ std::string ascii_key_system =
+ GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
+ std::string ascii_session_id = ToASCIIOrEmpty(session_id);
+
+ WebMediaPlayer::MediaKeyException e = AddKeyInternal(ascii_key_system,
+ key,
+ key_length,
+ init_data,
+ init_data_length,
+ ascii_session_id);
+ ReportMediaKeyExceptionToUMA("addKey", ascii_key_system, e);
+ return e;
+}
+
+WebMediaPlayer::MediaKeyException
+EncryptedMediaPlayerSupport::AddKeyInternal(
+ const std::string& key_system,
+ const unsigned char* key,
+ unsigned key_length,
+ const unsigned char* init_data,
+ unsigned init_data_length,
+ const std::string& session_id) {
+ DCHECK(key);
+ DCHECK_GT(key_length, 0u);
+
+ if (!IsConcreteSupportedKeySystem(key_system))
+ return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
+
+ if (current_key_system_.empty() || key_system != current_key_system_)
+ return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
+
+ proxy_decryptor_->AddKey(
+ key, key_length, init_data, init_data_length, session_id);
+ return WebMediaPlayer::MediaKeyExceptionNoError;
+}
+
+WebMediaPlayer::MediaKeyException
+EncryptedMediaPlayerSupport::CancelKeyRequest(
+ const WebString& key_system,
+ const WebString& session_id) {
+ DVLOG(1) << "cancelKeyRequest: " << base::string16(key_system) << ": "
+ << " [" << base::string16(session_id) << "]";
+
+ std::string ascii_key_system =
+ GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
+ std::string ascii_session_id = ToASCIIOrEmpty(session_id);
+
+ WebMediaPlayer::MediaKeyException e =
+ CancelKeyRequestInternal(ascii_key_system, ascii_session_id);
+ ReportMediaKeyExceptionToUMA("cancelKeyRequest", ascii_key_system, e);
+ return e;
+}
+
+WebMediaPlayer::MediaKeyException
+EncryptedMediaPlayerSupport::CancelKeyRequestInternal(
+ const std::string& key_system,
+ const std::string& session_id) {
+ if (!IsConcreteSupportedKeySystem(key_system))
+ return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
+
+ if (current_key_system_.empty() || key_system != current_key_system_)
+ return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
+
+ proxy_decryptor_->CancelKeyRequest(session_id);
+ return WebMediaPlayer::MediaKeyExceptionNoError;
+}
+
+void EncryptedMediaPlayerSupport::SetContentDecryptionModule(
+ blink::WebContentDecryptionModule* cdm) {
+ // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324
+ if (!cdm)
+ return;
+
+ web_cdm_ = ToWebContentDecryptionModuleImpl(cdm);
+
+ if (web_cdm_ && !decryptor_ready_cb_.is_null())
+ base::ResetAndReturn(&decryptor_ready_cb_)
+ .Run(web_cdm_->GetDecryptor(), base::Bind(DoNothing));
+}
+
+void EncryptedMediaPlayerSupport::SetContentDecryptionModule(
+ blink::WebContentDecryptionModule* cdm,
+ blink::WebContentDecryptionModuleResult result) {
+ // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324
+ if (!cdm) {
+ result.completeWithError(
+ blink::WebContentDecryptionModuleExceptionNotSupportedError,
+ 0,
+ "Null MediaKeys object is not supported.");
+ return;
+ }
+
+ web_cdm_ = ToWebContentDecryptionModuleImpl(cdm);
+
+ if (web_cdm_ && !decryptor_ready_cb_.is_null()) {
+ base::ResetAndReturn(&decryptor_ready_cb_)
+ .Run(web_cdm_->GetDecryptor(), BIND_TO_RENDER_LOOP1(
+ &EncryptedMediaPlayerSupport::ContentDecryptionModuleAttached,
+ result));
+ } else {
+ // No pipeline/decoder connected, so resolve the promise. When something
+ // is connected, setting the CDM will happen in SetDecryptorReadyCallback().
+ ContentDecryptionModuleAttached(result, true);
+ }
+}
+
+void EncryptedMediaPlayerSupport::ContentDecryptionModuleAttached(
+ blink::WebContentDecryptionModuleResult result,
+ bool success) {
+ if (success) {
+ result.complete();
+ return;
+ }
+
+ result.completeWithError(
+ blink::WebContentDecryptionModuleExceptionNotSupportedError,
+ 0,
+ "Unable to set MediaKeys object");
+}
+
+SetDecryptorReadyCB EncryptedMediaPlayerSupport::CreateSetDecryptorReadyCB() {
+ return BIND_TO_RENDER_LOOP(
+ &EncryptedMediaPlayerSupport::SetDecryptorReadyCallback);
+}
+
+Demuxer::NeedKeyCB EncryptedMediaPlayerSupport::CreateNeedKeyCB() {
+ return BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupport::OnNeedKey);
+}
+
+void EncryptedMediaPlayerSupport::OnPipelineDecryptError() {
+ EmeUMAHistogramCounts(current_key_system_, "DecryptError", 1);
+}
+
+void EncryptedMediaPlayerSupport::OnNeedKey(
+ const std::string& type,
+ const std::vector<uint8>& init_data) {
+ // Do not fire NeedKey event if encrypted media is not enabled.
+ if (!blink::WebRuntimeFeatures::isPrefixedEncryptedMediaEnabled() &&
+ !blink::WebRuntimeFeatures::isEncryptedMediaEnabled()) {
+ return;
+ }
+
+ UMA_HISTOGRAM_COUNTS(kMediaEme + std::string("NeedKey"), 1);
+
+ DCHECK(init_data_type_.empty() || type.empty() || type == init_data_type_);
+ if (init_data_type_.empty())
+ init_data_type_ = type;
+
+ const uint8* init_data_ptr = init_data.empty() ? NULL : &init_data[0];
+ client_->encrypted(WebString::fromUTF8(type), init_data_ptr,
+ base::saturated_cast<unsigned int>(init_data.size()));
+}
+
+void EncryptedMediaPlayerSupport::OnKeyAdded(const std::string& session_id) {
+ EmeUMAHistogramCounts(current_key_system_, "KeyAdded", 1);
+ client_->keyAdded(
+ WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)),
+ WebString::fromUTF8(session_id));
+}
+
+void EncryptedMediaPlayerSupport::OnKeyError(const std::string& session_id,
+ MediaKeys::KeyError error_code,
+ uint32 system_code) {
+ EmeUMAHistogramEnumeration(current_key_system_, "KeyError",
+ error_code, MediaKeys::kMaxKeyError);
+
+ uint16 short_system_code = 0;
+ if (system_code > std::numeric_limits<uint16>::max()) {
+ LOG(WARNING) << "system_code exceeds unsigned short limit.";
+ short_system_code = std::numeric_limits<uint16>::max();
+ } else {
+ short_system_code = static_cast<uint16>(system_code);
+ }
+
+ client_->keyError(
+ WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)),
+ WebString::fromUTF8(session_id),
+ static_cast<WebMediaPlayerClient::MediaKeyErrorCode>(error_code),
+ short_system_code);
+}
+
+void EncryptedMediaPlayerSupport::OnKeyMessage(
+ const std::string& session_id,
+ const std::vector<uint8>& message,
+ const GURL& destination_url) {
+ DCHECK(destination_url.is_empty() || destination_url.is_valid());
+
+ client_->keyMessage(
+ WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)),
+ WebString::fromUTF8(session_id),
+ message.empty() ? NULL : &message[0],
+ base::saturated_cast<unsigned int>(message.size()),
+ destination_url);
+}
+
+void EncryptedMediaPlayerSupport::SetDecryptorReadyCallback(
+ const DecryptorReadyCB& decryptor_ready_cb) {
+ // Cancels the previous decryptor request.
+ if (decryptor_ready_cb.is_null()) {
+ if (!decryptor_ready_cb_.is_null()) {
+ base::ResetAndReturn(&decryptor_ready_cb_)
+ .Run(NULL, base::Bind(DoNothing));
+ }
+ return;
+ }
+
+ // TODO(xhwang): Support multiple decryptor notification request (e.g. from
+ // video and audio). The current implementation is okay for the current
+ // media pipeline since we initialize audio and video decoders in sequence.
+ // But WebMediaPlayerImpl should not depend on media pipeline's implementation
+ // detail.
+ DCHECK(decryptor_ready_cb_.is_null());
+
+ // Mixed use of prefixed and unprefixed EME APIs is disallowed by Blink.
+ DCHECK(!proxy_decryptor_ || !web_cdm_);
+
+ if (proxy_decryptor_) {
+ decryptor_ready_cb.Run(proxy_decryptor_->GetDecryptor(),
+ base::Bind(DoNothing));
+ return;
+ }
+
+ if (web_cdm_) {
+ decryptor_ready_cb.Run(web_cdm_->GetDecryptor(), base::Bind(DoNothing));
+ return;
+ }
+
+ decryptor_ready_cb_ = decryptor_ready_cb;
+}
+
} // namespace media
diff --git a/media/blink/encrypted_media_player_support.h b/media/blink/encrypted_media_player_support.h
index 737720d..4f4c937 100644
--- a/media/blink/encrypted_media_player_support.h
+++ b/media/blink/encrypted_media_player_support.h
@@ -5,14 +5,19 @@
#ifndef MEDIA_BLINK_ENCRYPTED_MEDIA_PLAYER_SUPPORT_H_
#define MEDIA_BLINK_ENCRYPTED_MEDIA_PLAYER_SUPPORT_H_
-#include "media/base/decryptor.h"
+#include <string>
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "media/base/cdm_factory.h"
#include "media/base/demuxer.h"
-#include "media/base/media_export.h"
+#include "media/cdm/proxy_decryptor.h"
+#include "third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h"
#include "third_party/WebKit/public/platform/WebMediaPlayer.h"
namespace blink {
class WebContentDecryptionModule;
-class WebContentDecryptionModuleResult;
class WebLocalFrame;
class WebMediaPlayerClient;
class WebString;
@@ -20,58 +25,106 @@ class WebString;
namespace media {
-class MEDIA_EXPORT EncryptedMediaPlayerSupport {
+class WebContentDecryptionModuleImpl;
+
+class EncryptedMediaPlayerSupport
+ : public base::SupportsWeakPtr<EncryptedMediaPlayerSupport> {
public:
- EncryptedMediaPlayerSupport();
- virtual ~EncryptedMediaPlayerSupport();
+ EncryptedMediaPlayerSupport(scoped_ptr<CdmFactory> cdm_factory,
+ blink::WebMediaPlayerClient* client,
+ blink::WebContentDecryptionModule* initial_cdm);
+ ~EncryptedMediaPlayerSupport();
- // Prefixed API methods.
- virtual blink::WebMediaPlayer::MediaKeyException GenerateKeyRequest(
+ blink::WebMediaPlayer::MediaKeyException GenerateKeyRequest(
blink::WebLocalFrame* frame,
const blink::WebString& key_system,
const unsigned char* init_data,
- unsigned init_data_length) = 0;
+ unsigned init_data_length);
- virtual blink::WebMediaPlayer::MediaKeyException AddKey(
+ blink::WebMediaPlayer::MediaKeyException AddKey(
const blink::WebString& key_system,
const unsigned char* key,
unsigned key_length,
const unsigned char* init_data,
unsigned init_data_length,
- const blink::WebString& session_id) = 0;
+ const blink::WebString& session_id);
- virtual blink::WebMediaPlayer::MediaKeyException CancelKeyRequest(
+ blink::WebMediaPlayer::MediaKeyException CancelKeyRequest(
const blink::WebString& key_system,
- const blink::WebString& session_id) = 0;
-
+ const blink::WebString& session_id);
- // Unprefixed API methods.
- virtual void SetInitialContentDecryptionModule(
- blink::WebContentDecryptionModule* initial_cdm) = 0;
- virtual void SetContentDecryptionModule(
- blink::WebContentDecryptionModule* cdm) = 0;
- virtual void SetContentDecryptionModule(
+ void SetContentDecryptionModule(
+ blink::WebContentDecryptionModule* cdm);
+ void SetContentDecryptionModule(
blink::WebContentDecryptionModule* cdm,
- blink::WebContentDecryptionModuleResult result) = 0;
+ blink::WebContentDecryptionModuleResult result);
+ SetDecryptorReadyCB CreateSetDecryptorReadyCB();
+ Demuxer::NeedKeyCB CreateNeedKeyCB();
- // Callback factory and notification methods used by WebMediaPlayerImpl.
+ void OnPipelineDecryptError();
- // Creates a callback that Demuxers can use to signal that the content
- // requires a key. This method make sure the callback returned can be safely
- // invoked from any thread.
- virtual Demuxer::NeedKeyCB CreateNeedKeyCB() = 0;
+ private:
+ // Requests that this object notifies when a decryptor is ready through the
+ // |decryptor_ready_cb| provided.
+ // If |decryptor_ready_cb| is null, the existing callback will be fired with
+ // NULL immediately and reset.
+ void SetDecryptorReadyCallback(const DecryptorReadyCB& decryptor_ready_cb);
- // Creates a callback that renderers can use to set decryptor
- // ready callback. This method make sure the callback returned can be safely
- // invoked from any thread.
- virtual SetDecryptorReadyCB CreateSetDecryptorReadyCB() = 0;
+ blink::WebMediaPlayer::MediaKeyException GenerateKeyRequestInternal(
+ blink::WebLocalFrame* frame,
+ const std::string& key_system,
+ const unsigned char* init_data,
+ unsigned init_data_length);
- // Called to inform this object that the media pipeline encountered
- // and handled a decryption error.
- virtual void OnPipelineDecryptError() = 0;
+ blink::WebMediaPlayer::MediaKeyException AddKeyInternal(
+ const std::string& key_system,
+ const unsigned char* key,
+ unsigned key_length,
+ const unsigned char* init_data,
+ unsigned init_data_length,
+ const std::string& session_id);
+
+ blink::WebMediaPlayer::MediaKeyException CancelKeyRequestInternal(
+ const std::string& key_system,
+ const std::string& session_id);
+
+ void OnNeedKey(const std::string& type,
+ const std::vector<uint8>& init_data);
+
+ void OnKeyAdded(const std::string& session_id);
+ void OnKeyError(const std::string& session_id,
+ MediaKeys::KeyError error_code,
+ uint32 system_code);
+ void OnKeyMessage(const std::string& session_id,
+ const std::vector<uint8>& message,
+ const GURL& destination_url);
+
+ void ContentDecryptionModuleAttached(
+ blink::WebContentDecryptionModuleResult result,
+ bool success);
+
+ scoped_ptr<CdmFactory> cdm_factory_;
+
+ blink::WebMediaPlayerClient* client_;
+
+ // The currently selected key system. Empty string means that no key system
+ // has been selected.
+ std::string current_key_system_;
+
+ // Temporary for EME v0.1. In the future the init data type should be passed
+ // through GenerateKeyRequest() directly from WebKit.
+ std::string init_data_type_;
+
+ // Manages decryption keys and decrypts encrypted frames.
+ scoped_ptr<ProxyDecryptor> proxy_decryptor_;
+
+ // Non-owned pointer to the CDM. Updated via calls to
+ // setContentDecryptionModule().
+ WebContentDecryptionModuleImpl* web_cdm_;
+
+ DecryptorReadyCB decryptor_ready_cb_;
- private:
DISALLOW_COPY_AND_ASSIGN(EncryptedMediaPlayerSupport);
};
diff --git a/media/blink/media_blink.gyp b/media/blink/media_blink.gyp
index 32239ec..5307971 100644
--- a/media/blink/media_blink.gyp
+++ b/media/blink/media_blink.gyp
@@ -43,8 +43,6 @@
'encrypted_media_player_support.h',
'new_session_cdm_result_promise.cc',
'new_session_cdm_result_promise.h',
- 'null_encrypted_media_player_support.cc',
- 'null_encrypted_media_player_support.h',
'texttrack_impl.cc',
'texttrack_impl.h',
'video_frame_compositor.cc',
@@ -72,6 +70,8 @@
'conditions': [
['OS=="android"', {
'sources!': [
+ 'encrypted_media_player_support.cc',
+ 'encrypted_media_player_support.h',
'webmediaplayer_impl.cc',
'webmediaplayer_impl.h',
],
diff --git a/media/blink/null_encrypted_media_player_support.cc b/media/blink/null_encrypted_media_player_support.cc
deleted file mode 100644
index 240e23e..0000000
--- a/media/blink/null_encrypted_media_player_support.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2014 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 "media/blink/null_encrypted_media_player_support.h"
-
-#include "base/bind.h"
-#include "third_party/WebKit/public/platform/WebContentDecryptionModule.h"
-#include "third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h"
-
-namespace media {
-
-static void NeedKeyHandler(const std::string& type,
- const std::vector<uint8>& init_data) {
- NOTIMPLEMENTED();
-}
-
-scoped_ptr<EncryptedMediaPlayerSupport>
-NullEncryptedMediaPlayerSupport::Create(blink::WebMediaPlayerClient* client) {
- return scoped_ptr<EncryptedMediaPlayerSupport>(
- new NullEncryptedMediaPlayerSupport());
-}
-
-NullEncryptedMediaPlayerSupport::NullEncryptedMediaPlayerSupport() {
-}
-
-NullEncryptedMediaPlayerSupport::~NullEncryptedMediaPlayerSupport() {
-}
-
-blink::WebMediaPlayer::MediaKeyException
-NullEncryptedMediaPlayerSupport::GenerateKeyRequest(
- blink::WebLocalFrame* frame,
- const blink::WebString& key_system,
- const unsigned char* init_data,
- unsigned init_data_length) {
- return blink::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
-}
-
-blink::WebMediaPlayer::MediaKeyException
-NullEncryptedMediaPlayerSupport::AddKey(
- const blink::WebString& key_system,
- const unsigned char* key,
- unsigned key_length,
- const unsigned char* init_data,
- unsigned init_data_length,
- const blink::WebString& session_id) {
- return blink::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
-}
-
-blink::WebMediaPlayer::MediaKeyException
-NullEncryptedMediaPlayerSupport::CancelKeyRequest(
- const blink::WebString& key_system,
- const blink::WebString& session_id) {
- return blink::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
-}
-
-void NullEncryptedMediaPlayerSupport::SetInitialContentDecryptionModule(
- blink::WebContentDecryptionModule* initial_cdm) {
-}
-
-void NullEncryptedMediaPlayerSupport::SetContentDecryptionModule(
- blink::WebContentDecryptionModule* cdm) {
-}
-
-void NullEncryptedMediaPlayerSupport::SetContentDecryptionModule(
- blink::WebContentDecryptionModule* cdm,
- blink::WebContentDecryptionModuleResult result) {
- result.completeWithError(
- blink::WebContentDecryptionModuleExceptionNotSupportedError,
- 0,
- "Null MediaKeys object is not supported.");
-}
-
-Demuxer::NeedKeyCB NullEncryptedMediaPlayerSupport::CreateNeedKeyCB() {
- return base::Bind(&NeedKeyHandler);
-}
-
-SetDecryptorReadyCB
-NullEncryptedMediaPlayerSupport::CreateSetDecryptorReadyCB() {
- return SetDecryptorReadyCB();
-}
-
-void NullEncryptedMediaPlayerSupport::OnPipelineDecryptError() {
-}
-
-} // namespace media
diff --git a/media/blink/null_encrypted_media_player_support.h b/media/blink/null_encrypted_media_player_support.h
deleted file mode 100644
index 3b53ad2..0000000
--- a/media/blink/null_encrypted_media_player_support.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2014 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 MEDIA_BLINK_NULL_ENCRYPTED_MEDIA_PLAYER_SUPPORT_H_
-#define MEDIA_BLINK_NULL_ENCRYPTED_MEDIA_PLAYER_SUPPORT_H_
-
-#include "media/base/media_export.h"
-#include "media/blink/encrypted_media_player_support.h"
-
-namespace media {
-
-// A "null" implementation of the EncryptedMediaPlayerSupport interface
-// that indicates all key systems are not supported. This makes sure that
-// any attempts to play encrypted content always fail.
-class MEDIA_EXPORT NullEncryptedMediaPlayerSupport
- : public EncryptedMediaPlayerSupport {
- public:
- static scoped_ptr<EncryptedMediaPlayerSupport> Create(
- blink::WebMediaPlayerClient* client);
-
- ~NullEncryptedMediaPlayerSupport() override;
-
- // Prefixed API methods.
- blink::WebMediaPlayer::MediaKeyException GenerateKeyRequest(
- blink::WebLocalFrame* frame,
- const blink::WebString& key_system,
- const unsigned char* init_data,
- unsigned init_data_length) override;
-
- blink::WebMediaPlayer::MediaKeyException AddKey(
- const blink::WebString& key_system,
- const unsigned char* key,
- unsigned key_length,
- const unsigned char* init_data,
- unsigned init_data_length,
- const blink::WebString& session_id) override;
-
- blink::WebMediaPlayer::MediaKeyException CancelKeyRequest(
- const blink::WebString& key_system,
- const blink::WebString& session_id) override;
-
- // Unprefixed API methods.
- void SetInitialContentDecryptionModule(
- blink::WebContentDecryptionModule* initial_cdm) override;
- void SetContentDecryptionModule(
- blink::WebContentDecryptionModule* cdm) override;
- void SetContentDecryptionModule(
- blink::WebContentDecryptionModule* cdm,
- blink::WebContentDecryptionModuleResult result) override;
-
- // Callback factory and notification methods used by WebMediaPlayerImpl.
-
- // Creates a callback that Demuxers can use to signal that the content
- // requires a key. This method makes sure the callback returned can be safely
- // invoked from any thread.
- Demuxer::NeedKeyCB CreateNeedKeyCB() override;
-
- // Creates a callback that renderers can use to set decryptor
- // ready callback. This method makes sure the callback returned can be safely
- // invoked from any thread.
- SetDecryptorReadyCB CreateSetDecryptorReadyCB() override;
-
- // Called to inform this object that the media pipeline encountered
- // and handled a decryption error.
- void OnPipelineDecryptError() override;
-
- private:
- NullEncryptedMediaPlayerSupport();
-
- DISALLOW_COPY_AND_ASSIGN(NullEncryptedMediaPlayerSupport);
-};
-
-} // namespace media
-
-#endif // MEDIA_BLINK_NULL_ENCRYPTED_MEDIA_PLAYER_SUPPORT_H_
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index 0aaf1f0..68c17fb 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -138,6 +138,7 @@ WebMediaPlayerImpl::WebMediaPlayerImpl(
blink::WebMediaPlayerClient* client,
base::WeakPtr<WebMediaPlayerDelegate> delegate,
scoped_ptr<Renderer> renderer,
+ scoped_ptr<CdmFactory> cdm_factory,
const WebMediaPlayerParams& params)
: frame_(frame),
network_state_(WebMediaPlayer::NetworkStateEmpty),
@@ -167,12 +168,11 @@ WebMediaPlayerImpl::WebMediaPlayerImpl(
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNaturalSizeChanged),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnOpacityChanged))),
text_track_index_(0),
- encrypted_media_support_(
- params.CreateEncryptedMediaPlayerSupport(client)),
+ encrypted_media_support_(cdm_factory.Pass(),
+ client,
+ params.initial_cdm()),
audio_hardware_config_(params.audio_hardware_config()),
renderer_(renderer.Pass()) {
- DCHECK(encrypted_media_support_);
-
// Threaded compositing isn't enabled universally yet.
if (!compositor_task_runner_.get())
compositor_task_runner_ = base::MessageLoopProxy::current();
@@ -648,7 +648,7 @@ WebMediaPlayerImpl::generateKeyRequest(const WebString& key_system,
unsigned init_data_length) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- return encrypted_media_support_->GenerateKeyRequest(
+ return encrypted_media_support_.GenerateKeyRequest(
frame_, key_system, init_data, init_data_length);
}
@@ -661,7 +661,7 @@ WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::addKey(
const WebString& session_id) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- return encrypted_media_support_->AddKey(
+ return encrypted_media_support_.AddKey(
key_system, key, key_length, init_data, init_data_length, session_id);
}
@@ -670,14 +670,14 @@ WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::cancelKeyRequest(
const WebString& session_id) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- return encrypted_media_support_->CancelKeyRequest(key_system, session_id);
+ return encrypted_media_support_.CancelKeyRequest(key_system, session_id);
}
void WebMediaPlayerImpl::setContentDecryptionModule(
blink::WebContentDecryptionModule* cdm) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- encrypted_media_support_->SetContentDecryptionModule(cdm);
+ encrypted_media_support_.SetContentDecryptionModule(cdm);
}
void WebMediaPlayerImpl::setContentDecryptionModule(
@@ -685,7 +685,7 @@ void WebMediaPlayerImpl::setContentDecryptionModule(
blink::WebContentDecryptionModuleResult result) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- encrypted_media_support_->SetContentDecryptionModule(cdm, result);
+ encrypted_media_support_.SetContentDecryptionModule(cdm, result);
}
void WebMediaPlayerImpl::OnPipelineSeeked(bool time_changed,
@@ -737,7 +737,7 @@ void WebMediaPlayerImpl::OnPipelineError(PipelineStatus error) {
SetNetworkState(PipelineErrorToNetworkState(error));
if (error == PIPELINE_ERROR_DECRYPT)
- encrypted_media_support_->OnPipelineDecryptError();
+ encrypted_media_support_.OnPipelineDecryptError();
}
void WebMediaPlayerImpl::OnPipelineMetadata(
@@ -842,14 +842,14 @@ void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) {
// renderers.
scoped_ptr<Renderer> WebMediaPlayerImpl::CreateRenderer() {
SetDecryptorReadyCB set_decryptor_ready_cb =
- encrypted_media_support_->CreateSetDecryptorReadyCB();
+ encrypted_media_support_.CreateSetDecryptorReadyCB();
// Create our audio decoders and renderer.
ScopedVector<AudioDecoder> audio_decoders;
- audio_decoders.push_back(new media::FFmpegAudioDecoder(
+ audio_decoders.push_back(new FFmpegAudioDecoder(
media_task_runner_, base::Bind(&LogMediaSourceError, media_log_)));
- audio_decoders.push_back(new media::OpusAudioDecoder(media_task_runner_));
+ audio_decoders.push_back(new OpusAudioDecoder(media_task_runner_));
scoped_ptr<AudioRenderer> audio_renderer(
new AudioRendererImpl(media_task_runner_,
@@ -892,7 +892,7 @@ void WebMediaPlayerImpl::StartPipeline() {
LogCB mse_log_cb;
Demuxer::NeedKeyCB need_key_cb =
- encrypted_media_support_->CreateNeedKeyCB();
+ encrypted_media_support_.CreateNeedKeyCB();
// Figure out which demuxer to use.
if (load_type_ != LoadTypeMediaSource) {
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h
index bec5747..674a378 100644
--- a/media/blink/webmediaplayer_impl.h
+++ b/media/blink/webmediaplayer_impl.h
@@ -15,12 +15,14 @@
#include "base/memory/weak_ptr.h"
#include "base/threading/thread.h"
#include "media/base/audio_renderer_sink.h"
+#include "media/base/cdm_factory.h"
#include "media/base/media_export.h"
#include "media/base/pipeline.h"
#include "media/base/renderer.h"
#include "media/base/text_track.h"
#include "media/blink/buffered_data_source.h"
#include "media/blink/buffered_data_source_host_impl.h"
+#include "media/blink/encrypted_media_player_support.h"
#include "media/blink/video_frame_compositor.h"
#include "media/filters/skcanvas_video_renderer.h"
#include "third_party/WebKit/public/platform/WebAudioSourceProvider.h"
@@ -46,7 +48,6 @@ namespace media {
class AudioHardwareConfig;
class ChunkDemuxer;
-class EncryptedMediaPlayerSupport;
class GpuVideoAcceleratorFactories;
class MediaLog;
class VideoFrameCompositor;
@@ -71,6 +72,7 @@ class MEDIA_EXPORT WebMediaPlayerImpl
blink::WebMediaPlayerClient* client,
base::WeakPtr<WebMediaPlayerDelegate> delegate,
scoped_ptr<Renderer> renderer,
+ scoped_ptr<CdmFactory> cdm_factory,
const WebMediaPlayerParams& params);
virtual ~WebMediaPlayerImpl();
@@ -305,7 +307,7 @@ class MEDIA_EXPORT WebMediaPlayerImpl
// Text track objects get a unique index value when they're created.
int text_track_index_;
- scoped_ptr<EncryptedMediaPlayerSupport> encrypted_media_support_;
+ EncryptedMediaPlayerSupport encrypted_media_support_;
const AudioHardwareConfig& audio_hardware_config_;
diff --git a/media/blink/webmediaplayer_params.cc b/media/blink/webmediaplayer_params.cc
index 1fd2b8a..ff3ed60 100644
--- a/media/blink/webmediaplayer_params.cc
+++ b/media/blink/webmediaplayer_params.cc
@@ -19,8 +19,6 @@ WebMediaPlayerParams::WebMediaPlayerParams(
const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories,
const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner,
- const EncryptedMediaPlayerSupportCreateCB&
- encrypted_media_player_support_cb,
blink::WebContentDecryptionModule* initial_cdm)
: defer_load_cb_(defer_load_cb),
audio_renderer_sink_(audio_renderer_sink),
@@ -29,20 +27,9 @@ WebMediaPlayerParams::WebMediaPlayerParams(
gpu_factories_(gpu_factories),
media_task_runner_(media_task_runner),
compositor_task_runner_(compositor_task_runner),
- encrypted_media_player_support_cb_(encrypted_media_player_support_cb),
initial_cdm_(initial_cdm) {
}
WebMediaPlayerParams::~WebMediaPlayerParams() {}
-scoped_ptr<EncryptedMediaPlayerSupport>
-WebMediaPlayerParams::CreateEncryptedMediaPlayerSupport(
- blink::WebMediaPlayerClient* client) const {
- scoped_ptr<EncryptedMediaPlayerSupport> encrypted_media_support =
- encrypted_media_player_support_cb_.Run(client);
- if (encrypted_media_support)
- encrypted_media_support->SetInitialContentDecryptionModule(initial_cdm_);
- return encrypted_media_support.Pass();
-}
-
} // namespace media
diff --git a/media/blink/webmediaplayer_params.h b/media/blink/webmediaplayer_params.h
index c765548..3b7d343 100644
--- a/media/blink/webmediaplayer_params.h
+++ b/media/blink/webmediaplayer_params.h
@@ -8,17 +8,18 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "media/base/media_export.h"
-#include "media/blink/encrypted_media_player_support.h"
namespace base {
class SingleThreadTaskRunner;
}
namespace blink {
+class WebContentDecryptionModule;
class WebMediaPlayerClient;
}
namespace media {
+
class AudioHardwareConfig;
class AudioRendererSink;
class GpuVideoAcceleratorFactories;
@@ -28,10 +29,6 @@ class MediaLog;
// to plumb arguments through various abstraction layers.
class MEDIA_EXPORT WebMediaPlayerParams {
public:
- // Callback used to create EncryptedMediaPlayerSupport instances. This
- // callback must always return a valid EncryptedMediaPlayerSupport object.
- typedef base::Callback<scoped_ptr<EncryptedMediaPlayerSupport>(
- blink::WebMediaPlayerClient*)> EncryptedMediaPlayerSupportCreateCB;
typedef base::Callback<void(const base::Closure&)> DeferLoadCB;
// |defer_load_cb|, |audio_renderer_sink|, and |compositor_task_runner| may be
@@ -44,8 +41,6 @@ class MEDIA_EXPORT WebMediaPlayerParams {
const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories,
const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner,
const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner,
- const EncryptedMediaPlayerSupportCreateCB&
- encrypted_media_player_support_cb,
blink::WebContentDecryptionModule* initial_cdm);
~WebMediaPlayerParams();
@@ -81,8 +76,9 @@ class MEDIA_EXPORT WebMediaPlayerParams {
return compositor_task_runner_;
}
- scoped_ptr<EncryptedMediaPlayerSupport>
- CreateEncryptedMediaPlayerSupport(blink::WebMediaPlayerClient* client) const;
+ blink::WebContentDecryptionModule* initial_cdm() const {
+ return initial_cdm_;
+ }
private:
base::Callback<void(const base::Closure&)> defer_load_cb_;
@@ -92,7 +88,6 @@ class MEDIA_EXPORT WebMediaPlayerParams {
scoped_refptr<GpuVideoAcceleratorFactories> gpu_factories_;
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
- EncryptedMediaPlayerSupportCreateCB encrypted_media_player_support_cb_;
blink::WebContentDecryptionModule* initial_cdm_;
DISALLOW_IMPLICIT_CONSTRUCTORS(WebMediaPlayerParams);
diff --git a/content/renderer/media/crypto/proxy_decryptor.cc b/media/cdm/proxy_decryptor.cc
index 44a30fd..44c07e8 100644
--- a/content/renderer/media/crypto/proxy_decryptor.cc
+++ b/media/cdm/proxy_decryptor.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/media/crypto/proxy_decryptor.h"
+#include "media/cdm/proxy_decryptor.h"
#include <cstring>
@@ -15,7 +15,7 @@
#include "media/cdm/json_web_key.h"
#include "media/cdm/key_system_names.h"
-namespace content {
+namespace media {
// Special system code to signal a closed persistent session in a SessionError()
// call. This is needed because there is no SessionClosed() call in the prefixed
@@ -40,7 +40,7 @@ ProxyDecryptor::~ProxyDecryptor() {
media_keys_.reset();
}
-media::Decryptor* ProxyDecryptor::GetDecryptor() {
+Decryptor* ProxyDecryptor::GetDecryptor() {
return media_keys_ ? media_keys_->GetDecryptor() : NULL;
}
@@ -50,7 +50,7 @@ int ProxyDecryptor::GetCdmId() {
}
#endif
-bool ProxyDecryptor::InitializeCDM(media::CdmFactory* cdm_factory,
+bool ProxyDecryptor::InitializeCDM(CdmFactory* cdm_factory,
const std::string& key_system,
const GURL& security_origin) {
DVLOG(1) << "InitializeCDM: key_system = " << key_system;
@@ -61,7 +61,7 @@ bool ProxyDecryptor::InitializeCDM(media::CdmFactory* cdm_factory,
return false;
is_clear_key_ =
- media::IsClearKey(key_system) || media::IsExternalClearKey(key_system);
+ IsClearKey(key_system) || IsExternalClearKey(key_system);
return true;
}
@@ -96,8 +96,8 @@ bool ProxyDecryptor::GenerateKeyRequest(const std::string& init_data_type,
StripHeader(init_data_vector, strlen(kPrefixedApiPersistentSessionHeader));
}
- scoped_ptr<media::NewSessionCdmPromise> promise(
- new media::CdmCallbackPromise<std::string>(
+ scoped_ptr<NewSessionCdmPromise> promise(
+ new CdmCallbackPromise<std::string>(
base::Bind(&ProxyDecryptor::SetSessionId,
weak_ptr_factory_.GetWeakPtr(),
session_creation_type),
@@ -115,10 +115,10 @@ bool ProxyDecryptor::GenerateKeyRequest(const std::string& init_data_type,
return true;
}
- media::MediaKeys::SessionType session_type =
+ MediaKeys::SessionType session_type =
session_creation_type == PersistentSession
- ? media::MediaKeys::PERSISTENT_SESSION
- : media::MediaKeys::TEMPORARY_SESSION;
+ ? MediaKeys::PERSISTENT_SESSION
+ : MediaKeys::TEMPORARY_SESSION;
media_keys_->CreateSession(init_data_type,
init_data_vector_data,
@@ -145,14 +145,14 @@ void ProxyDecryptor::AddKey(const uint8* key,
session_id = it->first;
} else {
OnSessionError(std::string(),
- media::MediaKeys::NOT_SUPPORTED_ERROR,
+ MediaKeys::NOT_SUPPORTED_ERROR,
0,
"SessionId not specified.");
return;
}
}
- scoped_ptr<media::SimpleCdmPromise> promise(new media::CdmCallbackPromise<>(
+ scoped_ptr<SimpleCdmPromise> promise(new CdmCallbackPromise<>(
base::Bind(&ProxyDecryptor::OnSessionReady,
weak_ptr_factory_.GetWeakPtr(),
web_session_id),
@@ -174,7 +174,7 @@ void ProxyDecryptor::AddKey(const uint8* key,
}
std::string jwk =
- media::GenerateJWKSet(key, key_length, init_data, init_data_length);
+ GenerateJWKSet(key, key_length, init_data, init_data_length);
DCHECK(!jwk.empty());
media_keys_->UpdateSession(session_id,
reinterpret_cast<const uint8*>(jwk.data()),
@@ -189,7 +189,7 @@ void ProxyDecryptor::AddKey(const uint8* key,
void ProxyDecryptor::CancelKeyRequest(const std::string& web_session_id) {
DVLOG(1) << "CancelKeyRequest()";
- scoped_ptr<media::SimpleCdmPromise> promise(new media::CdmCallbackPromise<>(
+ scoped_ptr<SimpleCdmPromise> promise(new CdmCallbackPromise<>(
base::Bind(&ProxyDecryptor::OnSessionClosed,
weak_ptr_factory_.GetWeakPtr(),
web_session_id),
@@ -199,8 +199,8 @@ void ProxyDecryptor::CancelKeyRequest(const std::string& web_session_id) {
media_keys_->RemoveSession(web_session_id, promise.Pass());
}
-scoped_ptr<media::MediaKeys> ProxyDecryptor::CreateMediaKeys(
- media::CdmFactory* cdm_factory,
+scoped_ptr<MediaKeys> ProxyDecryptor::CreateMediaKeys(
+ CdmFactory* cdm_factory,
const std::string& key_system,
const GURL& security_origin) {
base::WeakPtr<ProxyDecryptor> weak_this = weak_ptr_factory_.GetWeakPtr();
@@ -224,7 +224,7 @@ void ProxyDecryptor::OnSessionMessage(const std::string& web_session_id,
// as the message. If unable to extract the key, return the message unchanged.
if (is_clear_key_) {
std::vector<uint8> key;
- if (media::ExtractFirstKeyIdFromLicenseRequest(message, &key)) {
+ if (ExtractFirstKeyIdFromLicenseRequest(message, &key)) {
key_message_cb_.Run(web_session_id, key, destination_url);
return;
}
@@ -265,8 +265,7 @@ void ProxyDecryptor::OnSessionClosed(const std::string& web_session_id) {
return;
if (it->second) {
- OnSessionError(web_session_id,
- media::MediaKeys::NOT_SUPPORTED_ERROR,
+ OnSessionError(web_session_id, MediaKeys::NOT_SUPPORTED_ERROR,
kSessionClosedSystemCode,
"Do not close persistent sessions.");
}
@@ -274,24 +273,24 @@ void ProxyDecryptor::OnSessionClosed(const std::string& web_session_id) {
}
void ProxyDecryptor::OnSessionError(const std::string& web_session_id,
- media::MediaKeys::Exception exception_code,
+ MediaKeys::Exception exception_code,
uint32 system_code,
const std::string& error_message) {
// Convert |error_name| back to MediaKeys::KeyError if possible. Prefixed
// EME has different error message, so all the specific error events will
// get lost.
- media::MediaKeys::KeyError error_code;
+ MediaKeys::KeyError error_code;
switch (exception_code) {
- case media::MediaKeys::CLIENT_ERROR:
- error_code = media::MediaKeys::kClientError;
+ case MediaKeys::CLIENT_ERROR:
+ error_code = MediaKeys::kClientError;
break;
- case media::MediaKeys::OUTPUT_ERROR:
- error_code = media::MediaKeys::kOutputError;
+ case MediaKeys::OUTPUT_ERROR:
+ error_code = MediaKeys::kOutputError;
break;
default:
// This will include all other CDM4 errors and any error generated
// by CDM5 or later.
- error_code = media::MediaKeys::kUnknownError;
+ error_code = MediaKeys::kUnknownError;
break;
}
key_error_cb_.Run(web_session_id, error_code, system_code);
@@ -309,4 +308,4 @@ void ProxyDecryptor::SetSessionId(SessionCreationType session_type,
OnSessionReady(web_session_id);
}
-} // namespace content
+} // namespace media
diff --git a/content/renderer/media/crypto/proxy_decryptor.h b/media/cdm/proxy_decryptor.h
index 62f2e8e..193c6b0 100644
--- a/content/renderer/media/crypto/proxy_decryptor.h
+++ b/media/cdm/proxy_decryptor.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_
-#define CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_
+#ifndef MEDIA_CDM_PROXY_DECRYPTOR_H_
+#define MEDIA_CDM_PROXY_DECRYPTOR_H_
#include <string>
#include <vector>
@@ -13,15 +13,14 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "media/base/decryptor.h"
+#include "media/base/media_export.h"
#include "media/base/media_keys.h"
class GURL;
namespace media {
-class CdmFactory;
-}
-namespace content {
+class CdmFactory;
// ProxyDecryptor is for EME v0.1b only. It should not be used for the WD API.
// A decryptor proxy that creates a real decryptor object on demand and
@@ -30,13 +29,13 @@ namespace content {
// TODO(xhwang): Currently we don't support run-time switching among decryptor
// objects. Fix this when needed.
// TODO(xhwang): The ProxyDecryptor is not a Decryptor. Find a better name!
-class ProxyDecryptor {
+class MEDIA_EXPORT ProxyDecryptor {
public:
// These are similar to the callbacks in media_keys.h, but pass back the
// web session ID rather than the internal session ID.
typedef base::Callback<void(const std::string& session_id)> KeyAddedCB;
typedef base::Callback<void(const std::string& session_id,
- media::MediaKeys::KeyError error_code,
+ MediaKeys::KeyError error_code,
uint32 system_code)> KeyErrorCB;
typedef base::Callback<void(const std::string& session_id,
const std::vector<uint8>& message,
@@ -49,7 +48,7 @@ class ProxyDecryptor {
// Returns the Decryptor associated with this object. May be NULL if no
// Decryptor is associated.
- media::Decryptor* GetDecryptor();
+ Decryptor* GetDecryptor();
#if defined(ENABLE_BROWSER_CDMS)
// Returns the CDM ID associated with this object. May be kInvalidCdmId if no
@@ -58,7 +57,7 @@ class ProxyDecryptor {
#endif
// Only call this once.
- bool InitializeCDM(media::CdmFactory* cdm_factory,
+ bool InitializeCDM(CdmFactory* cdm_factory,
const std::string& key_system,
const GURL& security_origin);
@@ -73,8 +72,8 @@ class ProxyDecryptor {
private:
// Helper function to create MediaKeys to handle the given |key_system|.
- scoped_ptr<media::MediaKeys> CreateMediaKeys(
- media::CdmFactory* cdm_factory,
+ scoped_ptr<MediaKeys> CreateMediaKeys(
+ CdmFactory* cdm_factory,
const std::string& key_system,
const GURL& security_origin);
@@ -89,7 +88,7 @@ class ProxyDecryptor {
void OnSessionReady(const std::string& web_session_id);
void OnSessionClosed(const std::string& web_session_id);
void OnSessionError(const std::string& web_session_id,
- media::MediaKeys::Exception exception_code,
+ MediaKeys::Exception exception_code,
uint32 system_code,
const std::string& error_message);
@@ -104,7 +103,7 @@ class ProxyDecryptor {
const std::string& web_session_id);
// The real MediaKeys that manages key operations for the ProxyDecryptor.
- scoped_ptr<media::MediaKeys> media_keys_;
+ scoped_ptr<MediaKeys> media_keys_;
// Callbacks for firing key events.
KeyAddedCB key_added_cb_;
@@ -126,6 +125,6 @@ class ProxyDecryptor {
DISALLOW_COPY_AND_ASSIGN(ProxyDecryptor);
};
-} // namespace content
+} // namespace media
-#endif // CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_
+#endif // MEDIA_CDM_PROXY_DECRYPTOR_H_
diff --git a/media/media.gyp b/media/media.gyp
index 3c438db..e60d4f8 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -388,6 +388,8 @@
'cdm/key_system_names.h',
'cdm/player_tracker_impl.cc',
'cdm/player_tracker_impl.h',
+ 'cdm/proxy_decryptor.cc',
+ 'cdm/proxy_decryptor.h',
'ffmpeg/ffmpeg_common.cc',
'ffmpeg/ffmpeg_common.h',
'ffmpeg/ffmpeg_deleters.h',
diff --git a/mojo/services/html_viewer/webmediaplayer_factory.cc b/mojo/services/html_viewer/webmediaplayer_factory.cc
index fbb8e9d..6c4653a 100644
--- a/mojo/services/html_viewer/webmediaplayer_factory.cc
+++ b/mojo/services/html_viewer/webmediaplayer_factory.cc
@@ -15,7 +15,6 @@
#include "media/base/media.h"
#include "media/base/media_log.h"
#include "media/base/renderer.h"
-#include "media/blink/null_encrypted_media_player_support.h"
#include "media/blink/webmediaplayer_impl.h"
#include "media/blink/webmediaplayer_params.h"
#include "media/filters/gpu_video_accelerator_factories.h"
@@ -72,12 +71,12 @@ blink::WebMediaPlayer* WebMediaPlayerFactory::CreateMediaPlayer(
scoped_refptr<media::GpuVideoAcceleratorFactories>(),
GetMediaThreadTaskRunner(),
compositor_task_runner_,
- base::Bind(&media::NullEncryptedMediaPlayerSupport::Create),
NULL);
base::WeakPtr<media::WebMediaPlayerDelegate> delegate;
- return new media::WebMediaPlayerImpl(
- frame, client, delegate, renderer.Pass(), params);
+ // TODO(xhwang): Provide a media based CdmFactory implementation.
+ return new media::WebMediaPlayerImpl(frame, client, delegate, renderer.Pass(),
+ nullptr, params);
#endif
}