Commit aed2c210 authored by Xiaohan Wang's avatar Xiaohan Wang Committed by Commit Bot

media: Add WidevineCdmProxyFactory

This class is in charge of creating CdmProxy for Widevine CDM.

BUG=787650

Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: I0b6b1fa4621b41b727f1200725dedca647939628
Reviewed-on: https://chromium-review.googlesource.com/933369Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Commit-Queue: Xiaohan Wang <xhwang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541967}
parent e918f504
......@@ -21,6 +21,18 @@ static_library("gpu") {
"//media/cdm:cdm_paths",
"//media/cdm/library_cdm/clear_key_cdm:clear_key_cdm_proxy",
]
if (is_win) {
sources += [
"widevine_cdm_proxy_factory.cc",
"widevine_cdm_proxy_factory.h",
]
deps += [
"//media",
"//media/gpu",
]
libs = [ "d3d11.lib" ]
}
}
if (is_chromeos) {
......
......@@ -6,5 +6,7 @@ include_rules = [
"+content/public/child",
"+content/public/gpu",
"+media/cdm",
"+media/gpu",
"+services/service_manager/public/cpp",
"+third_party/widevine/cdm/widevine_cdm_common.h",
]
......@@ -9,13 +9,19 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/public/child/child_thread.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
#include "media/cdm/cdm_paths.h"
#include "media/cdm/library_cdm/clear_key_cdm/clear_key_cdm_proxy.h"
#endif
#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(OS_WIN)
#include "chrome/gpu/widevine_cdm_proxy_factory.h"
#include "third_party/widevine/cdm/widevine_cdm_common.h"
#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(OS_WIN)
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
#if defined(OS_CHROMEOS)
#include "components/arc/video_accelerator/gpu_arc_video_decode_accelerator.h"
......@@ -94,10 +100,14 @@ std::unique_ptr<media::CdmProxy> ChromeContentGpuClient::CreateCdmProxy(
if (cdm_guid == media::kClearKeyCdmGuid)
return std::make_unique<media::ClearKeyCdmProxy>();
// TODO(rkuroiwa): Support creating Widevine specific CDM proxy here.
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(OS_WIN)
if (cdm_guid == kWidevineCdmGuid)
return CreateWidevineCdmProxy();
#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(OS_WIN)
return nullptr;
}
#endif
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
#if defined(OS_CHROMEOS)
void ChromeContentGpuClient::CreateArcVideoDecodeAccelerator(
......
// Copyright 2018 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 "chrome/gpu/widevine_cdm_proxy_factory.h"
#include <comdef.h>
#include <initguid.h>
#include <iomanip>
#include "build/build_config.h"
#include "media/cdm/cdm_proxy.h"
#include "media/gpu/windows/d3d11_cdm_proxy.h"
namespace {
// Helpers for printing HRESULTs.
struct PrintHr {
explicit PrintHr(HRESULT hr) : hr(hr) {}
HRESULT hr;
};
std::ostream& operator<<(std::ostream& os, const PrintHr& phr) {
std::ios_base::fmtflags ff = os.flags();
os << _com_error(phr.hr).ErrorMessage() << " (" << std::showbase << std::hex
<< std::uppercase << std::setfill('0') << std::setw(8) << phr.hr << ")";
os.flags(ff);
return os;
}
// clang-format off
DEFINE_GUID(kD3D11ConfigWidevineStreamId,
0x586e681, 0x4e14, 0x4133, 0x85, 0xe5, 0xa1, 0x4, 0x1f, 0x59, 0x9e, 0x26);
// clang-format on
} // namespace
std::unique_ptr<media::CdmProxy> CreateWidevineCdmProxy() {
Microsoft::WRL::ComPtr<ID3D11Device> device;
Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device;
// D3D11CdmProxy requires D3D_FEATURE_LEVEL_11_1.
const D3D_FEATURE_LEVEL feature_levels[] = {D3D_FEATURE_LEVEL_11_1};
// Create device and pupulate |device|.
HRESULT hresult = D3D11CreateDevice(
nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, feature_levels,
arraysize(feature_levels), D3D11_SDK_VERSION, device.GetAddressOf(),
nullptr, nullptr);
if (FAILED(hresult)) {
DLOG(ERROR) << "Failed to create the D3D11Device: " << PrintHr(hresult);
return nullptr;
}
hresult = device.CopyTo(video_device.GetAddressOf());
if (FAILED(hresult)) {
DLOG(ERROR) << "Failed to get ID3D11VideoDevice: " << PrintHr(hresult);
return nullptr;
}
D3D11_VIDEO_CONTENT_PROTECTION_CAPS caps = {};
// Check whether kD3D11ConfigWidevineStreamId is supported.
// We do not care about decoder support so just use a null decoder profile.
hresult = video_device->GetContentProtectionCaps(
&kD3D11ConfigWidevineStreamId, nullptr, &caps);
if (FAILED(hresult)) {
DLOG(ERROR) << "Failed to GetContentProtectionCaps: " << PrintHr(hresult);
return nullptr;
}
media::D3D11CdmProxy::FunctionIdMap function_id_map{
{media::CdmProxy::Function::kIntelNegotiateCryptoSessionKeyExchange,
0x90000001}};
return std::make_unique<media::D3D11CdmProxy>(
kD3D11ConfigWidevineStreamId,
media::CdmProxy::Protocol::kIntelConvergedSecurityAndManageabilityEngine,
std::move(function_id_map));
}
// Copyright 2018 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 CHROME_GPU_WIDEVINE_CDM_PROXY_FACTORY_H_
#define CHROME_GPU_WIDEVINE_CDM_PROXY_FACTORY_H_
#include <memory>
namespace media {
class CdmProxy;
}
std::unique_ptr<media::CdmProxy> CreateWidevineCdmProxy();
#endif // CHROME_GPU_WIDEVINE_CDM_PROXY_FACTORY_H_
// Copyright 2018 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 "chrome/gpu/widevine_cdm_proxy_factory.h"
#include "media/cdm/cdm_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(WidevineCdmProxyFactoryTest, CreateWidevineCdmProxy) {
// This fucntion may return null on unsupported devices. Hence ignore the
// return value and just make sure we do not crash in all cases.
CreateWidevineCdmProxy();
}
......@@ -4327,6 +4327,11 @@ test("unit_tests") {
if (is_win || is_mac || (is_linux && !is_chromeos)) {
sources += [ "../browser/password_manager/password_store_signin_notifier_impl_unittest.cc" ]
}
# TODO(crbug.com/349182): Replace "is_chrome_branded" with "enable_widevine".
if (is_chrome_branded && is_win) {
sources += [ "../gpu/widevine_cdm_proxy_factory_unittest.cc" ]
}
}
static_library("test_support_unit") {
......
......@@ -66,6 +66,7 @@ component("gpu") {
# Only local test code, GPU-related IPC code in the media layer, and
# media-related content code should access //media/gpu.
visibility = [
"//chrome/gpu",
"//components/arc/common:media",
"//components/arc/video_accelerator",
"//components/viz/service/main",
......@@ -563,9 +564,9 @@ source_set("unit_tests") {
}
if (is_win && enable_library_cdms) {
sources += [
"windows/d3d11_cdm_proxy_unittest.cc",
"windows/d3d11_mocks.cc",
"windows/d3d11_mocks.h",
"windows/d3d11_proxy_unittest.cc",
]
libs = [ "dxguid.lib" ]
}
......
......@@ -144,26 +144,19 @@ void D3D11CdmProxy::Initialize(Client* client, InitializeCB init_cb) {
client_ = client;
D3D_FEATURE_LEVEL actual_feature_level = {};
D3D_FEATURE_LEVEL feature_levels[] = {D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0};
const D3D_FEATURE_LEVEL feature_levels[] = {D3D_FEATURE_LEVEL_11_1};
HRESULT hresult = create_device_func_.Run(
nullptr, // No adapter.
D3D_DRIVER_TYPE_HARDWARE, nullptr, // No software rasterizer.
0, // flags, none.
feature_levels, arraysize(feature_levels), D3D11_SDK_VERSION,
device_.GetAddressOf(), &actual_feature_level,
device_context_.GetAddressOf());
device_.GetAddressOf(), nullptr, device_context_.GetAddressOf());
if (FAILED(hresult)) {
DLOG(ERROR) << "Failed to create the D3D11Device:" << hresult;
failed();
return;
}
if (actual_feature_level != D3D_FEATURE_LEVEL_11_1) {
DLOG(ERROR) << "D3D11 feature level too low: " << actual_feature_level;
failed();
return;
}
hresult = device_.CopyTo(video_device_.GetAddressOf());
if (FAILED(hresult)) {
......
......@@ -93,7 +93,6 @@ class D3D11CdmProxyTest : public ::testing::Test {
EXPECT_CALL(create_device_mock_,
Create(_, D3D_DRIVER_TYPE_HARDWARE, _, _, _, _, _, _, _, _))
.WillOnce(DoAll(SetArgPointee<7>(device_mock_.Get()),
SetArgPointee<8>(D3D_FEATURE_LEVEL_11_1),
SetArgPointee<9>(device_context_mock_.Get()),
Return(S_OK)));
......
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