Commit f2413ff1 authored by Rintaro Kuroiwa's avatar Rintaro Kuroiwa Committed by Commit Bot

Use the crypto session's device instead of creating a new one

- DecryptionBlt() implementation checks whether the buffers and crypto session are from
  the same device.

Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: Ic3215a828a782ff4aaf29bc1fb36153c5241a5c3
Reviewed-on: https://chromium-review.googlesource.com/1188631
Commit-Queue: Rintaro Kuroiwa <rkuroiwa@chromium.org>
Reviewed-by: default avatarXiaohan Wang <xhwang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#586413}
parent df8d7a0c
......@@ -104,9 +104,7 @@ bool IsWholeSampleEncrypted(const DecryptConfig& decrypt_config,
} // namespace
D3D11Decryptor::D3D11Decryptor(CdmProxyContext* cdm_proxy_context)
: cdm_proxy_context_(cdm_proxy_context),
create_device_func_(base::BindRepeating(D3D11CreateDevice)),
weak_factory_(this) {
: cdm_proxy_context_(cdm_proxy_context), weak_factory_(this) {
DCHECK(cdm_proxy_context_);
}
......@@ -147,7 +145,10 @@ void D3D11Decryptor::Decrypt(StreamType stream_type,
return;
}
if (!IsDecryptionBufferInitialized() && !InitializeDecryptionBuffer()) {
// Because DecryptionBlt() implementation checks whether the device, buffers,
// and the crypto session are from the same device, the buffers have to be
// recreated.
if (!InitializeDecryptionBuffer(*context)) {
decrypt_cb.Run(kError, nullptr);
return;
}
......@@ -214,30 +215,21 @@ void D3D11Decryptor::DeinitializeDecoder(StreamType stream_type) {
// nothing to be done here.
}
bool D3D11Decryptor::IsDecryptionBufferInitialized() {
// This must be the last object initialized in InitializeDecryptionBuffer().
return cpu_accessible_buffer_;
}
bool D3D11Decryptor::InitializeDecryptionBuffer() {
const D3D_FEATURE_LEVEL feature_levels[] = {D3D_FEATURE_LEVEL_11_1};
HRESULT hresult = create_device_func_.Run(
nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, feature_levels,
base::size(feature_levels), D3D11_SDK_VERSION,
device_.ReleaseAndGetAddressOf(), nullptr,
device_context_.ReleaseAndGetAddressOf());
if (FAILED(hresult)) {
DVLOG(2) << "Failed to create D3D11 device: " << hresult;
return false;
}
bool D3D11Decryptor::InitializeDecryptionBuffer(
const CdmProxyContext::D3D11DecryptContext& decrypt_context) {
// TODO(crbug.com/877667): Check whether the crypto session's device is the
// same as device_, if so there is no reason to recreate buffers.
decrypt_context.crypto_session->GetDevice(device_.ReleaseAndGetAddressOf());
device_->GetImmediateContext(device_context_.ReleaseAndGetAddressOf());
hresult = device_context_.CopyTo(video_context_.ReleaseAndGetAddressOf());
HRESULT hresult =
device_context_.CopyTo(video_context_.ReleaseAndGetAddressOf());
if (FAILED(hresult)) {
DVLOG(2) << "Failed to get video context.";
return false;
}
// The buffer is statging so that the data can be accessed by the CPU and HW.
// The buffer is staging so that the data can be accessed by the CPU and HW.
if (!CreateBuffer(device_.Get(), D3D11_USAGE_STAGING, 0, // no binding.
D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE,
encrypted_sample_buffer_.ReleaseAndGetAddressOf())) {
......
......@@ -40,16 +40,10 @@ class MEDIA_GPU_EXPORT D3D11Decryptor : public Decryptor {
void ResetDecoder(StreamType stream_type) final;
void DeinitializeDecoder(StreamType stream_type) final;
void SetCreateDeviceCallbackForTesting(D3D11CreateDeviceCB callback) {
create_device_func_ = callback;
}
private:
// Returns true if the decryption buffers have been initialized.
bool IsDecryptionBufferInitialized();
// Initialize the buffers for decryption.
bool InitializeDecryptionBuffer();
// Initialize the buffers for decryption from decryption context.
bool InitializeDecryptionBuffer(
const CdmProxyContext::D3D11DecryptContext& decrypt_context);
// CTR mode decrypts |encrypted| data into |output|. |output| is always
// cleared. Returns true on success.
......@@ -90,10 +84,6 @@ class MEDIA_GPU_EXPORT D3D11Decryptor : public Decryptor {
// to.
ComPtr<ID3D11Buffer> cpu_accessible_buffer_;
// Can be set in tests via SetCreateDeviceCallbackForTesting().
// Is D3D11CreateDevice() when not mocked.
D3D11CreateDeviceCB create_device_func_;
base::WeakPtrFactory<D3D11Decryptor> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(D3D11Decryptor);
......
......@@ -123,24 +123,11 @@ class D3D11DecryptorTest : public ::testing::Test {
device_mock_ = CreateD3D11Mock<D3D11DeviceMock>();
device_context_mock_ = CreateD3D11Mock<D3D11DeviceContextMock>();
video_context_mock_ = CreateD3D11Mock<D3D11VideoContextMock>();
ON_CALL(create_device_mock_,
Create(_, D3D_DRIVER_TYPE_HARDWARE, _, _, _, _, _, _, _, _))
.WillByDefault(
DoAll(AddRefAndSetArgPointee<7>(device_mock_.Get()),
AddRefAndSetArgPointee<9>(device_context_mock_.Get()),
Return(S_OK)));
decryptor_->SetCreateDeviceCallbackForTesting(
base::BindRepeating(&D3D11CreateDeviceMock::Create,
base::Unretained(&create_device_mock_)));
}
std::unique_ptr<D3D11Decryptor> decryptor_;
CdmProxyContextMock mock_proxy_;
D3D11CreateDeviceMock create_device_mock_;
ComPtr<D3D11DeviceMock> device_mock_;
ComPtr<D3D11DeviceContextMock> device_context_mock_;
ComPtr<D3D11VideoContextMock> video_context_mock_;
......@@ -170,14 +157,17 @@ TEST_F(D3D11DecryptorTest, FullSampleCtrDecrypt) {
decrypt_context.key_blob = kAnyKeyBlob;
decrypt_context.key_blob_size = base::size(kAnyKeyBlob);
decrypt_context.key_info_guid = TEST_GUID;
EXPECT_CALL(*crypto_session_mock.Get(), GetDevice(_))
.Times(AtLeast(1))
.WillRepeatedly(AddRefAndSetArgPointee<0>(device_mock_.Get()));
EXPECT_CALL(*device_mock_.Get(), GetImmediateContext(_))
.Times(AtLeast(1))
.WillRepeatedly(AddRefAndSetArgPointee<0>(device_context_mock_.Get()));
EXPECT_CALL(mock_proxy_, GetD3D11DecryptContext(kKeyId))
.WillOnce(Return(decrypt_context));
EXPECT_CALL(create_device_mock_,
Create(_, D3D_DRIVER_TYPE_HARDWARE, _, _, _, _, _, _, _, _))
.WillOnce(DoAll(AddRefAndSetArgPointee<7>(device_mock_.Get()),
AddRefAndSetArgPointee<9>(device_context_mock_.Get()),
Return(S_OK)));
EXPECT_CALL(*device_context_mock_.Get(),
QueryInterface(IID_ID3D11VideoContext, _))
.Times(AtLeast(1))
......@@ -309,14 +299,17 @@ TEST_F(D3D11DecryptorTest, SubsampleCtrDecrypt) {
decrypt_context.key_blob = kAnyKeyBlob;
decrypt_context.key_blob_size = base::size(kAnyKeyBlob);
decrypt_context.key_info_guid = TEST_GUID;
EXPECT_CALL(*crypto_session_mock.Get(), GetDevice(_))
.Times(AtLeast(1))
.WillRepeatedly(AddRefAndSetArgPointee<0>(device_mock_.Get()));
EXPECT_CALL(*device_mock_.Get(), GetImmediateContext(_))
.Times(AtLeast(1))
.WillRepeatedly(AddRefAndSetArgPointee<0>(device_context_mock_.Get()));
EXPECT_CALL(mock_proxy_, GetD3D11DecryptContext(kKeyId))
.WillOnce(Return(decrypt_context));
EXPECT_CALL(create_device_mock_,
Create(_, D3D_DRIVER_TYPE_HARDWARE, _, _, _, _, _, _, _, _))
.WillOnce(DoAll(AddRefAndSetArgPointee<7>(device_mock_.Get()),
AddRefAndSetArgPointee<9>(device_context_mock_.Get()),
Return(S_OK)));
EXPECT_CALL(*device_context_mock_.Get(),
QueryInterface(IID_ID3D11VideoContext, _))
.Times(AtLeast(1))
......@@ -417,12 +410,20 @@ TEST_F(D3D11DecryptorTest, DecryptInputTooBig) {
CdmProxyContext::D3D11DecryptContext decrypt_context = {};
ComPtr<D3D11CryptoSessionMock> crypto_session_mock =
CreateD3D11Mock<D3D11CryptoSessionMock>();
decrypt_context.crypto_session = crypto_session_mock.Get();
decrypt_context.key_blob = kAnyKeyBlob;
decrypt_context.key_blob_size = base::size(kAnyKeyBlob);
decrypt_context.key_info_guid = TEST_GUID;
ON_CALL(mock_proxy_, GetD3D11DecryptContext(kKeyId))
.WillByDefault(Return(decrypt_context));
EXPECT_CALL(*crypto_session_mock.Get(), GetDevice(_))
.Times(AtLeast(1))
.WillRepeatedly(AddRefAndSetArgPointee<0>(device_mock_.Get()));
EXPECT_CALL(*device_mock_.Get(), GetImmediateContext(_))
.Times(AtLeast(1))
.WillRepeatedly(AddRefAndSetArgPointee<0>(device_context_mock_.Get()));
ComPtr<D3D11BufferMock> staging_buffer1 = CreateD3D11Mock<D3D11BufferMock>();
ComPtr<D3D11BufferMock> staging_buffer2 = CreateD3D11Mock<D3D11BufferMock>();
ComPtr<D3D11BufferMock> gpu_buffer = CreateD3D11Mock<D3D11BufferMock>();
......
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