Commit ff66de3b authored by Giovanni Ortuño Urquidi's avatar Giovanni Ortuño Urquidi Committed by Commit Bot

Revert "Refactor GetResolutionsForDecoders() to support AV1. Take #2"

This reverts commit 1470bc06.

Reason for revert: Still causing issues on windows:

https://ci.chromium.org/p/chromium/builders/ci/Win7%20Tests%20%281%29/103592

[ RUN      ] SupportedResolutionResolverTest.MultipleCodecs
../../media/gpu/windows/supported_profile_helpers_unittest.cc(249): error: Expected equality of these values:
  base::size(kSupportedH264Profiles) + 1
    Which is: 4
  supported_resolutions.size()
    Which is: 3
Stack trace:
Backtrace:
	media::SupportedResolutionResolverTest_MultipleCodecs_Test::TestBody [0x00E22189+1133]

[  FAILED  ] SupportedResolutionResolverTest.MultipleCodecs (46 ms)

Original change's description:
> Refactor GetResolutionsForDecoders() to support AV1. Take #2
> 
> Same as the previous patch, but avoids assigning from a const& that
> is destructed by the assignment. PS#1 is the original change, all
> later patch sets are the new one.
> 
> ---- [ Original Description Below ] ----
> 
> Does the following:
> - Internalizes h264 and min resolution details.
> - Sets the minimum resolution to 64,64 for both decoders.
> - Only loops through the video device profiles once.
> - Switches away from an std::pair to a named struct.
> - Adds AV1 GUID values and uses them in DXVA decoder.
> - Stops D3D11VideoDecoder for enumerating unsupported profiles.
> - Stops using the DXVA2_Intel_ModeH264_E for enumeration.
> - Gives all resolution tests a square resolution; e.g., 4k x 4k.
> - Doesn't test or indicate support for a duplicate portrait resolution.
> 
> TBR=liberato, tmathmeyer
> 
> Bug: 1073252
> Test: Updated unittests.
> Change-Id: I0503d43630238c0a11b3a683308232f13cfdf37b
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2227969
> Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
> Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#774474}

TBR=dalecurtis@chromium.org,liberato@chromium.org,tmathmeyer@chromium.org

Change-Id: I253f981c011e79a68ccf3625386275e44698c57d
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 1073252
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2228369Reviewed-by: default avatarGiovanni Ortuño Urquidi <ortuno@chromium.org>
Commit-Queue: Giovanni Ortuño Urquidi <ortuno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#774497}
parent 5caa62b5
...@@ -166,7 +166,6 @@ component("gpu") { ...@@ -166,7 +166,6 @@ component("gpu") {
if (is_win) { if (is_win) {
sources += [ sources += [
"windows/av1_guids.h",
"windows/d3d11_com_defs.h", "windows/d3d11_com_defs.h",
"windows/d3d11_copying_texture_wrapper.cc", "windows/d3d11_copying_texture_wrapper.cc",
"windows/d3d11_copying_texture_wrapper.h", "windows/d3d11_copying_texture_wrapper.h",
......
// Copyright 2020 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 MEDIA_GPU_WINDOWS_AV1_GUIDS_H_
#define MEDIA_GPU_WINDOWS_AV1_GUIDS_H_
#include <initguid.h>
#if WDK_NTDDI_VERSION <= NTDDI_WIN10_19H1
DEFINE_GUID(DXVA_ModeAV1_VLD_Profile0,
0xb8be4ccb,
0xcf53,
0x46ba,
0x8d,
0x59,
0xd6,
0xb8,
0xa6,
0xda,
0x5d,
0x2a);
DEFINE_GUID(DXVA_ModeAV1_VLD_Profile1,
0x6936ff0f,
0x45b1,
0x4163,
0x9c,
0xc1,
0x64,
0x6e,
0xf6,
0x94,
0x61,
0x08);
DEFINE_GUID(DXVA_ModeAV1_VLD_Profile2,
0x0c5f2aa1,
0xe541,
0x4089,
0xbb,
0x7b,
0x98,
0x11,
0x0a,
0x19,
0xd7,
0xc8);
#endif // WDK_NTDDI_VERSION <= NTDDI_WIN10_19H1
#endif // MEDIA_GPU_WINDOWS_AV1_GUIDS_H_
...@@ -908,35 +908,97 @@ D3D11VideoDecoder::GetSupportedVideoDecoderConfigs( ...@@ -908,35 +908,97 @@ D3D11VideoDecoder::GetSupportedVideoDecoderConfigs(
return {}; return {};
} }
const auto supported_resolutions =
GetSupportedD3D11VideoDecoderResolutions(d3d11_device, gpu_workarounds);
std::vector<SupportedVideoDecoderConfig> configs; std::vector<SupportedVideoDecoderConfig> configs;
for (const auto& kv : supported_resolutions) { // VP9 has no default resolutions since it may not even be supported.
const auto profile = kv.first; ResolutionPair max_h264_resolutions(gfx::Size(1920, 1088), gfx::Size());
if (profile == VP9PROFILE_PROFILE2 && ResolutionPair max_vp8_resolutions;
!base::FeatureList::IsEnabled(kD3D11VideoDecoderVP9Profile2)) { ResolutionPair max_vp9_profile0_resolutions;
continue; ResolutionPair max_vp9_profile2_resolutions;
} const gfx::Size min_resolution(64, 64);
// TODO(liberato): Add VP8 and AV1 support to D3D11VideoDecoder. GetResolutionsForDecoders(
if (profile == VP8PROFILE_ANY || {D3D11_DECODER_PROFILE_H264_VLD_NOFGT}, d3d11_device, gpu_workarounds,
(profile >= AV1PROFILE_MIN && profile <= AV1PROFILE_MAX)) { &max_h264_resolutions, &max_vp8_resolutions,
continue; &max_vp9_profile0_resolutions, &max_vp9_profile2_resolutions);
}
if (max_h264_resolutions.first.width() > 0) {
const auto& resolution_range = kv.second; // Push H264 configs, except HIGH10.
configs.emplace_back(profile, profile, resolution_range.min_resolution, // landscape
resolution_range.max_landscape_resolution, configs.push_back(SupportedVideoDecoderConfig(
/*allow_encrypted=*/false, H264PROFILE_MIN, // profile_min
/*require_encrypted=*/false); static_cast<VideoCodecProfile>(H264PROFILE_HIGH10PROFILE -
if (!resolution_range.max_portrait_resolution.IsEmpty() && 1), // profile_max
resolution_range.max_portrait_resolution != min_resolution, // coded_size_min
resolution_range.max_landscape_resolution) { max_h264_resolutions.first, // coded_size_max
configs.emplace_back(profile, profile, resolution_range.min_resolution, false, // allow_encrypted
resolution_range.max_portrait_resolution, false)); // require_encrypted
/*allow_encrypted=*/false, configs.push_back(SupportedVideoDecoderConfig(
/*require_encrypted=*/false); static_cast<VideoCodecProfile>(H264PROFILE_HIGH10PROFILE +
1), // profile_min
H264PROFILE_MAX, // profile_max
min_resolution, // coded_size_min
max_h264_resolutions.first, // coded_size_max
false, // allow_encrypted
false)); // require_encrypted
// portrait
configs.push_back(SupportedVideoDecoderConfig(
H264PROFILE_MIN, // profile_min
static_cast<VideoCodecProfile>(H264PROFILE_HIGH10PROFILE -
1), // profile_max
min_resolution, // coded_size_min
max_h264_resolutions.second, // coded_size_max
false, // allow_encrypted
false)); // require_encrypted
configs.push_back(SupportedVideoDecoderConfig(
static_cast<VideoCodecProfile>(H264PROFILE_HIGH10PROFILE +
1), // profile_min
H264PROFILE_MAX, // profile_max
min_resolution, // coded_size_min
max_h264_resolutions.second, // coded_size_max
false, // allow_encrypted
false)); // require_encrypted
}
// TODO(liberato): Fill this in for VP8.
if (max_vp9_profile0_resolutions.first.width()) {
// landscape
configs.push_back(SupportedVideoDecoderConfig(
VP9PROFILE_PROFILE0, // profile_min
VP9PROFILE_PROFILE0, // profile_max
min_resolution, // coded_size_min
max_vp9_profile0_resolutions.first, // coded_size_max
false, // allow_encrypted
false)); // require_encrypted
// portrait
configs.push_back(SupportedVideoDecoderConfig(
VP9PROFILE_PROFILE0, // profile_min
VP9PROFILE_PROFILE0, // profile_max
min_resolution, // coded_size_min
max_vp9_profile0_resolutions.second, // coded_size_max
false, // allow_encrypted
false)); // require_encrypted
}
if (base::FeatureList::IsEnabled(kD3D11VideoDecoderVP9Profile2)) {
if (max_vp9_profile2_resolutions.first.width()) {
// landscape
configs.push_back(SupportedVideoDecoderConfig(
VP9PROFILE_PROFILE2, // profile_min
VP9PROFILE_PROFILE2, // profile_max
min_resolution, // coded_size_min
max_vp9_profile2_resolutions.first, // coded_size_max
false, // allow_encrypted
false)); // require_encrypted
// portrait
configs.push_back(SupportedVideoDecoderConfig(
VP9PROFILE_PROFILE2, // profile_min
VP9PROFILE_PROFILE2, // profile_max
min_resolution, // coded_size_min
max_vp9_profile2_resolutions.second, // coded_size_max
false, // allow_encrypted
false)); // require_encrypted
} }
} }
......
...@@ -7,6 +7,10 @@ ...@@ -7,6 +7,10 @@
#include <algorithm> #include <algorithm>
#include <memory> #include <memory>
#if !defined(OS_WIN)
#error This file should only be built on Windows.
#endif // !defined(OS_WIN)
#include <codecapi.h> #include <codecapi.h>
#include <dxgi1_2.h> #include <dxgi1_2.h>
#include <ks.h> #include <ks.h>
...@@ -117,6 +121,13 @@ DEFINE_GUID(MF_XVP_PLAYBACK_MODE, ...@@ -117,6 +121,13 @@ DEFINE_GUID(MF_XVP_PLAYBACK_MODE,
0xcc, 0xcc,
0xe9); 0xe9);
// Defines the GUID for the Intel H264 DXVA device.
static const GUID DXVA2_Intel_ModeH264_E = {
0x604F8E68,
0x4951,
0x4c54,
{0x88, 0xFE, 0xAB, 0xD2, 0x5C, 0x15, 0xB3, 0xD6}};
static const CLSID CLSID_CAV1DecoderMFT = { static const CLSID CLSID_CAV1DecoderMFT = {
0xC843981A, 0xC843981A,
0x3359, 0x3359,
...@@ -173,7 +184,7 @@ HRESULT g_last_device_removed_reason; ...@@ -173,7 +184,7 @@ HRESULT g_last_device_removed_reason;
namespace media { namespace media {
constexpr VideoCodecProfile kSupportedProfiles[] = { static const VideoCodecProfile kSupportedProfiles[] = {
H264PROFILE_BASELINE, H264PROFILE_MAIN, H264PROFILE_HIGH, H264PROFILE_BASELINE, H264PROFILE_MAIN, H264PROFILE_HIGH,
VP8PROFILE_ANY, VP9PROFILE_PROFILE0, VP9PROFILE_PROFILE2, VP8PROFILE_ANY, VP9PROFILE_PROFILE0, VP9PROFILE_PROFILE2,
AV1PROFILE_PROFILE_MAIN, AV1PROFILE_PROFILE_HIGH, AV1PROFILE_PROFILE_PRO}; AV1PROFILE_PROFILE_MAIN, AV1PROFILE_PROFILE_HIGH, AV1PROFILE_PROFILE_PRO};
...@@ -1336,28 +1347,84 @@ DXVAVideoDecodeAccelerator::GetSupportedProfiles( ...@@ -1336,28 +1347,84 @@ DXVAVideoDecodeAccelerator::GetSupportedProfiles(
} }
} }
const auto supported_resolutions = GetSupportedD3D11VideoDecoderResolutions( // On Windows 7 the maximum resolution supported by media foundation is
gl::QueryD3D11DeviceObjectFromANGLE(), workarounds); // 1920 x 1088. We use 1088 to account for 16x16 macroblocks.
for (const auto& kv : supported_resolutions) { ResolutionPair max_h264_resolutions(gfx::Size(1920, 1088), gfx::Size());
const auto& resolution_range = kv.second;
// VP8/VP9 has no default resolutions since it may not even be supported.
ResolutionPair max_vp8_resolutions;
ResolutionPair max_vp9_profile0_resolutions;
ResolutionPair max_vp9_profile2_resolutions;
GetResolutionsForDecoders({DXVA2_ModeH264_E, DXVA2_Intel_ModeH264_E},
gl::QueryD3D11DeviceObjectFromANGLE(), workarounds,
&max_h264_resolutions, &max_vp8_resolutions,
&max_vp9_profile0_resolutions,
&max_vp9_profile2_resolutions);
for (const auto& supported_profile : kSupportedProfiles) {
const bool is_h264 = supported_profile >= H264PROFILE_MIN &&
supported_profile <= H264PROFILE_MAX;
const bool is_vp9 = supported_profile >= VP9PROFILE_MIN &&
supported_profile <= VP9PROFILE_MAX;
const bool is_vp8 = supported_profile == VP8PROFILE_ANY;
const bool is_av1 = supported_profile >= AV1PROFILE_MIN &&
supported_profile <= AV1PROFILE_MAX;
DCHECK(is_h264 || is_vp9 || is_vp8 || is_av1);
ResolutionPair max_resolutions;
if (is_h264) {
max_resolutions = max_h264_resolutions;
} else if (supported_profile == VP9PROFILE_PROFILE0) {
max_resolutions = max_vp9_profile0_resolutions;
} else if (supported_profile == VP9PROFILE_PROFILE2) {
max_resolutions = max_vp9_profile2_resolutions;
} else if (is_vp8) {
max_resolutions = max_vp8_resolutions;
} else if (is_av1) {
if (!base::FeatureList::IsEnabled(kMediaFoundationAV1Decoding))
continue;
// TODO(dalecurtis): Update GetResolutionsForDecoders() to support AV1.
SupportedProfile profile;
profile.profile = supported_profile;
profile.min_resolution = gfx::Size();
profile.max_resolution = gfx::Size(8192, 8192);
profiles.push_back(profile);
continue;
}
// Skip adding VPx profiles if it's not supported or disabled.
if ((is_vp9 || is_vp8) && max_resolutions.first.IsEmpty())
continue;
// Windows Media Foundation H.264 decoding does not support decoding videos
// with any dimension smaller than 48 pixels:
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815
//
// TODO(dalecurtis): These values are too low. We should only be using
// hardware decode for videos above ~360p, see http://crbug.com/684792.
const gfx::Size min_resolution =
is_h264 ? gfx::Size(48, 48) : gfx::Size(16, 16);
{ {
SupportedProfile profile; SupportedProfile profile;
profile.profile = kv.first; profile.profile = supported_profile;
profile.min_resolution = resolution_range.min_resolution; profile.min_resolution = min_resolution;
profile.max_resolution = resolution_range.max_landscape_resolution; profile.max_resolution = max_resolutions.first;
profiles.push_back(profile); profiles.push_back(profile);
} }
if (!resolution_range.max_portrait_resolution.IsEmpty() && const gfx::Size portrait_max_resolution = max_resolutions.second;
resolution_range.max_portrait_resolution != if (!portrait_max_resolution.IsEmpty()) {
resolution_range.max_landscape_resolution) {
SupportedProfile profile; SupportedProfile profile;
profile.profile = kv.first; profile.profile = supported_profile;
profile.min_resolution = resolution_range.min_resolution; profile.min_resolution = min_resolution;
profile.max_resolution = resolution_range.max_portrait_resolution; profile.max_resolution = portrait_max_resolution;
profiles.push_back(profile); profiles.push_back(profile);
} }
} }
return profiles; return profiles;
} }
......
...@@ -7,12 +7,18 @@ ...@@ -7,12 +7,18 @@
#include <d3d11_1.h> #include <d3d11_1.h>
#include <d3d9.h> #include <d3d9.h>
#include <dxva2api.h>
#include <initguid.h> #include <initguid.h>
#include <mfidl.h>
#include <stdint.h> #include <stdint.h>
#include <wrl/client.h> #include <wrl/client.h>
// Work around bug in this header by disabling the relevant warning for it.
// https://connect.microsoft.com/VisualStudio/feedback/details/911260/dxva2api-h-in-win8-sdk-triggers-c4201-with-w4
#pragma warning(push)
#pragma warning(disable : 4201)
#include <dxva2api.h>
#pragma warning(pop)
#include <mfidl.h>
#include <list> #include <list>
#include <map> #include <map>
#include <memory> #include <memory>
......
...@@ -9,14 +9,16 @@ ...@@ -9,14 +9,16 @@
#include <memory> #include <memory>
#include <utility> #include <utility>
#include <d3d9.h>
#include <dxva2api.h>
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "base/win/windows_version.h" #include "base/win/windows_version.h"
#include "build/build_config.h"
#include "gpu/config/gpu_driver_bug_workarounds.h"
#include "media/base/media_switches.h" #include "media/base/media_switches.h"
#include "media/gpu/windows/av1_guids.h"
#if !defined(OS_WIN)
#error This file should only be built on Windows.
#endif // !defined(OS_WIN)
namespace { namespace {
...@@ -24,7 +26,7 @@ namespace { ...@@ -24,7 +26,7 @@ namespace {
// or earlier, and don't handle resolutions higher than 1920 x 1088 well. // or earlier, and don't handle resolutions higher than 1920 x 1088 well.
// //
// NOTE: This list must be kept in sorted order. // NOTE: This list must be kept in sorted order.
constexpr uint16_t kLegacyAmdGpuList[] = { static const uint16_t kLegacyAmdGpuList[] = {
0x130f, 0x6700, 0x6701, 0x6702, 0x6703, 0x6704, 0x6705, 0x6706, 0x6707, 0x130f, 0x6700, 0x6701, 0x6702, 0x6703, 0x6704, 0x6705, 0x6706, 0x6707,
0x6708, 0x6709, 0x6718, 0x6719, 0x671c, 0x671d, 0x671f, 0x6720, 0x6721, 0x6708, 0x6709, 0x6718, 0x6719, 0x671c, 0x671d, 0x671f, 0x6720, 0x6721,
0x6722, 0x6723, 0x6724, 0x6725, 0x6726, 0x6727, 0x6728, 0x6729, 0x6738, 0x6722, 0x6723, 0x6724, 0x6725, 0x6726, 0x6727, 0x6728, 0x6729, 0x6738,
...@@ -65,18 +67,14 @@ constexpr uint16_t kLegacyAmdGpuList[] = { ...@@ -65,18 +67,14 @@ constexpr uint16_t kLegacyAmdGpuList[] = {
// 1920 x 1088 are supported. Updated based on crash reports. // 1920 x 1088 are supported. Updated based on crash reports.
// //
// NOTE: This list must be kept in sorted order. // NOTE: This list must be kept in sorted order.
constexpr uint16_t kLegacyIntelGpuList[] = { static const uint16_t kLegacyIntelGpuList[] = {
0x102, 0x106, 0x116, 0x126, 0x152, 0x156, 0x166, 0x102, 0x106, 0x116, 0x126, 0x152, 0x156, 0x166,
0x402, 0x406, 0x416, 0x41e, 0xa06, 0xa16, 0xf31, 0x402, 0x406, 0x416, 0x41e, 0xa06, 0xa16, 0xf31,
}; };
// Windows Media Foundation H.264 decoding does not support decoding videos } // namespace
// with any dimension smaller than 48 pixels:
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815 namespace media {
//
// TODO(dalecurtis): These values are too low. We should only be using
// hardware decode for videos above ~360p, see http://crbug.com/684792.
constexpr gfx::Size kMinResolution(64, 64);
// Certain AMD GPU drivers like R600, R700, Evergreen and Cayman and some second // Certain AMD GPU drivers like R600, R700, Evergreen and Cayman and some second
// generation Intel GPU drivers crash if we create a video device with a // generation Intel GPU drivers crash if we create a video device with a
...@@ -159,12 +157,32 @@ bool IsResolutionSupportedForDevice(const gfx::Size& resolution_to_test, ...@@ -159,12 +157,32 @@ bool IsResolutionSupportedForDevice(const gfx::Size& resolution_to_test,
config_count > 0; config_count > 0;
} }
media::SupportedResolutionRange GetResolutionsForGUID( // Returns a tuple of (LandscapeMax, PortraitMax). If landscape maximum can not
// be computed, the value of |default_max| is returned for the landscape maximum
// and a zero size value is returned for portrait max (erring conservatively).
ResolutionPair GetMaxResolutionsForGUIDs(
const gfx::Size& default_max,
ID3D11VideoDevice* video_device, ID3D11VideoDevice* video_device,
const GUID& decoder_guid, const std::vector<GUID>& valid_guids,
const std::vector<gfx::Size>& resolutions_to_test, const std::vector<gfx::Size>& resolutions_to_test,
DXGI_FORMAT format = DXGI_FORMAT_NV12) { DXGI_FORMAT format) {
media::SupportedResolutionRange result; ResolutionPair result(default_max, gfx::Size());
// Enumerate supported video profiles and look for the profile.
GUID decoder_guid = GUID_NULL;
UINT profile_count = video_device->GetVideoDecoderProfileCount();
for (UINT profile_idx = 0; profile_idx < profile_count; profile_idx++) {
GUID profile_id = {};
if (SUCCEEDED(
video_device->GetVideoDecoderProfile(profile_idx, &profile_id)) &&
std::find(valid_guids.begin(), valid_guids.end(), profile_id) !=
valid_guids.end()) {
decoder_guid = profile_id;
break;
}
}
if (decoder_guid == GUID_NULL)
return result;
// Verify input is in ascending order by height. // Verify input is in ascending order by height.
DCHECK(std::is_sorted(resolutions_to_test.begin(), resolutions_to_test.end(), DCHECK(std::is_sorted(resolutions_to_test.begin(), resolutions_to_test.end(),
...@@ -177,54 +195,32 @@ media::SupportedResolutionRange GetResolutionsForGUID( ...@@ -177,54 +195,32 @@ media::SupportedResolutionRange GetResolutionsForGUID(
format)) { format)) {
break; break;
} }
result.max_landscape_resolution = res; result.first = res;
} }
// The max supported portrait resolution should be just be a w/h flip of the // The max supported portrait resolution should be just be a w/h flip of the
// max supported landscape resolution. // max supported landscape resolution.
const gfx::Size flipped(result.max_landscape_resolution.height(), gfx::Size flipped(result.first.height(), result.first.width());
result.max_landscape_resolution.width()); if (IsResolutionSupportedForDevice(flipped, decoder_guid, video_device,
if (flipped == result.max_landscape_resolution ||
IsResolutionSupportedForDevice(flipped, decoder_guid, video_device,
format)) { format)) {
result.max_portrait_resolution = flipped; result.second = flipped;
} }
if (!result.max_landscape_resolution.IsEmpty())
result.min_resolution = kMinResolution;
return result; return result;
} }
} // namespace // TODO(tmathmeyer) refactor this so that we don'ty call
// GetMaxResolutionsForGUIDS so many times.
namespace media { void GetResolutionsForDecoders(std::vector<GUID> h264_guids,
ComD3D11Device device,
SupportedResolutionRangeMap GetSupportedD3D11VideoDecoderResolutions( const gpu::GpuDriverBugWorkarounds& workarounds,
ComD3D11Device device, ResolutionPair* h264_resolutions,
const gpu::GpuDriverBugWorkarounds& workarounds) { ResolutionPair* vp8_resolutions,
TRACE_EVENT0("gpu,startup", "GetSupportedD3D11VideoDecoderResolutions"); ResolutionPair* vp9_0_resolutions,
SupportedResolutionRangeMap supported_resolutions; ResolutionPair* vp9_2_resolutions) {
TRACE_EVENT0("gpu,startup", "GetResolutionsForDecoders");
// We always insert support for H.264 regardless of the tests below. It's old
// enough to be ubiquitous.
//
// On Windows 7 the maximum resolution supported by media foundation is
// 1920 x 1088. We use 1088 to account for 16x16 macro-blocks.
constexpr gfx::Size kDefaultMaxH264Resolution(1920, 1088);
SupportedResolutionRange h264_profile;
h264_profile.min_resolution = kMinResolution;
h264_profile.max_landscape_resolution = kDefaultMaxH264Resolution;
// We don't have a way to map DXVA support to specific H.264 profiles, so just
// mark all the common ones with the same level of support.
constexpr VideoCodecProfile kSupportedH264Profiles[] = {
H264PROFILE_BASELINE, H264PROFILE_MAIN, H264PROFILE_HIGH};
for (const auto profile : kSupportedH264Profiles)
supported_resolutions[profile] = h264_profile;
if (base::win::GetVersion() <= base::win::Version::WIN7) if (base::win::GetVersion() <= base::win::Version::WIN7)
return supported_resolutions; return;
// To detect if a driver supports the desired resolutions, we try and create // 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 // a DXVA decoder instance for that resolution and profile. If that succeeds
...@@ -232,97 +228,43 @@ SupportedResolutionRangeMap GetSupportedD3D11VideoDecoderResolutions( ...@@ -232,97 +228,43 @@ SupportedResolutionRangeMap GetSupportedD3D11VideoDecoderResolutions(
// Legacy AMD drivers with UVD3 or earlier and some Intel GPU's crash while // Legacy AMD drivers with UVD3 or earlier and some Intel GPU's crash while
// creating surfaces larger than 1920 x 1088. // creating surfaces larger than 1920 x 1088.
if (!device || IsLegacyGPU(device.Get())) if (!device || IsLegacyGPU(device.Get()))
return supported_resolutions; return;
ComD3D11VideoDevice video_device; ComD3D11VideoDevice video_device;
if (FAILED(device.As(&video_device))) if (FAILED(device.As(&video_device)))
return supported_resolutions; return;
const std::vector<gfx::Size> kModernResolutions = { *h264_resolutions = GetMaxResolutionsForGUIDs(
gfx::Size(4096, 2160), gfx::Size(4096, 2304), gfx::Size(7680, 4320), h264_resolutions->first, video_device.Get(), h264_guids,
gfx::Size(8192, 4320), gfx::Size(8192, 8192)}; {gfx::Size(2560, 1440), gfx::Size(3840, 2160), gfx::Size(4096, 2160),
gfx::Size(4096, 2304)});
const bool should_test_for_av1_support = if (workarounds.disable_accelerated_vpx_decode)
base::FeatureList::IsEnabled(kMediaFoundationAV1Decoding); return;
// Enumerate supported video profiles and look for the known profile for each if (base::FeatureList::IsEnabled(kMediaFoundationVP8Decoding)) {
// codec. We first look through the the decoder profiles so we don't run N *vp8_resolutions = GetMaxResolutionsForGUIDs(
// resolution tests for a profile that's unsupported. vp8_resolutions->first, video_device.Get(),
UINT profile_count = video_device->GetVideoDecoderProfileCount(); {D3D11_DECODER_PROFILE_VP8_VLD},
for (UINT i = 0; i < profile_count; i++) { {gfx::Size(4096, 2160), gfx::Size(4096, 2304)});
GUID profile_id;
if (FAILED(video_device->GetVideoDecoderProfile(i, &profile_id)))
continue;
if (profile_id == D3D11_DECODER_PROFILE_H264_VLD_NOFGT) {
const auto result = GetResolutionsForGUID(
video_device.Get(), profile_id,
{gfx::Size(2560, 1440), gfx::Size(3840, 2160), gfx::Size(4096, 2160),
gfx::Size(4096, 2304), gfx::Size(4096, 4096)});
// Unlike the other codecs, H.264 support is assumed up to 1080p, even if
// our initial queries fail. If they fail, we use the defaults set above.
if (!result.max_landscape_resolution.IsEmpty()) {
for (const auto profile : kSupportedH264Profiles)
supported_resolutions[profile] = result;
}
continue;
}
// Note: Each bit depth of AV1 uses a different DXGI_FORMAT, here we only
// test for the 8-bit one (NV12).
if (should_test_for_av1_support) {
if (profile_id == DXVA_ModeAV1_VLD_Profile0) {
supported_resolutions[AV1PROFILE_PROFILE_MAIN] = GetResolutionsForGUID(
video_device.Get(), profile_id, kModernResolutions);
continue;
}
if (profile_id == DXVA_ModeAV1_VLD_Profile1) {
supported_resolutions[AV1PROFILE_PROFILE_HIGH] = GetResolutionsForGUID(
video_device.Get(), profile_id, kModernResolutions);
continue;
}
if (profile_id == DXVA_ModeAV1_VLD_Profile2) {
// TODO(dalecurtis): 12-bit profile 2 support is complicated. Ideally,
// we should test DXVA_ModeAV1_VLD_12bit_Profile2 and
// DXVA_ModeAV1_VLD_12bit_Profile2_420 when the bit depth of the content
// is 12-bit. However we don't know the bit depth or pixel format until
// too late. In these cases we'll end up initializing the decoder and
// failing on the first decode (which will trigger software fallback).
supported_resolutions[AV1PROFILE_PROFILE_PRO] = GetResolutionsForGUID(
video_device.Get(), profile_id, kModernResolutions);
continue;
}
}
if (workarounds.disable_accelerated_vpx_decode)
continue;
if (profile_id == D3D11_DECODER_PROFILE_VP8_VLD &&
base::FeatureList::IsEnabled(kMediaFoundationVP8Decoding)) {
supported_resolutions[VP8PROFILE_ANY] =
GetResolutionsForGUID(video_device.Get(), profile_id,
{gfx::Size(4096, 2160), gfx::Size(4096, 2304),
gfx::Size(4096, 4096)});
continue;
}
if (profile_id == D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0) {
supported_resolutions[VP9PROFILE_PROFILE0] = GetResolutionsForGUID(
video_device.Get(), profile_id, kModernResolutions);
continue;
}
// RS3 has issues with VP9.2 decoding. See https://crbug.com/937108.
if (profile_id == D3D11_DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2 &&
base::win::GetVersion() != base::win::Version::WIN10_RS3) {
supported_resolutions[VP9PROFILE_PROFILE2] = GetResolutionsForGUID(
video_device.Get(), profile_id, kModernResolutions, DXGI_FORMAT_P010);
continue;
}
} }
return supported_resolutions; *vp9_0_resolutions = GetMaxResolutionsForGUIDs(
vp9_0_resolutions->first, video_device.Get(),
{D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0},
{gfx::Size(4096, 2160), gfx::Size(4096, 2304), gfx::Size(7680, 4320),
gfx::Size(8192, 4320), gfx::Size(8192, 8192)});
// RS3 has issues with VP9.2 decoding. See https://crbug.com/937108.
if (base::win::GetVersion() == base::win::Version::WIN10_RS3)
return;
*vp9_2_resolutions = GetMaxResolutionsForGUIDs(
vp9_2_resolutions->first, video_device.Get(),
{D3D11_DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2},
{gfx::Size(4096, 2160), gfx::Size(4096, 2304), gfx::Size(7680, 4320),
gfx::Size(8192, 4320), gfx::Size(8192, 8192)},
DXGI_FORMAT_P010);
} }
} // namespace media } // namespace media
...@@ -5,35 +5,47 @@ ...@@ -5,35 +5,47 @@
#ifndef MEDIA_GPU_WINDOWS_SUPPORTED_PROFILE_HELPERS_H_ #ifndef MEDIA_GPU_WINDOWS_SUPPORTED_PROFILE_HELPERS_H_
#define MEDIA_GPU_WINDOWS_SUPPORTED_PROFILE_HELPERS_H_ #define MEDIA_GPU_WINDOWS_SUPPORTED_PROFILE_HELPERS_H_
#include "base/containers/flat_map.h" #include <d3d11_1.h>
#include <wrl/client.h>
#include <memory>
#include <utility>
#include <vector>
#include "gpu/config/gpu_driver_bug_workarounds.h" #include "gpu/config/gpu_driver_bug_workarounds.h"
#include "media/base/video_codecs.h"
#include "media/gpu/media_gpu_export.h" #include "media/gpu/media_gpu_export.h"
#include "media/gpu/windows/d3d11_com_defs.h" #include "media/gpu/windows/d3d11_com_defs.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/rect.h"
namespace media { namespace media {
struct SupportedResolutionRange { using ResolutionPair = std::pair<gfx::Size, gfx::Size>;
gfx::Size min_resolution;
gfx::Size max_landscape_resolution; bool IsLegacyGPU(ID3D11Device* device);
gfx::Size max_portrait_resolution;
}; // Returns true if a ID3D11VideoDecoder can be created for |resolution_to_test|
// on the given |video_device|.
using SupportedResolutionRangeMap = bool IsResolutionSupportedForDevice(const gfx::Size& resolution_to_test,
base::flat_map<VideoCodecProfile, SupportedResolutionRange>; const GUID& decoder_guid,
ID3D11VideoDevice* video_device,
// Enumerates the extent of hardware decoding support for H.264, VP8, VP9, and DXGI_FORMAT format);
// AV1. If a codec is supported, its minimum and maximum supported resolutions
// are returned under the appropriate VideoCodecProfile entry. ResolutionPair GetMaxResolutionsForGUIDs(
// const gfx::Size& default_max,
// Notes: ID3D11VideoDevice* video_device,
// - VP8 and AV1 are only tested if their base::Feature entries are enabled. const std::vector<GUID>& valid_guids,
// - Only baseline, main, and high H.264 profiles are supported. const std::vector<gfx::Size>& resolutions_to_test,
DXGI_FORMAT format = DXGI_FORMAT_NV12);
// TODO(dalecurtis): This function should be changed to use return values.
MEDIA_GPU_EXPORT MEDIA_GPU_EXPORT
SupportedResolutionRangeMap GetSupportedD3D11VideoDecoderResolutions( void GetResolutionsForDecoders(std::vector<GUID> h264_guids,
ComD3D11Device device, ComD3D11Device device,
const gpu::GpuDriverBugWorkarounds& workarounds); const gpu::GpuDriverBugWorkarounds& workarounds,
ResolutionPair* h264_resolutions,
ResolutionPair* vp8_resolutions,
ResolutionPair* vp9_0_resolutions,
ResolutionPair* vp9_2_resolutions);
} // namespace media } // namespace media
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "media/base/media_switches.h" #include "media/base/media_switches.h"
#include "media/base/test_helpers.h" #include "media/base/test_helpers.h"
#include "media/base/win/d3d11_mocks.h" #include "media/base/win/d3d11_mocks.h"
#include "media/gpu/windows/av1_guids.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
using ::testing::_; using ::testing::_;
...@@ -32,28 +31,25 @@ using ::testing::WithArgs; ...@@ -32,28 +31,25 @@ using ::testing::WithArgs;
return; \ return; \
} while (0) } while (0)
namespace { HRESULT SetIfSizeLessThan(D3D11_VIDEO_DECODER_DESC* desc, UINT* count) {
*count = 1;
using PciId = std::pair<uint16_t, uint16_t>; return S_OK;
constexpr PciId kLegacyIntelGpu = {0x8086, 0x102}; }
constexpr PciId kRecentIntelGpu = {0x8086, 0x100};
constexpr PciId kLegacyAmdGpu = {0x1022, 0x130f};
constexpr PciId kRecentAmdGpu = {0x1022, 0x130e};
constexpr gfx::Size kMinResolution(64, 64);
constexpr gfx::Size kFullHd(1920, 1088);
constexpr gfx::Size kSquare4k(4096, 4096);
constexpr gfx::Size kSquare8k(8192, 8192);
} // namespace
namespace media { namespace media {
constexpr VideoCodecProfile kSupportedH264Profiles[] = {
H264PROFILE_BASELINE, H264PROFILE_MAIN, H264PROFILE_HIGH};
class SupportedResolutionResolverTest : public ::testing::Test { class SupportedResolutionResolverTest : public ::testing::Test {
public: 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 { void SetUp() override {
gpu_workarounds_.disable_dxgi_zero_copy_video = false; gpu_workarounds_.disable_dxgi_zero_copy_video = false;
mock_d3d11_device_ = CreateD3D11Mock<NiceMock<D3D11DeviceMock>>(); mock_d3d11_device_ = CreateD3D11Mock<NiceMock<D3D11DeviceMock>>();
...@@ -72,11 +68,11 @@ class SupportedResolutionResolverTest : public ::testing::Test { ...@@ -72,11 +68,11 @@ class SupportedResolutionResolverTest : public ::testing::Test {
ON_CALL(*mock_dxgi_device_.Get(), GetAdapter(_)) ON_CALL(*mock_dxgi_device_.Get(), GetAdapter(_))
.WillByDefault(SetComPointeeAndReturnOk<0>(mock_dxgi_adapter_.Get())); .WillByDefault(SetComPointeeAndReturnOk<0>(mock_dxgi_adapter_.Get()));
SetGpuProfile(kRecentIntelGpu); SetGPUProfile(RecentIntelGPU);
SetMaxResolution(D3D11_DECODER_PROFILE_H264_VLD_NOFGT, kSquare4k); SetMaxResolutionForGUID(D3D11_DECODER_PROFILE_H264_VLD_NOFGT, {4096, 4096});
} }
void SetMaxResolution(const GUID& g, const gfx::Size& max_res) { void SetMaxResolutionForGUID(const GUID& g, const gfx::Size& max_res) {
max_size_for_guids_[g] = max_res; max_size_for_guids_[g] = max_res;
ON_CALL(*mock_d3d11_video_device_.Get(), GetVideoDecoderConfigCount(_, _)) ON_CALL(*mock_d3d11_video_device_.Get(), GetVideoDecoderConfigCount(_, _))
.WillByDefault( .WillByDefault(
...@@ -114,7 +110,7 @@ class SupportedResolutionResolverTest : public ::testing::Test { ...@@ -114,7 +110,7 @@ class SupportedResolutionResolverTest : public ::testing::Test {
}))); })));
} }
void SetGpuProfile(std::pair<uint16_t, uint16_t> vendor_and_gpu) { 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_.DeviceId = static_cast<UINT>(vendor_and_gpu.second);
mock_adapter_desc_.VendorId = static_cast<UINT>(vendor_and_gpu.first); mock_adapter_desc_.VendorId = static_cast<UINT>(vendor_and_gpu.first);
...@@ -123,39 +119,6 @@ class SupportedResolutionResolverTest : public ::testing::Test { ...@@ -123,39 +119,6 @@ class SupportedResolutionResolverTest : public ::testing::Test {
DoAll(SetArgPointee<0>(mock_adapter_desc_), Return(S_OK))); DoAll(SetArgPointee<0>(mock_adapter_desc_), Return(S_OK)));
} }
void AssertDefaultSupport(
const SupportedResolutionRangeMap& supported_resolutions,
size_t expected_size = 3u) {
ASSERT_EQ(expected_size, supported_resolutions.size());
for (const auto profile : kSupportedH264Profiles) {
auto it = supported_resolutions.find(profile);
ASSERT_NE(it, supported_resolutions.end());
EXPECT_EQ(kMinResolution, it->second.min_resolution);
EXPECT_EQ(kFullHd, it->second.max_landscape_resolution);
EXPECT_EQ(gfx::Size(), it->second.max_portrait_resolution);
}
}
void TestDecoderSupport(const GUID& decoder,
VideoCodecProfile profile,
const gfx::Size& max_res = kSquare4k,
const gfx::Size& max_landscape_res = kSquare4k,
const gfx::Size& max_portrait_res = kSquare4k) {
EnableDecoders({decoder});
SetMaxResolution(decoder, max_res);
const auto supported_resolutions = GetSupportedD3D11VideoDecoderResolutions(
mock_d3d11_device_, gpu_workarounds_);
AssertDefaultSupport(supported_resolutions,
base::size(kSupportedH264Profiles) + 1);
auto it = supported_resolutions.find(profile);
ASSERT_NE(it, supported_resolutions.end());
EXPECT_EQ(kMinResolution, it->second.min_resolution);
EXPECT_EQ(max_landscape_res, it->second.max_landscape_resolution);
EXPECT_EQ(max_portrait_res, it->second.max_portrait_resolution);
}
Microsoft::WRL::ComPtr<D3D11DeviceMock> mock_d3d11_device_; Microsoft::WRL::ComPtr<D3D11DeviceMock> mock_d3d11_device_;
Microsoft::WRL::ComPtr<DXGIAdapterMock> mock_dxgi_adapter_; Microsoft::WRL::ComPtr<DXGIAdapterMock> mock_dxgi_adapter_;
Microsoft::WRL::ComPtr<DXGIDeviceMock> mock_dxgi_device_; Microsoft::WRL::ComPtr<DXGIDeviceMock> mock_dxgi_device_;
...@@ -168,125 +131,144 @@ class SupportedResolutionResolverTest : public ::testing::Test { ...@@ -168,125 +131,144 @@ class SupportedResolutionResolverTest : public ::testing::Test {
return memcmp(&a, &b, sizeof(GUID)) < 0; return memcmp(&a, &b, sizeof(GUID)) < 0;
} }
}; };
base::flat_map<GUID, gfx::Size, GUIDComparison> max_size_for_guids_; std::map<GUID, gfx::Size, GUIDComparison> max_size_for_guids_;
}; };
TEST_F(SupportedResolutionResolverTest, HasH264SupportByDefault) { TEST_F(SupportedResolutionResolverTest, NoDeviceAllDefault) {
DONT_RUN_ON_WIN_7(); DONT_RUN_ON_WIN_7();
AssertDefaultSupport(
GetSupportedD3D11VideoDecoderResolutions(nullptr, gpu_workarounds_));
SetGpuProfile(kLegacyIntelGpu); ResolutionPair h264_res_expected = {{1, 2}, {3, 4}};
AssertDefaultSupport(GetSupportedD3D11VideoDecoderResolutions( ResolutionPair h264_res = {{1, 2}, {3, 4}};
mock_d3d11_device_, gpu_workarounds_)); ResolutionPair vp8_res;
ResolutionPair vp9_0_res;
SetGpuProfile(kLegacyAmdGpu); ResolutionPair vp9_2_res;
AssertDefaultSupport(GetSupportedD3D11VideoDecoderResolutions( GetResolutionsForDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT}, nullptr,
mock_d3d11_device_, gpu_workarounds_)); gpu_workarounds_, &h264_res, &vp8_res, &vp9_0_res,
&vp9_2_res);
ASSERT_EQ(h264_res, h264_res_expected);
ASSERT_EQ(vp8_res, zero);
ASSERT_EQ(vp9_0_res, zero);
ASSERT_EQ(vp9_0_res, zero);
} }
TEST_F(SupportedResolutionResolverTest, WorkaroundsDisableVpx) { TEST_F(SupportedResolutionResolverTest, LegacyGPUAllDefault) {
DONT_RUN_ON_WIN_7(); DONT_RUN_ON_WIN_7();
gpu_workarounds_.disable_accelerated_vpx_decode = true; SetGPUProfile(LegacyIntelGPU);
EnableDecoders({D3D11_DECODER_PROFILE_VP8_VLD,
D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0, ResolutionPair h264_res_expected = {{1, 2}, {3, 4}};
D3D11_DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2}); ResolutionPair h264_res = {{1, 2}, {3, 4}};
ResolutionPair vp8_res;
AssertDefaultSupport(GetSupportedD3D11VideoDecoderResolutions( ResolutionPair vp9_0_res;
mock_d3d11_device_, gpu_workarounds_)); ResolutionPair vp9_2_res;
GetResolutionsForDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT},
mock_d3d11_device_, gpu_workarounds_, &h264_res,
&vp8_res, &vp9_0_res, &vp9_2_res);
ASSERT_EQ(h264_res, h264_res_expected);
ASSERT_EQ(vp8_res, zero);
ASSERT_EQ(vp9_2_res, zero);
ASSERT_EQ(vp9_0_res, zero);
} }
TEST_F(SupportedResolutionResolverTest, H264Supports4k) { TEST_F(SupportedResolutionResolverTest, WorkaroundsDisableVpx) {
DONT_RUN_ON_WIN_7(); DONT_RUN_ON_WIN_7();
gpu_workarounds_.disable_dxgi_zero_copy_video = true;
EnableDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT}); EnableDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT});
const auto supported_resolutions = GetSupportedD3D11VideoDecoderResolutions(
mock_d3d11_device_, gpu_workarounds_); ResolutionPair h264_res;
ResolutionPair vp8_res;
ASSERT_EQ(3u, supported_resolutions.size()); ResolutionPair vp9_0_res;
for (const auto profile : kSupportedH264Profiles) { ResolutionPair vp9_2_res;
auto it = supported_resolutions.find(profile); GetResolutionsForDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT},
ASSERT_NE(it, supported_resolutions.end()); mock_d3d11_device_, gpu_workarounds_, &h264_res,
EXPECT_EQ(kMinResolution, it->second.min_resolution); &vp8_res, &vp9_0_res, &vp9_2_res);
EXPECT_EQ(kSquare4k, it->second.max_landscape_resolution);
EXPECT_EQ(kSquare4k, it->second.max_portrait_resolution); ASSERT_EQ(h264_res, tall4k);
}
ASSERT_EQ(vp8_res, zero);
ASSERT_EQ(vp9_0_res, zero);
ASSERT_EQ(vp9_2_res, zero);
} }
TEST_F(SupportedResolutionResolverTest, VP8Supports4k) { TEST_F(SupportedResolutionResolverTest, VP8_Supports4k) {
DONT_RUN_ON_WIN_7(); DONT_RUN_ON_WIN_7();
base::test::ScopedFeatureList scoped_feature_list; base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(kMediaFoundationVP8Decoding); scoped_feature_list.InitAndEnableFeature(kMediaFoundationVP8Decoding);
TestDecoderSupport(D3D11_DECODER_PROFILE_VP8_VLD, VP8PROFILE_ANY);
}
TEST_F(SupportedResolutionResolverTest, VP9Profile0Supports8k) { EnableDecoders(
DONT_RUN_ON_WIN_7(); {D3D11_DECODER_PROFILE_H264_VLD_NOFGT, D3D11_DECODER_PROFILE_VP8_VLD});
TestDecoderSupport(D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0, SetMaxResolutionForGUID(D3D11_DECODER_PROFILE_VP8_VLD, {4096, 4096});
VP9PROFILE_PROFILE0, kSquare8k, kSquare8k, kSquare8k);
}
TEST_F(SupportedResolutionResolverTest, VP9Profile2Supports8k) { ResolutionPair h264_res;
DONT_RUN_ON_WIN_7(); ResolutionPair vp8_res;
TestDecoderSupport(D3D11_DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2, ResolutionPair vp9_0_res;
VP9PROFILE_PROFILE2, kSquare8k, kSquare8k, kSquare8k); ResolutionPair vp9_2_res;
GetResolutionsForDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT},
mock_d3d11_device_, gpu_workarounds_, &h264_res,
&vp8_res, &vp9_0_res, &vp9_2_res);
ASSERT_EQ(h264_res, tall4k);
ASSERT_EQ(vp8_res, tall4k);
ASSERT_EQ(vp9_0_res, zero);
ASSERT_EQ(vp9_2_res, zero);
} }
TEST_F(SupportedResolutionResolverTest, MultipleCodecs) { TEST_F(SupportedResolutionResolverTest, VP9_0Supports8k) {
SetGpuProfile(kRecentAmdGpu); DONT_RUN_ON_WIN_7();
// H.264 and VP9.0 are the most common supported codecs.
EnableDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT, EnableDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT,
D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0}); D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0});
SetMaxResolution(D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0, kSquare8k); SetMaxResolutionForGUID(D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0, {8192, 8192});
const auto supported_resolutions = GetSupportedD3D11VideoDecoderResolutions(
mock_d3d11_device_, gpu_workarounds_);
ASSERT_EQ(base::size(kSupportedH264Profiles) + 1,
supported_resolutions.size());
for (const auto profile : kSupportedH264Profiles) {
auto it = supported_resolutions.find(profile);
ASSERT_NE(it, supported_resolutions.end());
EXPECT_EQ(kMinResolution, it->second.min_resolution);
EXPECT_EQ(kSquare4k, it->second.max_landscape_resolution);
EXPECT_EQ(kSquare4k, it->second.max_portrait_resolution);
}
auto it = supported_resolutions.find(VP9PROFILE_PROFILE0); ResolutionPair h264_res;
ASSERT_NE(it, supported_resolutions.end()); ResolutionPair vp8_res;
EXPECT_EQ(kMinResolution, it->second.min_resolution); ResolutionPair vp9_0_res;
EXPECT_EQ(kSquare8k, it->second.max_landscape_resolution); ResolutionPair vp9_2_res;
EXPECT_EQ(kSquare8k, it->second.max_portrait_resolution); GetResolutionsForDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT},
} mock_d3d11_device_, gpu_workarounds_, &h264_res,
&vp8_res, &vp9_0_res, &vp9_2_res);
TEST_F(SupportedResolutionResolverTest, AV1ProfileMainSupports8k) { ASSERT_EQ(h264_res, tall4k);
DONT_RUN_ON_WIN_7();
base::test::ScopedFeatureList scoped_feature_list; ASSERT_EQ(vp8_res, zero);
scoped_feature_list.InitAndEnableFeature(kMediaFoundationAV1Decoding);
TestDecoderSupport(DXVA_ModeAV1_VLD_Profile0, AV1PROFILE_PROFILE_MAIN,
kSquare8k, kSquare8k, kSquare8k);
}
TEST_F(SupportedResolutionResolverTest, AV1ProfileHighSupports8k) { ASSERT_EQ(vp9_0_res, eightKsquare);
DONT_RUN_ON_WIN_7();
base::test::ScopedFeatureList scoped_feature_list; ASSERT_EQ(vp9_2_res, zero);
scoped_feature_list.InitAndEnableFeature(kMediaFoundationAV1Decoding);
TestDecoderSupport(DXVA_ModeAV1_VLD_Profile1, AV1PROFILE_PROFILE_HIGH,
kSquare8k, kSquare8k, kSquare8k);
} }
TEST_F(SupportedResolutionResolverTest, AV1ProfileProSupports8k) { TEST_F(SupportedResolutionResolverTest, BothVP9ProfilesSupported) {
DONT_RUN_ON_WIN_7(); DONT_RUN_ON_WIN_7();
base::test::ScopedFeatureList scoped_feature_list; EnableDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT,
scoped_feature_list.InitAndEnableFeature(kMediaFoundationAV1Decoding); D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0,
TestDecoderSupport(DXVA_ModeAV1_VLD_Profile2, AV1PROFILE_PROFILE_PRO, D3D11_DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2});
kSquare8k, kSquare8k, kSquare8k); SetMaxResolutionForGUID(D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0, {8192, 8192});
SetMaxResolutionForGUID(D3D11_DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2,
{8192, 8192});
ResolutionPair h264_res;
ResolutionPair vp8_res;
ResolutionPair vp9_0_res;
ResolutionPair vp9_2_res;
GetResolutionsForDecoders({D3D11_DECODER_PROFILE_H264_VLD_NOFGT},
mock_d3d11_device_, gpu_workarounds_, &h264_res,
&vp8_res, &vp9_0_res, &vp9_2_res);
ASSERT_EQ(h264_res, tall4k);
ASSERT_EQ(vp8_res, zero);
ASSERT_EQ(vp9_0_res, eightKsquare);
ASSERT_EQ(vp9_2_res, eightKsquare);
} }
} // namespace media } // 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