summaryrefslogtreecommitdiffstats
path: root/media/base
diff options
context:
space:
mode:
Diffstat (limited to 'media/base')
-rw-r--r--media/base/android/media_drm_bridge.cc67
-rw-r--r--media/base/android/media_drm_bridge.h16
-rw-r--r--media/base/key_systems.cc11
-rw-r--r--media/base/media.cc6
-rw-r--r--media/base/media.h6
-rw-r--r--media/base/mime_util_internal.cc5
6 files changed, 92 insertions, 19 deletions
diff --git a/media/base/android/media_drm_bridge.cc b/media/base/android/media_drm_bridge.cc
index 0633c31..a5975f3 100644
--- a/media/base/android/media_drm_bridge.cc
+++ b/media/base/android/media_drm_bridge.cc
@@ -26,6 +26,7 @@
#include "base/thread_task_runner_handle.h"
#include "jni/MediaDrmBridge_jni.h"
#include "media/base/android/media_client_android.h"
+#include "media/base/android/media_codec_util.h"
#include "media/base/android/media_drm_bridge_delegate.h"
#include "media/base/android/provision_fetcher.h"
#include "media/base/cdm_key_information.h"
@@ -174,8 +175,12 @@ base::LazyInstance<KeySystemManager>::Leaky g_key_system_manager =
// resolved.
bool IsKeySystemSupportedWithTypeImpl(const std::string& key_system,
const std::string& container_mime_type) {
- if (!MediaDrmBridge::IsAvailable())
+ DCHECK(MediaDrmBridge::IsAvailable());
+
+ if (key_system.empty()) {
+ NOTREACHED();
return false;
+ }
UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system);
if (scheme_uuid.empty())
@@ -215,10 +220,7 @@ std::string GetSecurityLevelString(
return "";
}
-} // namespace
-
-// static
-bool MediaDrmBridge::IsAvailable() {
+bool AreMediaDrmApisAvailable() {
if (base::android::BuildInfo::GetInstance()->sdk_int() < 19)
return false;
@@ -233,6 +235,15 @@ bool MediaDrmBridge::IsAvailable() {
return true;
}
+} // namespace
+
+// MediaDrm is not generally usable without MediaCodec. Thus, both the MediaDrm
+// APIs and MediaCodec APIs must be enabled and not blacklisted.
+// static
+bool MediaDrmBridge::IsAvailable() {
+ return AreMediaDrmApisAvailable() && MediaCodecUtil::IsMediaCodecAvailable();
+}
+
// static
bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) {
return RegisterNativesImpl(env);
@@ -240,7 +251,9 @@ bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) {
// static
bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) {
- DCHECK(!key_system.empty());
+ if (!MediaDrmBridge::IsAvailable())
+ return false;
+
return IsKeySystemSupportedWithTypeImpl(key_system, "");
}
@@ -248,17 +261,24 @@ bool MediaDrmBridge::IsKeySystemSupported(const std::string& key_system) {
bool MediaDrmBridge::IsKeySystemSupportedWithType(
const std::string& key_system,
const std::string& container_mime_type) {
- DCHECK(!key_system.empty() && !container_mime_type.empty());
+ DCHECK(!container_mime_type.empty()) << "Call IsKeySystemSupported instead";
+
+ if (!MediaDrmBridge::IsAvailable())
+ return false;
+
return IsKeySystemSupportedWithTypeImpl(key_system, container_mime_type);
}
// static
std::vector<std::string> MediaDrmBridge::GetPlatformKeySystemNames() {
+ if (!MediaDrmBridge::IsAvailable())
+ return std::vector<std::string>();
+
return g_key_system_manager.Get().GetPlatformKeySystemNames();
}
// static
-scoped_refptr<MediaDrmBridge> MediaDrmBridge::Create(
+scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateInternal(
const std::string& key_system,
SecurityLevel security_level,
const CreateFetcherCB& create_fetcher_cb,
@@ -267,10 +287,8 @@ scoped_refptr<MediaDrmBridge> MediaDrmBridge::Create(
const LegacySessionErrorCB& legacy_session_error_cb,
const SessionKeysChangeCB& session_keys_change_cb,
const SessionExpirationUpdateCB& session_expiration_update_cb) {
- DVLOG(1) << __FUNCTION__;
-
- if (!IsAvailable())
- return nullptr;
+ // All paths requires the MediaDrmApis.
+ DCHECK(AreMediaDrmApisAvailable());
UUID scheme_uuid = g_key_system_manager.Get().GetUUID(key_system);
if (scheme_uuid.empty())
@@ -288,12 +306,37 @@ scoped_refptr<MediaDrmBridge> MediaDrmBridge::Create(
}
// static
+scoped_refptr<MediaDrmBridge> MediaDrmBridge::Create(
+ const std::string& key_system,
+ SecurityLevel security_level,
+ const CreateFetcherCB& create_fetcher_cb,
+ const SessionMessageCB& session_message_cb,
+ const SessionClosedCB& session_closed_cb,
+ const LegacySessionErrorCB& legacy_session_error_cb,
+ const SessionKeysChangeCB& session_keys_change_cb,
+ const SessionExpirationUpdateCB& session_expiration_update_cb) {
+ DVLOG(1) << __FUNCTION__;
+
+ if (!IsAvailable())
+ return nullptr;
+
+ return CreateInternal(key_system, security_level, create_fetcher_cb,
+ session_message_cb, session_closed_cb,
+ legacy_session_error_cb, session_keys_change_cb,
+ session_expiration_update_cb);
+}
+
+// static
scoped_refptr<MediaDrmBridge> MediaDrmBridge::CreateWithoutSessionSupport(
const std::string& key_system,
SecurityLevel security_level,
const CreateFetcherCB& create_fetcher_cb) {
DVLOG(1) << __FUNCTION__;
+ // Sessions won't be used so decoding capability is not required.
+ if (!AreMediaDrmApisAvailable())
+ return nullptr;
+
return MediaDrmBridge::Create(key_system, security_level, create_fetcher_cb,
SessionMessageCB(), SessionClosedCB(),
LegacySessionErrorCB(), SessionKeysChangeCB(),
diff --git a/media/base/android/media_drm_bridge.h b/media/base/android/media_drm_bridge.h
index 04e57fc..d5408c1 100644
--- a/media/base/android/media_drm_bridge.h
+++ b/media/base/android/media_drm_bridge.h
@@ -55,9 +55,9 @@ class MEDIA_EXPORT MediaDrmBridge : public MediaKeys, public PlayerTracker {
using MediaCryptoReadyCB = base::Callback<void(JavaObjectPtr media_crypto,
bool needs_protected_surface)>;
- // Checks whether MediaDRM is available.
- // All other static methods check IsAvailable() internally. There's no need
- // to check IsAvailable() explicitly before calling them.
+ // Checks whether MediaDRM is available and usable, including for decoding.
+ // All other static methods check IsAvailable() or equivalent internally.
+ // There is no need to check IsAvailable() explicitly before calling them.
static bool IsAvailable();
static bool RegisterMediaDrmBridge(JNIEnv* env);
@@ -243,6 +243,16 @@ class MEDIA_EXPORT MediaDrmBridge : public MediaKeys, public PlayerTracker {
// For DeleteSoon() in DeleteOnCorrectThread().
friend class base::DeleteHelper<MediaDrmBridge>;
+ static scoped_refptr<MediaDrmBridge> CreateInternal(
+ const std::string& key_system,
+ SecurityLevel security_level,
+ const CreateFetcherCB& create_fetcher_cb,
+ const SessionMessageCB& session_message_cb,
+ const SessionClosedCB& session_closed_cb,
+ const LegacySessionErrorCB& legacy_session_error_cb,
+ const SessionKeysChangeCB& session_keys_change_cb,
+ const SessionExpirationUpdateCB& session_expiration_update_cb);
+
// Constructs a MediaDrmBridge for |scheme_uuid| and |security_level|. The
// default security level will be used if |security_level| is
// SECURITY_LEVEL_DEFAULT. Sessions should not be created if session callbacks
diff --git a/media/base/key_systems.cc b/media/base/key_systems.cc
index 914661f..8a3ae69 100644
--- a/media/base/key_systems.cc
+++ b/media/base/key_systems.cc
@@ -15,6 +15,7 @@
#include "base/time/time.h"
#include "build/build_config.h"
#include "media/base/key_system_info.h"
+#include "media/base/media.h"
#include "media/base/media_client.h"
#include "media/cdm/key_system_names.h"
#include "third_party/widevine/cdm/widevine_cdm_common.h"
@@ -409,6 +410,16 @@ void KeySystemsImpl::AddSupportedKeySystems(
DCHECK_EQ(key_system_map_.count(info.key_system), 0u)
<< "Key system '" << info.key_system << "' already registered";
+
+#if defined(OS_ANDROID)
+ // Ensure that the renderer can access the decoders necessary to use the
+ // key system.
+ if (!info.use_aes_decryptor && !ArePlatformDecodersAvailable()) {
+ DLOG(WARNING) << info.key_system << " not registered";
+ continue;
+ }
+#endif // defined(OS_ANDROID)
+
key_system_map_[info.key_system] = info;
}
}
diff --git a/media/base/media.cc b/media/base/media.cc
index efc495b..b2e1c45 100644
--- a/media/base/media.cc
+++ b/media/base/media.cc
@@ -115,6 +115,12 @@ bool IsUnifiedMediaPipelineEnabledForMse() {
switches::kEnableUnifiedMediaPipeline) ||
!MediaCodecUtil::IsMediaCodecAvailable();
}
+
+bool ArePlatformDecodersAvailable() {
+ return IsUnifiedMediaPipelineEnabled()
+ ? HasPlatformDecoderSupport()
+ : MediaCodecUtil::IsMediaCodecAvailable();
+}
#endif
} // namespace media
diff --git a/media/base/media.h b/media/base/media.h
index 65a7a69..b6cccc4 100644
--- a/media/base/media.h
+++ b/media/base/media.h
@@ -46,6 +46,12 @@ MEDIA_EXPORT bool IsUnifiedMediaPipelineEnabled();
// cases where existing pipeline has no support). As above, codecs requiring
// platform support may not be available.
MEDIA_EXPORT bool IsUnifiedMediaPipelineEnabledForMse();
+
+// Returns whether the platform decoders are available for use.
+// This includes decoders being available on the platform and accessible, such
+// as via the GPU process. Should only be used for actual decoders
+// (e.g. MediaCodec) and not full-featured players (e.g. MediaPlayer).
+MEDIA_EXPORT bool ArePlatformDecodersAvailable();
#endif
} // namespace media
diff --git a/media/base/mime_util_internal.cc b/media/base/mime_util_internal.cc
index a0ce3c4..7e7f004 100644
--- a/media/base/mime_util_internal.cc
+++ b/media/base/mime_util_internal.cc
@@ -274,10 +274,7 @@ MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) {
// When the unified media pipeline is enabled, we need support for both GPU
// video decoders and MediaCodec; indicated by HasPlatformDecoderSupport().
// When the Android pipeline is used, we only need access to MediaCodec.
- platform_info_.has_platform_decoders =
- platform_info_.is_unified_media_pipeline_enabled
- ? HasPlatformDecoderSupport()
- : MediaCodecUtil::IsMediaCodecAvailable();
+ platform_info_.has_platform_decoders = ArePlatformDecodersAvailable();
platform_info_.has_platform_vp8_decoder =
MediaCodecUtil::IsVp8DecoderAvailable();
platform_info_.supports_opus = PlatformHasOpusSupport();