Commit 8d9534ba authored by Ted Meyer's avatar Ted Meyer Committed by Commit Bot

Adds Unit tests for supported profile helpers

Also moved the trace event to GetResolutionsForDecoders so that when it
is refactored, performance can be measurably improved.

Change-Id: Ia0d8808aac8962fde5a45753933672b49900d429
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1705034
Commit-Queue: Ted Meyer <tmathmeyer@chromium.org>
Reviewed-by: default avatarFrank Liberato <liberato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#680126}
parent e8942634
......@@ -584,6 +584,7 @@ source_set("unit_tests") {
"windows/d3d11_texture_selector_unittest.cc",
"windows/d3d11_video_decoder_unittest.cc",
"windows/d3d11_video_processor_proxy_unittest.cc",
"windows/supported_profile_helpers_unittest.cc",
]
libs = [ "dxguid.lib" ]
}
......
......@@ -164,7 +164,6 @@ ResolutionPair GetMaxResolutionsForGUIDs(
const std::vector<GUID>& valid_guids,
const std::vector<gfx::Size>& resolutions_to_test,
DXGI_FORMAT format) {
TRACE_EVENT0("gpu,startup", "GetMaxResolutionsForGUIDs");
ResolutionPair result(default_max, gfx::Size());
// Enumerate supported video profiles and look for the profile.
......@@ -208,12 +207,15 @@ ResolutionPair GetMaxResolutionsForGUIDs(
return result;
}
// TODO(tmathmeyer) refactor this so that we don'ty call
// GetMaxResolutionsForGUIDS so many times.
void GetResolutionsForDecoders(std::vector<GUID> h264_guids,
ComD3D11Device device,
const gpu::GpuDriverBugWorkarounds& workarounds,
ResolutionPair* h264_resolutions,
ResolutionPair* vp9_0_resolutions,
ResolutionPair* vp9_2_resolutions) {
TRACE_EVENT0("gpu,startup", "GetResolutionsForDecoders");
if (base::win::GetVersion() > base::win::Version::WIN7) {
// To detect if a driver supports the desired resolutions, we try and create
// a DXVA decoder instance for that resolution and profile. If that succeeds
......
......@@ -12,6 +12,7 @@
#include <vector>
#include "gpu/config/gpu_driver_bug_workarounds.h"
#include "media/gpu/media_gpu_export.h"
#include "media/gpu/windows/d3d11_com_defs.h"
#include "ui/gfx/geometry/rect.h"
......@@ -37,6 +38,7 @@ ResolutionPair GetMaxResolutionsForGUIDs(
const std::vector<gfx::Size>& resolutions_to_test,
DXGI_FORMAT format = DXGI_FORMAT_NV12);
MEDIA_GPU_EXPORT
void GetResolutionsForDecoders(std::vector<GUID> h264_guids,
ComD3D11Device device,
const gpu::GpuDriverBugWorkarounds& workarounds,
......
// Copyright 2019 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/gpu/windows/supported_profile_helpers.h"
#include <d3d11.h>
#include <d3d11_1.h>
#include <initguid.h>
#include <map>
#include <utility>
#include "base/win/windows_version.h"
#include "media/base/test_helpers.h"
#include "media/base/win/d3d11_mocks.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::_;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::WithArgs;
#define DONT_RUN_ON_WIN_7() \
do { \
if (base::win::GetVersion() <= base::win::Version::WIN7) \
return; \
} while (0)
HRESULT SetIfSizeLessThan(D3D11_VIDEO_DECODER_DESC* desc, UINT* count) {
*count = 1;
return S_OK;
}
namespace media {
class SupportedResolutionResolverTest : public ::testing::Test {
public:
const std::pair<uint16_t, uint16_t> LegacyIntelGPU = {0x8086, 0x102};
const std::pair<uint16_t, uint16_t> RecentIntelGPU = {0x8086, 0x100};
const std::pair<uint16_t, uint16_t> LegacyAMDGPU = {0x1022, 0x130f};
const std::pair<uint16_t, uint16_t> RecentAMDGPU = {0x1022, 0x130e};
const ResolutionPair ten_eighty = {{1920, 1080}, {1080, 1920}};
const ResolutionPair zero = {{0, 0}, {0, 0}};
const ResolutionPair tall4k = {{4096, 2304}, {2304, 4096}};
const ResolutionPair eightKsquare = {{8192, 8192}, {8192, 8192}};
void SetUp() override {
gpu_workarounds_.disable_dxgi_zero_copy_video = false;
mock_d3d11_device_ = CreateD3D11Mock<NiceMock<D3D11DeviceMock>>();
mock_dxgi_device_ = CreateD3D11Mock<NiceMock<DXGIDeviceMock>>();
ON_CALL(*mock_d3d11_device_.Get(), QueryInterface(IID_IDXGIDevice, _))
.WillByDefault(SetComPointeeAndReturnOk<1>(mock_dxgi_device_.Get()));
mock_d3d11_video_device_ =
CreateD3D11Mock<NiceMock<D3D11VideoDeviceMock>>();
ON_CALL(*mock_d3d11_device_.Get(), QueryInterface(IID_ID3D11VideoDevice, _))
.WillByDefault(
SetComPointeeAndReturnOk<1>(mock_d3d11_video_device_.Get()));
mock_dxgi_adapter_ = CreateD3D11Mock<NiceMock<DXGIAdapterMock>>();
ON_CALL(*mock_dxgi_device_.Get(), GetAdapter(_))
.WillByDefault(SetComPointeeAndReturnOk<0>(mock_dxgi_adapter_.Get()));
SetGPUProfile(RecentIntelGPU);
SetMaxResolutionForGUID(D3D11_DECODER_PROFILE_H264_VLD_NOFGT, {4096, 4096});
}
void SetMaxResolutionForGUID(const GUID& g, const gfx::Size& max_res) {
max_size_for_guids_[g] = max_res;
ON_CALL(*mock_d3d11_video_device_.Get(), GetVideoDecoderConfigCount(_, _))
.WillByDefault(
WithArgs<0, 1>(Invoke([this](const D3D11_VIDEO_DECODER_DESC* desc,
UINT* count) -> HRESULT {
*count = 0;
const auto& itr = this->max_size_for_guids_.find(desc->Guid);
if (itr == this->max_size_for_guids_.end())
return E_FAIL;
const gfx::Size max = itr->second;
if (max.height() < 0 || max.width() < 0)
return E_FAIL;
if (static_cast<UINT>(max.height()) < desc->SampleHeight)
return E_FAIL;
if (static_cast<UINT>(max.width()) < desc->SampleWidth)
return S_OK;
*count = 1;
return S_OK;
})));
}
void EnableDecoders(const std::vector<GUID>& decoder_guids) {
ON_CALL(*mock_d3d11_video_device_.Get(), GetVideoDecoderProfileCount())
.WillByDefault(Return(decoder_guids.size()));
// Note that we don't check if the guid in the config actually matches
// |decoder_profile|. Perhaps we should.
ON_CALL(*mock_d3d11_video_device_.Get(), GetVideoDecoderProfile(_, _))
.WillByDefault(WithArgs<0, 1>(
Invoke([decoder_guids](UINT p_idx, GUID* guid) -> HRESULT {
if (p_idx >= decoder_guids.size())
return E_FAIL;
*guid = decoder_guids.at(p_idx);
return S_OK;
})));
}
void SetGPUProfile(std::pair<uint16_t, uint16_t> vendor_and_gpu) {
mock_adapter_desc_.DeviceId = static_cast<UINT>(vendor_and_gpu.second);
mock_adapter_desc_.VendorId = static_cast<UINT>(vendor_and_gpu.first);
ON_CALL(*mock_dxgi_adapter_.Get(), GetDesc(_))
.WillByDefault(
DoAll(SetArgPointee<0>(mock_adapter_desc_), Return(S_OK)));
}
Microsoft::WRL::ComPtr<D3D11DeviceMock> mock_d3d11_device_;
Microsoft::WRL::ComPtr<DXGIAdapterMock> mock_dxgi_adapter_;
Microsoft::WRL::ComPtr<DXGIDeviceMock> mock_dxgi_device_;
Microsoft::WRL::ComPtr<D3D11VideoDeviceMock> mock_d3d11_video_device_;
DXGI_ADAPTER_DESC mock_adapter_desc_;
gpu::GpuDriverBugWorkarounds gpu_workarounds_;
struct GUIDComparison {
bool operator()(const GUID& a, const GUID& b) const {
return memcmp(&a, &b, sizeof(GUID)) < 0;
}
};
std::map<GUID, gfx::Size, GUIDComparison> max_size_for_guids_;
};
TEST_F(SupportedResolutionResolverTest, NoDeviceAllDefault) {
DONT_RUN_ON_WIN_7();
ResolutionPair h264_res_expected = {{1, 2}, {3, 4}};
ResolutionPair h264_res = {{1, 2}, {3, 4}};
ResolutionPair vp9_0_res;
ResolutionPair vp9_2_res;
GetResolutionsForDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT}, nullptr,
gpu_workarounds_, &h264_res, &vp9_0_res,
&vp9_2_res);
ASSERT_EQ(h264_res, h264_res_expected);
ASSERT_EQ(vp9_0_res, zero);
ASSERT_EQ(vp9_0_res, zero);
}
TEST_F(SupportedResolutionResolverTest, LegacyGPUAllDefault) {
DONT_RUN_ON_WIN_7();
SetGPUProfile(LegacyIntelGPU);
ResolutionPair h264_res_expected = {{1, 2}, {3, 4}};
ResolutionPair h264_res = {{1, 2}, {3, 4}};
ResolutionPair vp9_0_res;
ResolutionPair vp9_2_res;
GetResolutionsForDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT},
mock_d3d11_device_, gpu_workarounds_, &h264_res,
&vp9_0_res, &vp9_2_res);
ASSERT_EQ(h264_res, h264_res_expected);
ASSERT_EQ(vp9_2_res, zero);
ASSERT_EQ(vp9_0_res, zero);
}
TEST_F(SupportedResolutionResolverTest, WorkaroundsDisableVpx) {
DONT_RUN_ON_WIN_7();
gpu_workarounds_.disable_dxgi_zero_copy_video = true;
EnableDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT});
ResolutionPair h264_res;
ResolutionPair vp9_0_res;
ResolutionPair vp9_2_res;
GetResolutionsForDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT},
mock_d3d11_device_, gpu_workarounds_, &h264_res,
&vp9_0_res, &vp9_2_res);
ASSERT_EQ(h264_res, tall4k);
ASSERT_EQ(vp9_0_res, zero);
ASSERT_EQ(vp9_2_res, zero);
}
TEST_F(SupportedResolutionResolverTest, VP9_0Supports8k) {
DONT_RUN_ON_WIN_7();
EnableDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT,
D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0});
SetMaxResolutionForGUID(D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0, {8192, 8192});
ResolutionPair h264_res;
ResolutionPair vp9_0_res;
ResolutionPair vp9_2_res;
GetResolutionsForDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT},
mock_d3d11_device_, gpu_workarounds_, &h264_res,
&vp9_0_res, &vp9_2_res);
ASSERT_EQ(h264_res, tall4k);
ASSERT_EQ(vp9_0_res, eightKsquare);
ASSERT_EQ(vp9_2_res, zero);
}
TEST_F(SupportedResolutionResolverTest, BothVP9ProfilesSupported) {
DONT_RUN_ON_WIN_7();
EnableDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT,
D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0,
D3D11_DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2});
SetMaxResolutionForGUID(D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0, {8192, 8192});
SetMaxResolutionForGUID(D3D11_DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2,
{8192, 8192});
ResolutionPair h264_res;
ResolutionPair vp9_0_res;
ResolutionPair vp9_2_res;
GetResolutionsForDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT},
mock_d3d11_device_, gpu_workarounds_, &h264_res,
&vp9_0_res, &vp9_2_res);
ASSERT_EQ(h264_res, tall4k);
ASSERT_EQ(vp9_0_res, eightKsquare);
ASSERT_EQ(vp9_2_res, eightKsquare);
}
} // namespace media
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