vaapi_unittest.cc 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. // This has to be included first.
  5. // See http://code.google.com/p/googletest/issues/detail?id=371
  6. #include "testing/gtest/include/gtest/gtest.h"
  7. #include <drm_fourcc.h>
  8. #include <gbm.h>
  9. #include <unistd.h>
  10. #include <map>
  11. #include <vector>
  12. #include <va/va.h>
  13. #include <va/va_drmcommon.h>
  14. #include <va/va_str.h>
  15. #include <xf86drm.h>
  16. #include "base/bits.h"
  17. #include "base/callback_helpers.h"
  18. #include "base/containers/contains.h"
  19. #include "base/cpu.h"
  20. #include "base/files/file.h"
  21. #include "base/files/file_util.h"
  22. #include "base/files/scoped_file.h"
  23. #include "base/logging.h"
  24. #include "base/process/launch.h"
  25. #include "base/strings/pattern.h"
  26. #include "base/strings/string_split.h"
  27. #include "base/strings/string_util.h"
  28. #include "base/strings/stringprintf.h"
  29. #include "base/test/launcher/unit_test_launcher.h"
  30. #include "base/test/scoped_feature_list.h"
  31. #include "base/test/test_suite.h"
  32. #include "build/chromeos_buildflags.h"
  33. #include "media/base/media_switches.h"
  34. #include "media/gpu/vaapi/vaapi_wrapper.h"
  35. #include "media/media_buildflags.h"
  36. #include "testing/gmock/include/gmock/gmock.h"
  37. #include "third_party/abseil-cpp/absl/types/optional.h"
  38. #include "ui/gfx/linux/gbm_defines.h"
  39. #if defined(USE_OZONE) && BUILDFLAG(IS_LINUX)
  40. // GN doesn't understand conditional includes, so we need nogncheck here.
  41. // See crbug.com/1125897.
  42. #include "ui/ozone/public/ozone_platform.h" // nogncheck
  43. #endif
  44. namespace media {
  45. namespace {
  46. absl::optional<VAProfile> ConvertToVAProfile(VideoCodecProfile profile) {
  47. // A map between VideoCodecProfile and VAProfile.
  48. const std::map<VideoCodecProfile, VAProfile> kProfileMap = {
  49. // VAProfileH264Baseline is deprecated in <va/va.h> from libva 2.0.0.
  50. {H264PROFILE_BASELINE, VAProfileH264ConstrainedBaseline},
  51. {H264PROFILE_MAIN, VAProfileH264Main},
  52. {H264PROFILE_HIGH, VAProfileH264High},
  53. {VP8PROFILE_ANY, VAProfileVP8Version0_3},
  54. {VP9PROFILE_PROFILE0, VAProfileVP9Profile0},
  55. {VP9PROFILE_PROFILE2, VAProfileVP9Profile2},
  56. {AV1PROFILE_PROFILE_MAIN, VAProfileAV1Profile0},
  57. #if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
  58. {HEVCPROFILE_MAIN, VAProfileHEVCMain},
  59. {HEVCPROFILE_MAIN_STILL_PICTURE, VAProfileHEVCMain},
  60. {HEVCPROFILE_MAIN10, VAProfileHEVCMain10},
  61. #endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
  62. };
  63. auto it = kProfileMap.find(profile);
  64. return it != kProfileMap.end() ? absl::make_optional<VAProfile>(it->second)
  65. : absl::nullopt;
  66. }
  67. // Converts the given string to VAProfile
  68. absl::optional<VAProfile> StringToVAProfile(const std::string& va_profile) {
  69. const std::map<std::string, VAProfile> kStringToVAProfile = {
  70. {"VAProfileNone", VAProfileNone},
  71. {"VAProfileH264ConstrainedBaseline", VAProfileH264ConstrainedBaseline},
  72. // Even though it's deprecated, we leave VAProfileH264Baseline's
  73. // translation here to assert we never encounter it.
  74. {"VAProfileH264Baseline", VAProfileH264Baseline},
  75. {"VAProfileH264Main", VAProfileH264Main},
  76. {"VAProfileH264High", VAProfileH264High},
  77. {"VAProfileJPEGBaseline", VAProfileJPEGBaseline},
  78. {"VAProfileVP8Version0_3", VAProfileVP8Version0_3},
  79. {"VAProfileVP9Profile0", VAProfileVP9Profile0},
  80. {"VAProfileVP9Profile2", VAProfileVP9Profile2},
  81. {"VAProfileAV1Profile0", VAProfileAV1Profile0},
  82. #if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
  83. {"VAProfileHEVCMain", VAProfileHEVCMain},
  84. {"VAProfileHEVCMain10", VAProfileHEVCMain10},
  85. #endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
  86. #if BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA)
  87. {"VAProfileProtected", VAProfileProtected},
  88. #endif // BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA)
  89. };
  90. auto it = kStringToVAProfile.find(va_profile);
  91. return it != kStringToVAProfile.end()
  92. ? absl::make_optional<VAProfile>(it->second)
  93. : absl::nullopt;
  94. }
  95. // Converts the given string to VAEntrypoint
  96. absl::optional<VAEntrypoint> StringToVAEntrypoint(
  97. const std::string& va_entrypoint) {
  98. const std::map<std::string, VAEntrypoint> kStringToVAEntrypoint = {
  99. {"VAEntrypointVLD", VAEntrypointVLD},
  100. {"VAEntrypointEncSlice", VAEntrypointEncSlice},
  101. {"VAEntrypointEncPicture", VAEntrypointEncPicture},
  102. {"VAEntrypointEncSliceLP", VAEntrypointEncSliceLP},
  103. {"VAEntrypointVideoProc", VAEntrypointVideoProc},
  104. #if BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA)
  105. {"VAEntrypointProtectedContent", VAEntrypointProtectedContent},
  106. #endif // BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA)
  107. };
  108. auto it = kStringToVAEntrypoint.find(va_entrypoint);
  109. return it != kStringToVAEntrypoint.end()
  110. ? absl::make_optional<VAEntrypoint>(it->second)
  111. : absl::nullopt;
  112. }
  113. std::unique_ptr<base::test::ScopedFeatureList> CreateScopedFeatureList() {
  114. auto scoped_feature_list = std::make_unique<base::test::ScopedFeatureList>();
  115. scoped_feature_list->InitWithFeatures(
  116. /*enabled_features=*/{media::kVaapiAV1Decoder},
  117. /*disabled_features=*/{});
  118. return scoped_feature_list;
  119. }
  120. unsigned int ToVaRTFormat(uint32_t va_fourcc) {
  121. switch (va_fourcc) {
  122. case VA_FOURCC_I420:
  123. case VA_FOURCC_NV12:
  124. return VA_RT_FORMAT_YUV420;
  125. case VA_FOURCC_YUY2:
  126. return VA_RT_FORMAT_YUV422;
  127. case VA_FOURCC_RGBA:
  128. return VA_RT_FORMAT_RGB32;
  129. case VA_FOURCC_P010:
  130. return VA_RT_FORMAT_YUV420_10;
  131. }
  132. return kInvalidVaRtFormat;
  133. }
  134. uint32_t ToVaFourcc(unsigned int va_rt_format) {
  135. switch (va_rt_format) {
  136. case VA_RT_FORMAT_YUV420:
  137. return VA_FOURCC_NV12;
  138. case VA_RT_FORMAT_YUV420_10:
  139. return VA_FOURCC_P010;
  140. }
  141. return DRM_FORMAT_INVALID;
  142. }
  143. int ToGBMFormat(unsigned int va_rt_format) {
  144. switch (va_rt_format) {
  145. case VA_RT_FORMAT_YUV420:
  146. return DRM_FORMAT_NV12;
  147. case VA_RT_FORMAT_YUV420_10:
  148. return DRM_FORMAT_P010;
  149. }
  150. return DRM_FORMAT_INVALID;
  151. }
  152. const std::string VARTFormatToString(unsigned int va_rt_format) {
  153. switch (va_rt_format) {
  154. case VA_RT_FORMAT_YUV420:
  155. return "VA_RT_FORMAT_YUV420";
  156. case VA_RT_FORMAT_YUV420_10:
  157. return "VA_RT_FORMAT_YUV420_10";
  158. }
  159. NOTREACHED() << "Unknown VA_RT_FORMAT 0x" << std::hex << va_rt_format;
  160. return "Unknown VA_RT_FORMAT";
  161. }
  162. #define TOSTR(enumCase) \
  163. case enumCase: \
  164. return #enumCase
  165. const char* VAProfileToString(VAProfile profile) {
  166. // clang-format off
  167. switch (profile) {
  168. TOSTR(VAProfileNone);
  169. TOSTR(VAProfileMPEG2Simple);
  170. TOSTR(VAProfileMPEG2Main);
  171. TOSTR(VAProfileMPEG4Simple);
  172. TOSTR(VAProfileMPEG4AdvancedSimple);
  173. TOSTR(VAProfileMPEG4Main);
  174. case VAProfileH264Baseline:
  175. NOTREACHED() << "VAProfileH264Baseline is deprecated";
  176. return "Deprecated VAProfileH264Baseline";
  177. TOSTR(VAProfileH264Main);
  178. TOSTR(VAProfileH264High);
  179. TOSTR(VAProfileVC1Simple);
  180. TOSTR(VAProfileVC1Main);
  181. TOSTR(VAProfileVC1Advanced);
  182. TOSTR(VAProfileH263Baseline);
  183. TOSTR(VAProfileH264ConstrainedBaseline);
  184. TOSTR(VAProfileJPEGBaseline);
  185. TOSTR(VAProfileVP8Version0_3);
  186. TOSTR(VAProfileH264MultiviewHigh);
  187. TOSTR(VAProfileH264StereoHigh);
  188. TOSTR(VAProfileHEVCMain);
  189. TOSTR(VAProfileHEVCMain10);
  190. TOSTR(VAProfileVP9Profile0);
  191. TOSTR(VAProfileVP9Profile1);
  192. TOSTR(VAProfileVP9Profile2);
  193. TOSTR(VAProfileVP9Profile3);
  194. TOSTR(VAProfileHEVCMain12);
  195. TOSTR(VAProfileHEVCMain422_10);
  196. TOSTR(VAProfileHEVCMain422_12);
  197. TOSTR(VAProfileHEVCMain444);
  198. TOSTR(VAProfileHEVCMain444_10);
  199. TOSTR(VAProfileHEVCMain444_12);
  200. TOSTR(VAProfileHEVCSccMain);
  201. TOSTR(VAProfileHEVCSccMain10);
  202. TOSTR(VAProfileHEVCSccMain444);
  203. TOSTR(VAProfileAV1Profile0);
  204. TOSTR(VAProfileAV1Profile1);
  205. TOSTR(VAProfileHEVCSccMain444_10);
  206. #if VA_MAJOR_VERSION >= 2 || VA_MINOR_VERSION >= 11
  207. TOSTR(VAProfileProtected);
  208. #endif
  209. }
  210. // clang-format on
  211. return "<unknown profile>";
  212. }
  213. } // namespace
  214. class VaapiTest : public testing::Test {
  215. public:
  216. VaapiTest() : scoped_feature_list_(CreateScopedFeatureList()) {}
  217. ~VaapiTest() override = default;
  218. private:
  219. std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
  220. };
  221. std::map<VAProfile, std::vector<VAEntrypoint>> ParseVainfo(
  222. const std::string& output) {
  223. const std::vector<std::string> lines =
  224. base::SplitString(output, "\n", base::WhitespaceHandling::TRIM_WHITESPACE,
  225. base::SplitResult::SPLIT_WANT_ALL);
  226. std::map<VAProfile, std::vector<VAEntrypoint>> info;
  227. for (const std::string& line : lines) {
  228. if (!base::StartsWith(line, "VAProfile",
  229. base::CompareCase::INSENSITIVE_ASCII)) {
  230. continue;
  231. }
  232. std::vector<std::string> res =
  233. base::SplitString(line, ":", base::WhitespaceHandling::TRIM_WHITESPACE,
  234. base::SplitResult::SPLIT_WANT_ALL);
  235. if (res.size() != 2) {
  236. LOG(ERROR) << "Unexpected line: " << line;
  237. continue;
  238. }
  239. auto va_profile = StringToVAProfile(res[0]);
  240. if (!va_profile)
  241. continue;
  242. auto va_entrypoint = StringToVAEntrypoint(res[1]);
  243. if (!va_entrypoint)
  244. continue;
  245. info[*va_profile].push_back(*va_entrypoint);
  246. DVLOG(3) << line;
  247. }
  248. return info;
  249. }
  250. std::string GetVaInfo(std::vector<std::string> argv) {
  251. int fds[2];
  252. PCHECK(pipe(fds) == 0);
  253. base::File read_pipe(fds[0]);
  254. base::ScopedFD write_pipe_fd(fds[1]);
  255. base::LaunchOptions options;
  256. options.fds_to_remap.emplace_back(write_pipe_fd.get(), STDOUT_FILENO);
  257. EXPECT_TRUE(LaunchProcess(argv, options).IsValid());
  258. write_pipe_fd.reset();
  259. char buf[262144] = {};
  260. int n = read_pipe.ReadAtCurrentPos(buf, sizeof(buf));
  261. PCHECK(n >= 0);
  262. EXPECT_LT(n, 262144);
  263. std::string output(buf, n);
  264. DVLOG(4) << output;
  265. return output;
  266. }
  267. std::map<VAProfile, std::vector<VAEntrypoint>> RetrieveVAInfoOutput() {
  268. std::vector<std::string> argv = {"vainfo"};
  269. std::string output = GetVaInfo(argv);
  270. return ParseVainfo(output);
  271. }
  272. TEST_F(VaapiTest, VaapiSandboxInitialization) {
  273. // Here we just test that the PreSandboxInitialization() in SetUp() worked
  274. // fine. Said initialization is buried in internal singletons, but we can
  275. // verify that at least the implementation type has been filled in.
  276. EXPECT_NE(VaapiWrapper::GetImplementationType(), VAImplementation::kInvalid);
  277. }
  278. // Commit [1] deprecated VAProfileH264Baseline from libva in 2017 (release
  279. // 2.0.0). This test verifies that such profile is never seen in the lab.
  280. // [1] https://github.com/intel/libva/commit/6f69256f8ccc9a73c0b196ab77ac69ab1f4f33c2
  281. TEST_F(VaapiTest, VerifyNoVAProfileH264Baseline) {
  282. const auto va_info = RetrieveVAInfoOutput();
  283. EXPECT_FALSE(base::Contains(va_info, VAProfileH264Baseline));
  284. }
  285. // Verifies that every VAProfile from VaapiWrapper::GetSupportedDecodeProfiles()
  286. // is indeed supported by the command line vainfo utility and by
  287. // VaapiWrapper::IsDecodeSupported().
  288. TEST_F(VaapiTest, GetSupportedDecodeProfiles) {
  289. const auto va_info = RetrieveVAInfoOutput();
  290. for (const auto& profile : VaapiWrapper::GetSupportedDecodeProfiles()) {
  291. const auto va_profile = ConvertToVAProfile(profile.profile);
  292. ASSERT_TRUE(va_profile.has_value());
  293. EXPECT_TRUE(base::Contains(va_info.at(*va_profile), VAEntrypointVLD))
  294. << " profile: " << GetProfileName(profile.profile)
  295. << ", va profile: " << vaProfileStr(*va_profile);
  296. EXPECT_TRUE(VaapiWrapper::IsDecodeSupported(*va_profile))
  297. << " profile: " << GetProfileName(profile.profile)
  298. << ", va profile: " << vaProfileStr(*va_profile);
  299. }
  300. }
  301. // Verifies that every VAProfile from VaapiWrapper::GetSupportedEncodeProfiles()
  302. // is indeed supported by the command line vainfo utility.
  303. TEST_F(VaapiTest, GetSupportedEncodeProfiles) {
  304. const auto va_info = RetrieveVAInfoOutput();
  305. for (const auto& profile : VaapiWrapper::GetSupportedEncodeProfiles()) {
  306. const auto va_profile = ConvertToVAProfile(profile.profile);
  307. ASSERT_TRUE(va_profile.has_value());
  308. EXPECT_TRUE(base::Contains(va_info.at(*va_profile), VAEntrypointEncSlice) ||
  309. base::Contains(va_info.at(*va_profile), VAEntrypointEncSliceLP))
  310. << " profile: " << GetProfileName(profile.profile)
  311. << ", va profile: " << vaProfileStr(*va_profile);
  312. }
  313. }
  314. // Verifies that the resolutions of profiles for VBR and CBR are the same.
  315. TEST_F(VaapiTest, VbrAndCbrResolutionsMatch) {
  316. struct ResolutionInfo {
  317. VaapiWrapper::CodecMode mode;
  318. gfx::Size min;
  319. gfx::Size max;
  320. };
  321. std::map<VAProfile, std::vector<ResolutionInfo>> supported_resolutions;
  322. for (const VaapiWrapper::CodecMode codec_mode :
  323. {VaapiWrapper::kEncodeConstantBitrate,
  324. VaapiWrapper::kEncodeConstantQuantizationParameter,
  325. VaapiWrapper::kEncodeVariableBitrate}) {
  326. const std::map<VAProfile, std::vector<VAEntrypoint>> configurations =
  327. VaapiWrapper::GetSupportedConfigurationsForCodecModeForTesting(
  328. codec_mode);
  329. for (const auto& configuration : configurations) {
  330. const VAProfile va_profile = configuration.first;
  331. ResolutionInfo res_info{.mode = codec_mode};
  332. ASSERT_TRUE(VaapiWrapper::GetSupportedResolutions(
  333. va_profile, codec_mode, res_info.min, res_info.max))
  334. << " Failed get resolutions: "
  335. << "profile=" << va_profile << ", mode=" << codec_mode;
  336. supported_resolutions[va_profile].push_back(res_info);
  337. }
  338. }
  339. for (const auto& r : supported_resolutions) {
  340. const VAProfile va_profile = r.first;
  341. const auto& resolution_info = r.second;
  342. for (size_t i = 0; i < resolution_info.size(); ++i) {
  343. for (size_t j = i + 1; j < resolution_info.size(); ++j) {
  344. EXPECT_EQ(resolution_info[i].min, resolution_info[j].min)
  345. << " Minimum supported resolution mismatch for profile="
  346. << VAProfileToString(va_profile) << ": " << resolution_info[i].mode
  347. << " (" << resolution_info[i].min.ToString() << ") and "
  348. << resolution_info[j].mode << " ("
  349. << resolution_info[j].min.ToString() << ")";
  350. EXPECT_EQ(resolution_info[i].max, resolution_info[j].max)
  351. << " Maximum supported resolution mismatch for profile="
  352. << VAProfileToString(va_profile) << ": " << resolution_info[i].mode
  353. << " (" << resolution_info[i].max.ToString() << ") and "
  354. << resolution_info[j].mode << " ("
  355. << resolution_info[j].max.ToString() << ")";
  356. }
  357. }
  358. }
  359. }
  360. #if BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA)
  361. // Verifies that VAProfileProtected is indeed supported by the command line
  362. // vainfo utility.
  363. TEST_F(VaapiTest, VaapiProfileProtected) {
  364. VAImplementation impl = VaapiWrapper::GetImplementationType();
  365. // VAProfileProtected is only used in the Intel iHD implementation. AMD does
  366. // not need to support that profile (but should be the only other protected
  367. // content VAAPI implementation).
  368. if (impl == VAImplementation::kIntelIHD) {
  369. const auto va_info = RetrieveVAInfoOutput();
  370. EXPECT_TRUE(base::Contains(va_info.at(VAProfileProtected),
  371. VAEntrypointProtectedContent))
  372. << ", va profile: " << vaProfileStr(VAProfileProtected);
  373. } else {
  374. EXPECT_EQ(impl, VAImplementation::kMesaGallium);
  375. }
  376. }
  377. #endif // BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA)
  378. // Verifies that if JPEG decoding and encoding are supported by VaapiWrapper,
  379. // they are also supported by by the command line vainfo utility.
  380. TEST_F(VaapiTest, VaapiProfilesJPEG) {
  381. const auto va_info = RetrieveVAInfoOutput();
  382. EXPECT_EQ(VaapiWrapper::IsDecodeSupported(VAProfileJPEGBaseline),
  383. base::Contains(va_info.at(VAProfileJPEGBaseline), VAEntrypointVLD));
  384. EXPECT_EQ(VaapiWrapper::IsJpegEncodeSupported(),
  385. base::Contains(va_info.at(VAProfileJPEGBaseline),
  386. VAEntrypointEncPicture));
  387. }
  388. // Verifies that the default VAEntrypoint as per VaapiWrapper is indeed among
  389. // the supported ones.
  390. TEST_F(VaapiTest, DefaultEntrypointIsSupported) {
  391. for (size_t i = 0; i < VaapiWrapper::kCodecModeMax; ++i) {
  392. const auto wrapper_mode = static_cast<VaapiWrapper::CodecMode>(i);
  393. std::map<VAProfile, std::vector<VAEntrypoint>> configurations =
  394. VaapiWrapper::GetSupportedConfigurationsForCodecModeForTesting(
  395. wrapper_mode);
  396. for (const auto& profile_and_entrypoints : configurations) {
  397. const VAEntrypoint default_entrypoint =
  398. VaapiWrapper::GetDefaultVaEntryPoint(wrapper_mode,
  399. profile_and_entrypoints.first);
  400. const auto& supported_entrypoints = profile_and_entrypoints.second;
  401. EXPECT_TRUE(base::Contains(supported_entrypoints, default_entrypoint))
  402. << "Default VAEntrypoint " << vaEntrypointStr(default_entrypoint)
  403. << " (VaapiWrapper mode = " << wrapper_mode
  404. << ") is not supported for "
  405. << vaProfileStr(profile_and_entrypoints.first);
  406. }
  407. }
  408. }
  409. // Verifies that VaapiWrapper::CreateContext() will queue up a buffer to set the
  410. // encoder to its lowest quality setting if a given VAProfile and VAEntrypoint
  411. // claims to support configuring it.
  412. TEST_F(VaapiTest, LowQualityEncodingSetting) {
  413. // This test only applies to low powered Intel processors.
  414. constexpr int kPentiumAndLaterFamily = 0x06;
  415. const base::CPU cpuid;
  416. const bool is_core_y_processor =
  417. base::MatchPattern(cpuid.cpu_brand(), "Intel(R) Core(TM) *Y CPU*");
  418. const bool is_low_power_intel =
  419. cpuid.family() == kPentiumAndLaterFamily &&
  420. (base::Contains(cpuid.cpu_brand(), "Pentium") ||
  421. base::Contains(cpuid.cpu_brand(), "Celeron") || is_core_y_processor);
  422. if (!is_low_power_intel)
  423. GTEST_SKIP() << "Not an Intel low power processor";
  424. for (const auto& codec_mode :
  425. {VaapiWrapper::kEncodeConstantBitrate,
  426. VaapiWrapper::kEncodeConstantQuantizationParameter}) {
  427. std::map<VAProfile, std::vector<VAEntrypoint>> configurations =
  428. VaapiWrapper::GetSupportedConfigurationsForCodecModeForTesting(
  429. codec_mode);
  430. for (const auto& profile_and_entrypoints : configurations) {
  431. const VAProfile va_profile = profile_and_entrypoints.first;
  432. scoped_refptr<VaapiWrapper> wrapper = VaapiWrapper::Create(
  433. VaapiWrapper::kEncodeConstantBitrate, va_profile,
  434. EncryptionScheme::kUnencrypted, base::DoNothing());
  435. // Depending on the GPU Gen, flags and policies, we may or may not utilize
  436. // all entrypoints (e.g. we might always want VAEntrypointEncSliceLP if
  437. // supported and enabled). Query VaapiWrapper's mandated entry point.
  438. const VAEntrypoint entrypoint =
  439. VaapiWrapper::GetDefaultVaEntryPoint(codec_mode, va_profile);
  440. ASSERT_TRUE(base::Contains(profile_and_entrypoints.second, entrypoint));
  441. VAConfigAttrib attrib{};
  442. attrib.type = VAConfigAttribEncQualityRange;
  443. {
  444. base::AutoLockMaybe auto_lock(wrapper->va_lock_.get());
  445. VAStatus va_res = vaGetConfigAttributes(
  446. wrapper->va_display_, va_profile, entrypoint, &attrib, 1);
  447. ASSERT_EQ(va_res, VA_STATUS_SUCCESS);
  448. }
  449. const auto quality_level = attrib.value;
  450. if (quality_level == VA_ATTRIB_NOT_SUPPORTED || quality_level <= 1u)
  451. continue;
  452. DLOG(INFO) << vaProfileStr(va_profile)
  453. << " supports encoding quality setting, with max value "
  454. << quality_level;
  455. // If we get here it means the |va_profile| and |entrypoint| support
  456. // the quality setting. We cannot inspect what the driver does with this
  457. // number (it could ignore it), so instead just make sure there's a
  458. // |pending_va_buffers_| that, when mapped, looks correct. That buffer
  459. // should be created by CreateContext().
  460. ASSERT_TRUE(wrapper->CreateContext(gfx::Size(640, 368)));
  461. ASSERT_EQ(wrapper->pending_va_buffers_.size(), 1u);
  462. {
  463. base::AutoLockMaybe auto_lock(wrapper->va_lock_.get());
  464. ScopedVABufferMapping mapping(wrapper->va_lock_, wrapper->va_display_,
  465. wrapper->pending_va_buffers_.front());
  466. ASSERT_TRUE(mapping.IsValid());
  467. auto* const va_buffer =
  468. reinterpret_cast<VAEncMiscParameterBuffer*>(mapping.data());
  469. EXPECT_EQ(va_buffer->type, VAEncMiscParameterTypeQualityLevel);
  470. auto* const enc_quality =
  471. reinterpret_cast<VAEncMiscParameterBufferQualityLevel*>(
  472. va_buffer->data);
  473. EXPECT_EQ(enc_quality->quality_level, quality_level)
  474. << vaProfileStr(va_profile) << " " << vaEntrypointStr(entrypoint);
  475. }
  476. }
  477. }
  478. }
  479. // This test checks the supported SVC scalability mode.
  480. TEST_F(VaapiTest, CheckSupportedSVCScalabilityModes) {
  481. #if BUILDFLAG(IS_CHROMEOS)
  482. const std::vector<SVCScalabilityMode> kSupportedTemporalSVC = {
  483. SVCScalabilityMode::kL1T2, SVCScalabilityMode::kL1T3};
  484. const std::vector<SVCScalabilityMode> kSupportedTemporalAndKeySVC = {
  485. SVCScalabilityMode::kL1T2, SVCScalabilityMode::kL1T3,
  486. SVCScalabilityMode::kL2T2Key, SVCScalabilityMode::kL2T3Key,
  487. SVCScalabilityMode::kL3T2Key, SVCScalabilityMode::kL3T3Key};
  488. #endif
  489. const auto scalability_modes_vp9_profile0 =
  490. VaapiWrapper::GetSupportedScalabilityModes(VP9PROFILE_PROFILE0,
  491. VAProfileVP9Profile0);
  492. #if BUILDFLAG(IS_CHROMEOS)
  493. if (base::FeatureList::IsEnabled(kVaapiVp9kSVCHWEncoding) &&
  494. VaapiWrapper::GetDefaultVaEntryPoint(
  495. VaapiWrapper::kEncodeConstantQuantizationParameter,
  496. VAProfileVP9Profile0) == VAEntrypointEncSliceLP) {
  497. EXPECT_EQ(scalability_modes_vp9_profile0, kSupportedTemporalAndKeySVC);
  498. } else {
  499. EXPECT_EQ(scalability_modes_vp9_profile0, kSupportedTemporalSVC);
  500. }
  501. #else
  502. EXPECT_TRUE(scalability_modes_vp9_profile0.empty());
  503. #endif
  504. const auto scalability_modes_vp9_profile2 =
  505. VaapiWrapper::GetSupportedScalabilityModes(VP9PROFILE_PROFILE2,
  506. VAProfileVP9Profile2);
  507. EXPECT_TRUE(scalability_modes_vp9_profile2.empty());
  508. const auto scalability_modes_vp8 = VaapiWrapper::GetSupportedScalabilityModes(
  509. VP8PROFILE_ANY, VAProfileVP8Version0_3);
  510. #if BUILDFLAG(IS_CHROMEOS)
  511. if (base::FeatureList::IsEnabled(kVaapiVp8TemporalLayerHWEncoding)) {
  512. EXPECT_EQ(scalability_modes_vp8, kSupportedTemporalSVC);
  513. } else {
  514. EXPECT_TRUE(scalability_modes_vp8.empty());
  515. }
  516. #else
  517. EXPECT_TRUE(scalability_modes_vp8.empty());
  518. #endif
  519. const auto scalability_modes_h264_baseline =
  520. VaapiWrapper::GetSupportedScalabilityModes(
  521. H264PROFILE_BASELINE, VAProfileH264ConstrainedBaseline);
  522. #if BUILDFLAG(IS_CHROMEOS)
  523. if (base::FeatureList::IsEnabled(kVaapiH264TemporalLayerHWEncoding)) {
  524. EXPECT_EQ(scalability_modes_h264_baseline, kSupportedTemporalSVC);
  525. } else {
  526. EXPECT_TRUE(scalability_modes_h264_baseline.empty());
  527. }
  528. #else
  529. EXPECT_TRUE(scalability_modes_h264_baseline.empty());
  530. #endif
  531. }
  532. class VaapiVppTest
  533. : public VaapiTest,
  534. public testing::WithParamInterface<std::tuple<uint32_t, uint32_t>> {
  535. public:
  536. VaapiVppTest() = default;
  537. ~VaapiVppTest() override = default;
  538. // Populate meaningful test suffixes instead of /0, /1, etc.
  539. struct PrintToStringParamName {
  540. template <class ParamType>
  541. std::string operator()(
  542. const testing::TestParamInfo<ParamType>& info) const {
  543. std::stringstream ss;
  544. ss << FourccToString(std::get<0>(info.param)) << "_to_"
  545. << FourccToString(std::get<1>(info.param));
  546. return ss.str();
  547. }
  548. };
  549. };
  550. TEST_P(VaapiVppTest, BlitWithVAAllocatedSurfaces) {
  551. const uint32_t va_fourcc_in = std::get<0>(GetParam());
  552. const uint32_t va_fourcc_out = std::get<1>(GetParam());
  553. // TODO(b/187852384): enable the other two backends.
  554. if (VaapiWrapper::GetImplementationType() != VAImplementation::kIntelIHD)
  555. GTEST_SKIP() << "backend not supported";
  556. if (!VaapiWrapper::IsVppFormatSupported(va_fourcc_in) ||
  557. !VaapiWrapper::IsVppFormatSupported(va_fourcc_out)) {
  558. GTEST_SKIP() << FourccToString(va_fourcc_in) << " -> "
  559. << FourccToString(va_fourcc_out) << " not supported";
  560. }
  561. constexpr gfx::Size kInputSize(640, 320);
  562. constexpr gfx::Size kOutputSize(320, 180);
  563. ASSERT_TRUE(VaapiWrapper::IsVppResolutionAllowed(kInputSize));
  564. ASSERT_TRUE(VaapiWrapper::IsVppResolutionAllowed(kOutputSize));
  565. auto wrapper =
  566. VaapiWrapper::Create(VaapiWrapper::kVideoProcess, VAProfileNone,
  567. EncryptionScheme::kUnencrypted, base::DoNothing());
  568. ASSERT_TRUE(!!wrapper);
  569. // Size is unnecessary for a VPP context.
  570. ASSERT_TRUE(wrapper->CreateContext(gfx::Size()));
  571. const unsigned int va_rt_format_in = ToVaRTFormat(va_fourcc_in);
  572. ASSERT_NE(va_rt_format_in, kInvalidVaRtFormat);
  573. const unsigned int va_rt_format_out = ToVaRTFormat(va_fourcc_out);
  574. ASSERT_NE(va_rt_format_out, kInvalidVaRtFormat);
  575. auto scoped_surfaces = wrapper->CreateScopedVASurfaces(
  576. va_rt_format_in, kInputSize, {VaapiWrapper::SurfaceUsageHint::kGeneric},
  577. 1u, /*visible_size=*/absl::nullopt, /*va_fourcc=*/absl::nullopt);
  578. ASSERT_FALSE(scoped_surfaces.empty());
  579. std::unique_ptr<ScopedVASurface> scoped_surface_in =
  580. std::move(scoped_surfaces[0]);
  581. scoped_surfaces = wrapper->CreateScopedVASurfaces(
  582. va_rt_format_out, kOutputSize, {VaapiWrapper::SurfaceUsageHint::kGeneric},
  583. 1u, /*visible_size=*/absl::nullopt, /*va_fourcc=*/absl::nullopt);
  584. ASSERT_FALSE(scoped_surfaces.empty());
  585. std::unique_ptr<ScopedVASurface> scoped_surface_out =
  586. std::move(scoped_surfaces[0]);
  587. scoped_refptr<VASurface> surface_in = base::MakeRefCounted<VASurface>(
  588. scoped_surface_in->id(), kInputSize, va_rt_format_in, base::DoNothing());
  589. scoped_refptr<VASurface> surface_out =
  590. base::MakeRefCounted<VASurface>(scoped_surface_out->id(), kOutputSize,
  591. va_rt_format_out, base::DoNothing());
  592. ASSERT_TRUE(wrapper->BlitSurface(*surface_in, *surface_out,
  593. gfx::Rect(kInputSize),
  594. gfx::Rect(kOutputSize), VIDEO_ROTATION_0));
  595. ASSERT_TRUE(wrapper->SyncSurface(scoped_surface_out->id()));
  596. wrapper->DestroyContext();
  597. }
  598. // TODO(b/187852384): Consider adding more VaapiVppTest cases, e.g. crops.
  599. // Note: vaCreateSurfaces() uses the RT version of the Four CC, so we don't need
  600. // to consider swizzlings, since they'll end up mapped to the same RT format.
  601. constexpr uint32_t kVAFourCCs[] = {VA_FOURCC_I420, VA_FOURCC_YUY2,
  602. VA_FOURCC_RGBA, VA_FOURCC_P010};
  603. INSTANTIATE_TEST_SUITE_P(,
  604. VaapiVppTest,
  605. ::testing::Combine(::testing::ValuesIn(kVAFourCCs),
  606. ::testing::ValuesIn(kVAFourCCs)),
  607. VaapiVppTest::PrintToStringParamName());
  608. class VaapiMinigbmTest
  609. : public VaapiTest,
  610. public testing::WithParamInterface<
  611. std::tuple<VAProfile, unsigned int /*va_rt_format*/, gfx::Size>> {
  612. public:
  613. VaapiMinigbmTest() = default;
  614. ~VaapiMinigbmTest() override = default;
  615. // Populate meaningful test suffixes instead of /0, /1, etc.
  616. struct PrintToStringParamName {
  617. template <class ParamType>
  618. std::string operator()(
  619. const testing::TestParamInfo<ParamType>& info) const {
  620. // Using here vaProfileStr(std::get<0>(info.param)) crashes the binary.
  621. // TODO(mcasas): investigate why and use it instead of codec%d.
  622. return base::StringPrintf(
  623. "%s__%s__%s", VAProfileToString(std::get<0>(info.param)),
  624. VARTFormatToString(std::get<1>(info.param)).c_str(),
  625. std::get<2>(info.param).ToString().c_str());
  626. }
  627. };
  628. };
  629. // This test allocates a VASurface (via VaapiWrapper) for the given VAProfile,
  630. // VA RT Format and resolution (as per the test parameters). It then verifies
  631. // that said VASurface's metadata (e.g. width, height, number of planes, pitch)
  632. // are the same as those we would allocate via minigbm.
  633. TEST_P(VaapiMinigbmTest, AllocateAndCompareWithMinigbm) {
  634. const VAProfile va_profile = std::get<0>(GetParam());
  635. const unsigned int va_rt_format = std::get<1>(GetParam());
  636. const gfx::Size resolution = std::get<2>(GetParam());
  637. // TODO(b/187852384): enable the other backends.
  638. const auto backend = VaapiWrapper::GetImplementationType();
  639. if (!(backend == VAImplementation::kIntelIHD ||
  640. backend == VAImplementation::kMesaGallium)) {
  641. GTEST_SKIP() << "backend not supported";
  642. }
  643. ASSERT_NE(va_rt_format, kInvalidVaRtFormat);
  644. if (!VaapiWrapper::IsDecodeSupported(va_profile))
  645. GTEST_SKIP() << vaProfileStr(va_profile) << " not supported.";
  646. if (!VaapiWrapper::IsDecodingSupportedForInternalFormat(va_profile,
  647. va_rt_format)) {
  648. GTEST_SKIP() << VARTFormatToString(va_rt_format) << " not supported.";
  649. }
  650. // TODO(b/200817282): Fix high-bit depth formats on AMD Gallium impl.
  651. if (backend == VAImplementation::kMesaGallium &&
  652. va_rt_format == VA_RT_FORMAT_YUV420_10) {
  653. GTEST_SKIP() << vaProfileStr(va_profile) << " fails on AMD, skipping.";
  654. }
  655. gfx::Size minimum_supported_size;
  656. gfx::Size maximum_supported_size;
  657. ASSERT_TRUE(VaapiWrapper::GetSupportedResolutions(
  658. va_profile, VaapiWrapper::CodecMode::kDecode, minimum_supported_size,
  659. maximum_supported_size));
  660. if (resolution.width() < minimum_supported_size.width() ||
  661. resolution.height() < minimum_supported_size.height() ||
  662. resolution.width() > maximum_supported_size.width() ||
  663. resolution.height() > maximum_supported_size.height()) {
  664. GTEST_SKIP() << resolution.ToString()
  665. << " not supported (min: " << minimum_supported_size.ToString()
  666. << ", max: " << maximum_supported_size.ToString() << ")";
  667. }
  668. auto wrapper =
  669. VaapiWrapper::Create(VaapiWrapper::kDecode, va_profile,
  670. EncryptionScheme::kUnencrypted, base::DoNothing());
  671. ASSERT_TRUE(!!wrapper);
  672. ASSERT_TRUE(wrapper->CreateContext(resolution));
  673. auto scoped_surfaces = wrapper->CreateScopedVASurfaces(
  674. va_rt_format, resolution, {VaapiWrapper::SurfaceUsageHint::kVideoDecoder},
  675. 1u,
  676. /*visible_size=*/absl::nullopt, /*va_fourcc=*/absl::nullopt);
  677. ASSERT_FALSE(scoped_surfaces.empty());
  678. const auto scoped_va_surface = std::move(scoped_surfaces[0]);
  679. wrapper->DestroyContext();
  680. ASSERT_TRUE(scoped_va_surface->IsValid());
  681. EXPECT_EQ(scoped_va_surface->format(), va_rt_format);
  682. // Request the underlying DRM metadata for |scoped_va_surface|.
  683. VADRMPRIMESurfaceDescriptor va_descriptor{};
  684. {
  685. base::AutoLockMaybe auto_lock(wrapper->va_lock_.get());
  686. VAStatus va_res =
  687. vaSyncSurface(wrapper->va_display_, scoped_va_surface->id());
  688. ASSERT_EQ(va_res, VA_STATUS_SUCCESS);
  689. va_res = vaExportSurfaceHandle(
  690. wrapper->va_display_, scoped_va_surface->id(),
  691. VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
  692. VA_EXPORT_SURFACE_READ_ONLY | VA_EXPORT_SURFACE_SEPARATE_LAYERS,
  693. &va_descriptor);
  694. ASSERT_EQ(va_res, VA_STATUS_SUCCESS);
  695. }
  696. // Verify some expected properties of the allocated VASurface. We expect one
  697. // or two |object|s, with a number of |layers| of the same |pitch|.
  698. EXPECT_EQ(scoped_va_surface->size(),
  699. gfx::Size(base::checked_cast<int>(va_descriptor.width),
  700. base::checked_cast<int>(va_descriptor.height)));
  701. const auto va_fourcc = ToVaFourcc(va_rt_format);
  702. ASSERT_NE(va_fourcc, base::checked_cast<unsigned int>(DRM_FORMAT_INVALID));
  703. EXPECT_EQ(va_descriptor.fourcc, va_fourcc)
  704. << FourccToString(va_descriptor.fourcc)
  705. << " != " << FourccToString(va_fourcc);
  706. EXPECT_THAT(va_descriptor.num_objects, ::testing::AnyOf(1, 2));
  707. // TODO(mcasas): consider comparing |size| with a better estimate of the
  708. // |scoped_va_surface| memory footprint (e.g. including planes and format).
  709. EXPECT_GE(va_descriptor.objects[0].size,
  710. base::checked_cast<uint32_t>(scoped_va_surface->size().GetArea()));
  711. if (va_descriptor.num_objects == 2) {
  712. const int uv_width = (scoped_va_surface->size().width() + 1) / 2;
  713. const int uv_height = (scoped_va_surface->size().height() + 1) / 2;
  714. EXPECT_GE(va_descriptor.objects[1].size,
  715. base::checked_cast<uint32_t>(2 * uv_width * uv_height));
  716. }
  717. base::AutoLockMaybe auto_lock(wrapper->va_lock_.get());
  718. const std::string va_vendor_string
  719. = vaQueryVendorString(wrapper->va_display_);
  720. uint64_t expected_drm_modifier = DRM_FORMAT_MOD_LINEAR;
  721. if (backend == VAImplementation::kIntelIHD) {
  722. expected_drm_modifier = I915_FORMAT_MOD_Y_TILED;
  723. } else if (backend == VAImplementation::kMesaGallium) {
  724. if (va_vendor_string.find("STONEY") != std::string::npos) {
  725. expected_drm_modifier = DRM_FORMAT_MOD_INVALID;
  726. }
  727. }
  728. EXPECT_EQ(va_descriptor.objects[0].drm_format_modifier,
  729. expected_drm_modifier);
  730. // TODO(mcasas): |num_layers| actually depends on |va_descriptor.va_fourcc|.
  731. EXPECT_EQ(va_descriptor.num_layers, 2u);
  732. for (uint32_t i = 0; i < va_descriptor.num_layers; ++i) {
  733. EXPECT_EQ(va_descriptor.layers[i].num_planes, 1u);
  734. const uint32_t expected_object_index =
  735. (va_descriptor.num_objects == 1) ? 0 : i;
  736. EXPECT_EQ(va_descriptor.layers[i].object_index[0], expected_object_index);
  737. DVLOG(2) << "plane " << i
  738. << ", pitch: " << va_descriptor.layers[i].pitch[0];
  739. // Luma and chroma planes have different |pitch| expectations.
  740. // TODO(mcasas): consider bitdepth for pitch lower thresholds.
  741. if (i == 0) {
  742. EXPECT_GE(
  743. va_descriptor.layers[i].pitch[0],
  744. base::checked_cast<uint32_t>(scoped_va_surface->size().width()));
  745. } else {
  746. const auto expected_rounded_up_pitch =
  747. base::bits::AlignUp(scoped_va_surface->size().width(), 2);
  748. EXPECT_GE(va_descriptor.layers[i].pitch[0],
  749. base::checked_cast<uint32_t>(expected_rounded_up_pitch));
  750. }
  751. }
  752. // Now open minigbm pointing to the DRM primary node, allocate a gbm_bo, and
  753. // compare its width/height/stride/etc with the |va_descriptor|s.
  754. constexpr char kPrimaryNodeFilePattern[] = "/dev/dri/card%d";
  755. struct gbm_device* gbm = nullptr;
  756. base::File drm_fd;
  757. // This loop ends on either the first card that does not exist or the first
  758. // primary node that is not vgem.
  759. for (int i = 0;; i++) {
  760. base::FilePath dev_path(FILE_PATH_LITERAL(
  761. base::StringPrintf(kPrimaryNodeFilePattern, i).c_str()));
  762. drm_fd =
  763. base::File(dev_path, base::File::FLAG_OPEN | base::File::FLAG_READ |
  764. base::File::FLAG_WRITE);
  765. ASSERT_TRUE(drm_fd.IsValid());
  766. // Skip the virtual graphics memory manager device.
  767. drmVersionPtr version = drmGetVersion(drm_fd.GetPlatformFile());
  768. if (!version)
  769. continue;
  770. std::string version_name(
  771. version->name,
  772. base::checked_cast<std::string::size_type>(version->name_len));
  773. drmFreeVersion(version);
  774. if (base::EqualsCaseInsensitiveASCII(version_name, "vgem"))
  775. continue;
  776. gbm = gbm_create_device(drm_fd.GetPlatformFile());
  777. break;
  778. }
  779. ASSERT_TRUE(gbm);
  780. const auto gbm_format = ToGBMFormat(va_rt_format);
  781. ASSERT_NE(gbm_format, DRM_FORMAT_INVALID);
  782. const auto bo_use_flags = GBM_BO_USE_TEXTURING | GBM_BO_USE_HW_VIDEO_DECODER;
  783. struct gbm_bo* bo =
  784. gbm_bo_create(gbm, resolution.width(), resolution.height(), gbm_format,
  785. bo_use_flags | GBM_BO_USE_SCANOUT);
  786. if (!bo) {
  787. // Try again without the scanout flag. This reproduces Chrome's behaviour.
  788. bo = gbm_bo_create(gbm, resolution.width(), resolution.height(), gbm_format,
  789. bo_use_flags);
  790. }
  791. ASSERT_TRUE(bo);
  792. EXPECT_EQ(scoped_va_surface->size(),
  793. gfx::Size(base::checked_cast<int>(gbm_bo_get_width(bo)),
  794. base::checked_cast<int>(gbm_bo_get_height(bo))));
  795. const int bo_num_planes = gbm_bo_get_plane_count(bo);
  796. ASSERT_EQ(va_descriptor.num_layers,
  797. base::checked_cast<uint32_t>(bo_num_planes));
  798. for (int i = 0; i < bo_num_planes; ++i) {
  799. EXPECT_EQ(va_descriptor.layers[i].pitch[0],
  800. gbm_bo_get_stride_for_plane(bo, i));
  801. }
  802. // TODO(mcasas): consider comparing |va_descriptor.objects[0].size| with |bo|s
  803. // size (as returned by lseek()ing it).
  804. gbm_bo_destroy(bo);
  805. gbm_device_destroy(gbm);
  806. }
  807. constexpr VAProfile kVACodecProfiles[] = {
  808. VAProfileVP8Version0_3, VAProfileH264ConstrainedBaseline,
  809. VAProfileVP9Profile0, VAProfileVP9Profile2,
  810. VAProfileAV1Profile0, VAProfileJPEGBaseline};
  811. constexpr uint32_t kVARTFormatsForGBM[] = {VA_RT_FORMAT_YUV420,
  812. VA_RT_FORMAT_YUV420_10};
  813. constexpr gfx::Size kResolutions[] = {
  814. // clang-format off
  815. gfx::Size(127, 127),
  816. gfx::Size(128, 128),
  817. gfx::Size(129, 129),
  818. gfx::Size(320, 180),
  819. gfx::Size(320, 240), // QVGA
  820. gfx::Size(323, 243),
  821. gfx::Size(480, 320), // 3/4 VGA
  822. gfx::Size(640, 360), // VGA
  823. gfx::Size(640, 480),
  824. gfx::Size(1280, 720)};
  825. // clang-format on
  826. INSTANTIATE_TEST_SUITE_P(
  827. ,
  828. VaapiMinigbmTest,
  829. ::testing::Combine(::testing::ValuesIn(kVACodecProfiles),
  830. ::testing::ValuesIn(kVARTFormatsForGBM),
  831. ::testing::ValuesIn(kResolutions)),
  832. VaapiMinigbmTest::PrintToStringParamName());
  833. } // namespace media
  834. int main(int argc, char** argv) {
  835. base::TestSuite test_suite(argc, argv);
  836. {
  837. // Enables/Disables features during PreSandboxInitialization(). We have to
  838. // destruct ScopedFeatureList after it because base::TestSuite::Run()
  839. // creates a ScopedFeatureList and multiple concurrent ScopedFeatureLists
  840. // are not allowed.
  841. auto scoped_feature_list = media::CreateScopedFeatureList();
  842. #if defined(USE_OZONE) && BUILDFLAG(IS_LINUX)
  843. // Initialize Ozone so that the VADisplayState can decide if we're running
  844. // on top of a platform that can deal with VA-API buffers.
  845. // TODO(b/230370976): we may no longer need to initialize Ozone since we
  846. // don't use it for buffer allocation.
  847. ui::OzonePlatform::InitParams params;
  848. params.single_process = true;
  849. ui::OzonePlatform::InitializeForUI(params);
  850. ui::OzonePlatform::InitializeForGPU(params);
  851. #endif
  852. // PreSandboxInitialization() loads and opens the driver, queries its
  853. // capabilities and fills in the VASupportedProfiles.
  854. media::VaapiWrapper::PreSandboxInitialization();
  855. }
  856. return base::LaunchUnitTests(
  857. argc, argv,
  858. base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite)));
  859. }