Commit 744c08f1 authored by Mounir Lamouri's avatar Mounir Lamouri Committed by Commit Bot

Media Capabilities: implement response side of Encrypted Media.

This is adding an DecodingInfo class that carries key system access
information back and create a MediaKeySystemAccess.

This implementation in //media/blink is a stub that is meant to only
pass WPT tests at the moment.

Bug: 907909
Change-Id: I3bac0087ca3051defb8b47d10fffdb6052814ae9
Reviewed-on: https://chromium-review.googlesource.com/c/1348733
Commit-Queue: Mounir Lamouri <mlamouri@chromium.org>
Reviewed-by: default avatarChrome Cunningham <chcunningham@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611917}
parent df19cc67
......@@ -10,16 +10,18 @@
#include "base/bind_helpers.h"
#include "media/base/audio_codecs.h"
#include "media/base/decode_capabilities.h"
#include "media/base/key_system_names.h"
#include "media/base/mime_util.h"
#include "media/base/video_codecs.h"
#include "media/base/video_color_space.h"
#include "media/blink/webcontentdecryptionmoduleaccess_impl.h"
#include "media/filters/stream_parser_factory.h"
#include "media/mojo/interfaces/media_types.mojom.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "services/service_manager/public/cpp/connector.h"
#include "third_party/blink/public/platform/modules/media_capabilities/web_audio_configuration.h"
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_info.h"
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_configuration.h"
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_decoding_configuration.h"
#include "third_party/blink/public/platform/modules/media_capabilities/web_video_configuration.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/scoped_web_callbacks.h"
......@@ -145,7 +147,7 @@ namespace {
void VideoPerfInfoCallback(
blink::ScopedWebCallbacks<blink::WebMediaCapabilitiesDecodingInfoCallbacks>
scoped_callbacks,
std::unique_ptr<blink::WebMediaCapabilitiesInfo> info,
std::unique_ptr<blink::WebMediaCapabilitiesDecodingInfo> info,
bool is_smooth,
bool is_power_efficient) {
DCHECK(info->supported);
......@@ -162,11 +164,11 @@ void OnGetPerfInfoError(
} // namespace
void WebMediaCapabilitiesClientImpl::DecodingInfo(
const blink::WebMediaConfiguration& configuration,
const blink::WebMediaDecodingConfiguration& configuration,
std::unique_ptr<blink::WebMediaCapabilitiesDecodingInfoCallbacks>
callbacks) {
std::unique_ptr<blink::WebMediaCapabilitiesInfo> info(
new blink::WebMediaCapabilitiesInfo());
std::unique_ptr<blink::WebMediaCapabilitiesDecodingInfo> info(
new blink::WebMediaCapabilitiesDecodingInfo());
// MSE support is cheap to check (regex matching). Do it first.
if (configuration.type == blink::MediaConfigurationType::kMediaSource &&
......@@ -207,6 +209,27 @@ void WebMediaCapabilitiesClientImpl::DecodingInfo(
return;
}
// TODO(907909): this is a mock implementation of Encrypted Media support to
// have a form of end-to-end implementation.
if (configuration.key_system_configuration.has_value()) {
auto key_system_configuration = configuration.key_system_configuration;
if (!media::IsClearKey(key_system_configuration->key_system.Utf8())) {
info->supported = info->smooth = info->power_efficient = false;
callbacks->OnSuccess(std::move(info));
return;
}
info->supported = info->smooth = info->power_efficient = true;
info->content_decryption_module_access =
base::WrapUnique(WebContentDecryptionModuleAccessImpl::Create(
key_system_configuration->key_system, blink::WebSecurityOrigin(),
blink::WebMediaKeySystemConfiguration(), {}, nullptr));
callbacks->OnSuccess(std::move(info));
return;
}
// Video is supported! Check its performance history.
info->supported = true;
......
......@@ -21,7 +21,7 @@ class MEDIA_BLINK_EXPORT WebMediaCapabilitiesClientImpl
// Implementation of blink::WebMediaCapabilitiesClient.
void DecodingInfo(
const blink::WebMediaConfiguration&,
const blink::WebMediaDecodingConfiguration&,
std::unique_ptr<blink::WebMediaCapabilitiesDecodingInfoCallbacks>)
override;
......
......@@ -12,7 +12,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_callbacks.h"
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_configuration.h"
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_decoding_configuration.h"
using ::testing::_;
......@@ -38,7 +38,8 @@ class MockWebMediaCapabilitiesQueryCallbacks
public:
~MockWebMediaCapabilitiesQueryCallbacks() override = default;
void OnSuccess(std::unique_ptr<blink::WebMediaCapabilitiesInfo>) override {}
void OnSuccess(
std::unique_ptr<blink::WebMediaCapabilitiesDecodingInfo>) override {}
MOCK_METHOD0(OnError, void());
};
......@@ -55,10 +56,11 @@ TEST(WebMediaCapabilitiesClientImplTest, RunCallbackEvenIfMojoDisconnects) {
25, // framerate
};
static const blink::WebMediaConfiguration kFakeMediaConfiguration{
static const blink::WebMediaDecodingConfiguration kFakeMediaConfiguration{
blink::MediaConfigurationType::kFile,
base::nullopt, // audio configuration
kFakeVideoConfiguration, // video configuration
base::nullopt, // key system configuration
};
using ::testing::InvokeWithoutArgs;
......
......@@ -145,6 +145,7 @@ source_set("blink_headers") {
"platform/modules/media_capabilities/web_audio_configuration.h",
"platform/modules/media_capabilities/web_media_capabilities_callbacks.h",
"platform/modules/media_capabilities/web_media_capabilities_client.h",
"platform/modules/media_capabilities/web_media_capabilities_decoding_info.h",
"platform/modules/media_capabilities/web_media_capabilities_info.h",
"platform/modules/media_capabilities/web_media_capabilities_key_system_configuration.h",
"platform/modules/media_capabilities/web_media_configuration.h",
......
......@@ -7,13 +7,14 @@
#include <memory>
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_decoding_info.h"
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_info.h"
#include "third_party/blink/public/platform/web_callbacks.h"
namespace blink {
using WebMediaCapabilitiesDecodingInfoCallbacks =
WebCallbacks<std::unique_ptr<WebMediaCapabilitiesInfo>, void>;
WebCallbacks<std::unique_ptr<WebMediaCapabilitiesDecodingInfo>, void>;
using WebMediaCapabilitiesEncodingInfoCallbacks =
WebCallbacks<std::unique_ptr<WebMediaCapabilitiesInfo>, void>;
......
......@@ -11,7 +11,7 @@
namespace blink {
struct WebMediaConfiguration;
struct WebMediaDecodingConfiguration;
// Interface between Blink and the Media layer.
class WebMediaCapabilitiesClient {
......@@ -19,7 +19,7 @@ class WebMediaCapabilitiesClient {
virtual ~WebMediaCapabilitiesClient() = default;
virtual void DecodingInfo(
const WebMediaConfiguration&,
const WebMediaDecodingConfiguration&,
std::unique_ptr<WebMediaCapabilitiesDecodingInfoCallbacks>) = 0;
};
......
// Copyright 2017 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 THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIA_CAPABILITIES_WEB_MEDIA_CAPABILITIES_DECODING_INFO_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIA_CAPABILITIES_WEB_MEDIA_CAPABILITIES_DECODING_INFO_H_
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_info.h"
#include "third_party/blink/public/platform/web_content_decryption_module_access.h"
namespace blink {
// Represents a MediaCapabilitiesDecodingInfo dictionary to be used outside of
// Blink. This is set by consumers and sent back to Blink.
struct WebMediaCapabilitiesDecodingInfo : WebMediaCapabilitiesInfo {
std::unique_ptr<WebContentDecryptionModuleAccess>
content_decryption_module_access;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIA_CAPABILITIES_WEB_MEDIA_CAPABILITIES_DECODING_INFO_H_
......@@ -21,6 +21,16 @@ enum class MediaConfigurationType {
// It is created by Blink and passed to consumers that can assume that all
// required fields are properly set.
struct WebMediaConfiguration {
WebMediaConfiguration() = default;
WebMediaConfiguration(
MediaConfigurationType type,
base::Optional<WebAudioConfiguration> audio_configuration,
base::Optional<WebVideoConfiguration> video_configuration)
: type(type),
audio_configuration(audio_configuration),
video_configuration(video_configuration) {}
MediaConfigurationType type;
base::Optional<WebAudioConfiguration> audio_configuration;
......
......@@ -15,6 +15,17 @@ namespace blink {
// Blink. The added `key_system_configuration` is optional and, if set, can be
// assumed to match the requirements set by the specification.
struct WebMediaDecodingConfiguration : public WebMediaConfiguration {
WebMediaDecodingConfiguration() = default;
WebMediaDecodingConfiguration(
MediaConfigurationType type,
base::Optional<WebAudioConfiguration> audio_configuration,
base::Optional<WebVideoConfiguration> video_configuration,
base::Optional<WebMediaCapabilitiesKeySystemConfiguration>
key_system_configuration)
: WebMediaConfiguration(type, audio_configuration, video_configuration),
key_system_configuration(key_system_configuration) {}
base::Optional<WebMediaCapabilitiesKeySystemConfiguration>
key_system_configuration;
};
......
......@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_decoding_info_callbacks.h"
#include "third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.h"
#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_decoding_info.h"
namespace blink {
......@@ -16,7 +17,7 @@ MediaCapabilitiesDecodingInfoCallbacks::
~MediaCapabilitiesDecodingInfoCallbacks() = default;
void MediaCapabilitiesDecodingInfoCallbacks::OnSuccess(
std::unique_ptr<WebMediaCapabilitiesInfo> result) {
std::unique_ptr<WebMediaCapabilitiesDecodingInfo> result) {
if (!resolver_->GetExecutionContext() ||
resolver_->GetExecutionContext()->IsContextDestroyed()) {
return;
......@@ -28,6 +29,15 @@ void MediaCapabilitiesDecodingInfoCallbacks::OnSuccess(
info->setSmooth(result->smooth);
info->setPowerEfficient(result->power_efficient);
if (result->content_decryption_module_access) {
// Per spec, the key system access should only be set if the configuration
// is supported.
DCHECK(result->supported);
info->setKeySystemAccess(new MediaKeySystemAccess(
std::move(result->content_decryption_module_access)));
}
resolver_->Resolve(std::move(info));
}
......
......@@ -19,7 +19,7 @@ class MediaCapabilitiesDecodingInfoCallbacks
~MediaCapabilitiesDecodingInfoCallbacks() override;
void OnSuccess(std::unique_ptr<WebMediaCapabilitiesInfo>) override;
void OnSuccess(std::unique_ptr<WebMediaCapabilitiesDecodingInfo>) override;
void OnError() override;
private:
......
......@@ -168,4 +168,38 @@ promise_test(t => {
});
}, "Test that decodingInfo returns a valid MediaCapabilitiesDecodingInfo objects with encrypted media");
promise_test(t => {
return navigator.mediaCapabilities.decodingInfo({
type: 'file',
video: minimalVideoConfiguration,
keySystemConfiguration: {
keySystem: 'foobar',
videoRobustness: '',
}
}).then(ability => {
assert_false(ability.supported);
assert_false(ability.smooth);
assert_false(ability.powerEfficient);
assert_equals(ability.keySystemAccess, null);
});
}, "Test that random key systems are reported as non supported.");
// TODO(mlamouri): this test could be split in two tests for which codec support
// across browsers is widely compatible: one when all browsers wouldn't support
// and one where all browsers do support. The current approach is to check that
// the answer is consistent to the spec.
promise_test(t => {
return navigator.mediaCapabilities.decodingInfo({
type: 'file',
video: minimalVideoConfiguration,
audio: minimalAudioConfiguration,
keySystemConfiguration: minimalKeySystemConfiguration,
}).then(ability => {
if (ability.supported)
assert_not_equals(ability.keySystemAccess, null);
else
assert_equals(ability.keySystemAccess, null);
});
}, "Test that keySystemAccess is only null when not supported if keySystemConfiguration was used.");
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment