vp9_vaapi_video_encoder_delegate_unittest.cc 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. // Copyright 2020 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. #include "media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.h"
  5. #include <memory>
  6. #include <numeric>
  7. #include <tuple>
  8. #include <va/va.h>
  9. #include "base/callback.h"
  10. #include "base/callback_helpers.h"
  11. #include "base/cxx17_backports.h"
  12. #include "base/logging.h"
  13. #include "base/memory/raw_ptr.h"
  14. #include "base/numerics/safe_conversions.h"
  15. #include "media/filters/vp9_parser.h"
  16. #include "media/gpu/gpu_video_encode_accelerator_helpers.h"
  17. #include "media/gpu/vaapi/vaapi_common.h"
  18. #include "media/gpu/vaapi/vaapi_wrapper.h"
  19. #include "media/gpu/video_rate_control.h"
  20. #include "media/gpu/vp9_svc_layers.h"
  21. #include "testing/gmock/include/gmock/gmock.h"
  22. #include "testing/gtest/include/gtest/gtest.h"
  23. #include "third_party/abseil-cpp/absl/types/optional.h"
  24. #include "third_party/libvpx/source/libvpx/vp9/common/vp9_blockd.h"
  25. #include "third_party/libvpx/source/libvpx/vp9/ratectrl_rtc.h"
  26. using ::testing::_;
  27. using ::testing::InSequence;
  28. using ::testing::Invoke;
  29. using ::testing::Return;
  30. namespace media {
  31. namespace {
  32. constexpr size_t kDefaultMaxNumRefFrames = kVp9NumRefsPerFrame;
  33. constexpr int kSpatialLayersResolutionScaleDenom[][3] = {
  34. {1, 0, 0}, // For one spatial layer.
  35. {2, 1, 0}, // For two spatial layers.
  36. {4, 2, 1}, // For three spatial layers.
  37. };
  38. constexpr uint8_t kTemporalLayerPattern[][4] = {
  39. {0, 0, 0, 0},
  40. {0, 1, 0, 1},
  41. {0, 2, 1, 2},
  42. };
  43. VaapiVideoEncoderDelegate::Config kDefaultVaapiVideoEncoderDelegateConfig{
  44. .max_num_ref_frames = kDefaultMaxNumRefFrames};
  45. VideoEncodeAccelerator::Config kDefaultVideoEncodeAcceleratorConfig(
  46. PIXEL_FORMAT_I420,
  47. gfx::Size(1280, 720),
  48. VP9PROFILE_PROFILE0,
  49. Bitrate::ConstantBitrate(14000000u)
  50. /* = maximum bitrate in bits per second for level 3.1 */,
  51. VideoEncodeAccelerator::kDefaultFramerate,
  52. absl::nullopt /* gop_length */,
  53. absl::nullopt /* h264 output level*/,
  54. false /* is_constrained_h264 */,
  55. VideoEncodeAccelerator::Config::StorageType::kShmem);
  56. constexpr std::array<bool, kVp9NumRefsPerFrame> kRefFramesUsedForKeyFrame = {
  57. false, false, false};
  58. constexpr std::array<bool, kVp9NumRefsPerFrame> kRefFramesUsedForInterFrame = {
  59. true, true, true};
  60. constexpr std::array<bool, kVp9NumRefsPerFrame>
  61. kRefFramesUsedForInterFrameInTemporalLayer = {true, false, false};
  62. void GetTemporalLayer(bool keyframe,
  63. int frame_num,
  64. size_t num_spatial_layers,
  65. size_t num_temporal_layers,
  66. std::array<bool, kVp9NumRefsPerFrame>* ref_frames_used,
  67. uint8_t* temporal_layer_id) {
  68. switch (num_temporal_layers) {
  69. case 1:
  70. *temporal_layer_id = 0;
  71. if (num_spatial_layers > 1) {
  72. // K-SVC stream.
  73. *ref_frames_used = keyframe
  74. ? kRefFramesUsedForKeyFrame
  75. : kRefFramesUsedForInterFrameInTemporalLayer;
  76. } else {
  77. // Simple stream.
  78. *ref_frames_used =
  79. keyframe ? kRefFramesUsedForKeyFrame : kRefFramesUsedForInterFrame;
  80. }
  81. break;
  82. case 2:
  83. if (keyframe) {
  84. *temporal_layer_id = 0;
  85. *ref_frames_used = kRefFramesUsedForKeyFrame;
  86. return;
  87. }
  88. {
  89. *temporal_layer_id = kTemporalLayerPattern[1][frame_num % 4];
  90. *ref_frames_used = kRefFramesUsedForInterFrameInTemporalLayer;
  91. }
  92. break;
  93. case 3:
  94. if (keyframe) {
  95. *temporal_layer_id = 0u;
  96. *ref_frames_used = kRefFramesUsedForKeyFrame;
  97. return;
  98. }
  99. {
  100. *temporal_layer_id = kTemporalLayerPattern[2][frame_num % 4];
  101. *ref_frames_used = kRefFramesUsedForInterFrameInTemporalLayer;
  102. }
  103. break;
  104. }
  105. }
  106. VideoBitrateAllocation CreateBitrateAllocationWithActiveLayers(
  107. const VideoBitrateAllocation& bitrate_allocation,
  108. const std::vector<size_t>& active_layers) {
  109. VideoBitrateAllocation new_bitrate_allocation;
  110. for (size_t si : active_layers) {
  111. for (size_t ti = 0; ti < VideoBitrateAllocation::kMaxTemporalLayers; ++ti) {
  112. const uint32_t bps = bitrate_allocation.GetBitrateBps(si, ti);
  113. new_bitrate_allocation.SetBitrate(si, ti, bps);
  114. }
  115. }
  116. return new_bitrate_allocation;
  117. }
  118. VideoBitrateAllocation AdaptBitrateAllocation(
  119. const VideoBitrateAllocation& bitrate_allocation) {
  120. VideoBitrateAllocation new_bitrate_allocation;
  121. size_t new_si = 0;
  122. for (size_t si = 0; si < VideoBitrateAllocation::kMaxSpatialLayers; ++si) {
  123. int sum = 0;
  124. for (size_t ti = 0; ti < VideoBitrateAllocation::kMaxTemporalLayers; ++ti)
  125. sum += bitrate_allocation.GetBitrateBps(si, ti);
  126. if (sum == 0) {
  127. // The spatial layer is disabled.
  128. continue;
  129. }
  130. for (size_t ti = 0; ti < VideoBitrateAllocation::kMaxTemporalLayers; ++ti) {
  131. const uint32_t bps = bitrate_allocation.GetBitrateBps(si, ti);
  132. new_bitrate_allocation.SetBitrate(new_si, ti, bps);
  133. }
  134. new_si++;
  135. }
  136. return new_bitrate_allocation;
  137. }
  138. std::vector<gfx::Size> GetDefaultSpatialLayerResolutions(
  139. size_t num_spatial_layers) {
  140. constexpr gfx::Size& kDefaultSize =
  141. kDefaultVideoEncodeAcceleratorConfig.input_visible_size;
  142. std::vector<gfx::Size> spatial_layer_resolutions(num_spatial_layers);
  143. for (size_t sid = 0; sid < num_spatial_layers; ++sid) {
  144. const int denom =
  145. kSpatialLayersResolutionScaleDenom[num_spatial_layers - 1][sid];
  146. spatial_layer_resolutions[sid] =
  147. gfx::Size(kDefaultSize.width() / denom, kDefaultSize.height() / denom);
  148. }
  149. return spatial_layer_resolutions;
  150. }
  151. MATCHER_P4(MatchRtcConfigWithRates,
  152. bitrate_allocation,
  153. framerate,
  154. num_temporal_layers,
  155. spatial_layer_resolutions,
  156. "") {
  157. if (arg.target_bandwidth < 0)
  158. return false;
  159. if (static_cast<uint32_t>(arg.target_bandwidth) !=
  160. bitrate_allocation.GetSumBps() / 1000) {
  161. return false;
  162. }
  163. if (arg.framerate != static_cast<double>(framerate))
  164. return false;
  165. const size_t num_spatial_layers = spatial_layer_resolutions.size();
  166. for (size_t sid = 0; sid < num_spatial_layers; ++sid) {
  167. int bitrate_sum = 0;
  168. for (size_t tid = 0; tid < num_temporal_layers; ++tid) {
  169. size_t idx = sid * num_temporal_layers + tid;
  170. bitrate_sum += bitrate_allocation.GetBitrateBps(sid, tid);
  171. if (arg.layer_target_bitrate[idx] != bitrate_sum / 1000)
  172. return false;
  173. if (arg.ts_rate_decimator[tid] != (1 << (num_temporal_layers - tid - 1)))
  174. return false;
  175. }
  176. if (arg.scaling_factor_num[sid] != 1 ||
  177. arg.scaling_factor_den[sid] !=
  178. kSpatialLayersResolutionScaleDenom[num_spatial_layers - 1][sid]) {
  179. return false;
  180. }
  181. }
  182. const gfx::Size& size = spatial_layer_resolutions.back();
  183. return arg.width == size.width() && arg.height == size.height() &&
  184. base::checked_cast<size_t>(arg.ss_number_layers) ==
  185. num_spatial_layers &&
  186. base::checked_cast<size_t>(arg.ts_number_layers) ==
  187. num_temporal_layers;
  188. }
  189. MATCHER_P3(MatchFrameParam,
  190. frame_type,
  191. temporal_layer_id,
  192. spatial_layer_id,
  193. "") {
  194. return arg.frame_type == frame_type &&
  195. arg.temporal_layer_id == temporal_layer_id &&
  196. arg.spatial_layer_id == spatial_layer_id;
  197. }
  198. MATCHER_P2(MatchVABufferDescriptor, va_buffer_type, va_buffer_size, "") {
  199. return arg.type == va_buffer_type && arg.size == va_buffer_size &&
  200. arg.data != nullptr;
  201. }
  202. class MockVaapiWrapper : public VaapiWrapper {
  203. public:
  204. MockVaapiWrapper() : VaapiWrapper(kEncodeConstantQuantizationParameter) {}
  205. MOCK_METHOD1(SubmitBuffer_Locked, bool(const VABufferDescriptor&));
  206. protected:
  207. ~MockVaapiWrapper() override = default;
  208. };
  209. class MockVP9RateControl
  210. : public VideoRateControl<libvpx::VP9RateControlRtcConfig,
  211. libvpx::VP9RateControlRTC,
  212. libvpx::VP9FrameParamsQpRTC> {
  213. public:
  214. MockVP9RateControl() = default;
  215. ~MockVP9RateControl() override = default;
  216. MOCK_METHOD1(UpdateRateControl, void(const libvpx::VP9RateControlRtcConfig&));
  217. MOCK_CONST_METHOD0(GetQP, int());
  218. MOCK_CONST_METHOD0(GetLoopfilterLevel, int());
  219. MOCK_METHOD1(ComputeQP, void(const libvpx::VP9FrameParamsQpRTC&));
  220. MOCK_METHOD1(PostEncodeUpdate, void(uint64_t));
  221. };
  222. } // namespace
  223. struct VP9VaapiVideoEncoderDelegateTestParam;
  224. class VP9VaapiVideoEncoderDelegateTest
  225. : public ::testing::TestWithParam<VP9VaapiVideoEncoderDelegateTestParam> {
  226. public:
  227. VP9VaapiVideoEncoderDelegateTest() = default;
  228. ~VP9VaapiVideoEncoderDelegateTest() override = default;
  229. void SetUp() override;
  230. MOCK_METHOD0(OnError, void());
  231. protected:
  232. void ResetEncoder();
  233. void InitializeVP9VaapiVideoEncoderDelegate(size_t num_spatial_layers,
  234. size_t num_temporal_layers);
  235. void EncodeConstantQuantizationParameterSequence(
  236. bool is_keyframe,
  237. const gfx::Size& layer_size,
  238. absl::optional<std::array<bool, kVp9NumRefsPerFrame>>
  239. expected_ref_frames_used,
  240. uint8_t expected_temporal_layer_id,
  241. uint8_t expected_spatial_layer_id);
  242. void UpdateRatesTest(size_t num_spatial_layers, size_t num_temporal_layers);
  243. void UpdateRatesAndEncode(
  244. const VideoBitrateAllocation& bitrate_allocation,
  245. uint32_t framerate,
  246. bool valid_rates_request,
  247. bool is_key_pic,
  248. const std::vector<gfx::Size>& expected_spatial_layer_resolutions,
  249. size_t expected_temporal_layers,
  250. size_t expected_temporal_layer_id);
  251. private:
  252. std::unique_ptr<VaapiVideoEncoderDelegate::EncodeJob> CreateEncodeJob(
  253. bool keyframe,
  254. const scoped_refptr<VASurface>& va_surface,
  255. const scoped_refptr<VP9Picture>& picture);
  256. std::unique_ptr<VP9VaapiVideoEncoderDelegate> encoder_;
  257. scoped_refptr<MockVaapiWrapper> mock_vaapi_wrapper_;
  258. raw_ptr<MockVP9RateControl> mock_rate_ctrl_ = nullptr;
  259. };
  260. void VP9VaapiVideoEncoderDelegateTest::ResetEncoder() {
  261. encoder_ = std::make_unique<VP9VaapiVideoEncoderDelegate>(
  262. mock_vaapi_wrapper_,
  263. base::BindRepeating(&VP9VaapiVideoEncoderDelegateTest::OnError,
  264. base::Unretained(this)));
  265. }
  266. void VP9VaapiVideoEncoderDelegateTest::SetUp() {
  267. mock_vaapi_wrapper_ = base::MakeRefCounted<MockVaapiWrapper>();
  268. ASSERT_TRUE(mock_vaapi_wrapper_);
  269. ResetEncoder();
  270. EXPECT_CALL(*this, OnError()).Times(0);
  271. }
  272. std::unique_ptr<VaapiVideoEncoderDelegate::EncodeJob>
  273. VP9VaapiVideoEncoderDelegateTest::CreateEncodeJob(
  274. bool keyframe,
  275. const scoped_refptr<VASurface>& va_surface,
  276. const scoped_refptr<VP9Picture>& picture) {
  277. constexpr VABufferID kDummyVABufferID = 12;
  278. auto scoped_va_buffer = ScopedVABuffer::CreateForTesting(
  279. kDummyVABufferID, VAEncCodedBufferType,
  280. kDefaultVideoEncodeAcceleratorConfig.input_visible_size.GetArea());
  281. // TODO(b/229358029): Set a valid timestamp and check the timestamp in
  282. // metadata.
  283. constexpr base::TimeDelta timestamp;
  284. return std::make_unique<VaapiVideoEncoderDelegate::EncodeJob>(
  285. keyframe, timestamp, va_surface->id(), picture,
  286. std::move(scoped_va_buffer));
  287. }
  288. void VP9VaapiVideoEncoderDelegateTest::InitializeVP9VaapiVideoEncoderDelegate(
  289. size_t num_spatial_layers,
  290. size_t num_temporal_layers) {
  291. auto config = kDefaultVideoEncodeAcceleratorConfig;
  292. auto ave_config = kDefaultVaapiVideoEncoderDelegateConfig;
  293. auto rate_ctrl = std::make_unique<MockVP9RateControl>();
  294. mock_rate_ctrl_ = rate_ctrl.get();
  295. encoder_->set_rate_ctrl_for_testing(std::move(rate_ctrl));
  296. auto initial_bitrate_allocation = AllocateDefaultBitrateForTesting(
  297. num_spatial_layers, num_temporal_layers,
  298. kDefaultVideoEncodeAcceleratorConfig.bitrate);
  299. std::vector<gfx::Size> svc_layer_size =
  300. GetDefaultSpatialLayerResolutions(num_spatial_layers);
  301. if (num_spatial_layers > 1u || num_temporal_layers > 1u) {
  302. DCHECK_GT(num_spatial_layers, 0u);
  303. for (size_t sid = 0; sid < num_spatial_layers; ++sid) {
  304. uint32_t sl_bitrate = 0;
  305. for (size_t tid = 0; tid < num_temporal_layers; ++tid)
  306. sl_bitrate += initial_bitrate_allocation.GetBitrateBps(sid, tid);
  307. VideoEncodeAccelerator::Config::SpatialLayer spatial_layer;
  308. spatial_layer.width = svc_layer_size[sid].width();
  309. spatial_layer.height = svc_layer_size[sid].height();
  310. spatial_layer.bitrate_bps = sl_bitrate;
  311. spatial_layer.framerate = *config.initial_framerate;
  312. spatial_layer.num_of_temporal_layers = num_temporal_layers;
  313. spatial_layer.max_qp = 30u;
  314. config.spatial_layers.push_back(spatial_layer);
  315. }
  316. }
  317. EXPECT_CALL(*mock_rate_ctrl_,
  318. UpdateRateControl(MatchRtcConfigWithRates(
  319. AllocateDefaultBitrateForTesting(
  320. num_spatial_layers, num_temporal_layers, config.bitrate),
  321. VideoEncodeAccelerator::kDefaultFramerate,
  322. num_temporal_layers, svc_layer_size)))
  323. .Times(1)
  324. .WillOnce(Return());
  325. EXPECT_TRUE(encoder_->Initialize(config, ave_config));
  326. EXPECT_EQ(num_temporal_layers > 1u || num_spatial_layers > 1u,
  327. !!encoder_->svc_layers_);
  328. EXPECT_EQ(encoder_->GetSVCLayerResolutions(), svc_layer_size);
  329. }
  330. void VP9VaapiVideoEncoderDelegateTest::
  331. EncodeConstantQuantizationParameterSequence(
  332. bool is_keyframe,
  333. const gfx::Size& layer_size,
  334. absl::optional<std::array<bool, kVp9NumRefsPerFrame>>
  335. expected_ref_frames_used,
  336. uint8_t expected_temporal_layer_id,
  337. uint8_t expected_spatial_layer_id) {
  338. InSequence seq;
  339. constexpr VASurfaceID kDummyVASurfaceID = 123;
  340. auto va_surface = base::MakeRefCounted<VASurface>(
  341. kDummyVASurfaceID, layer_size, VA_RT_FORMAT_YUV420, base::DoNothing());
  342. scoped_refptr<VP9Picture> picture = new VaapiVP9Picture(va_surface);
  343. auto encode_job = CreateEncodeJob(is_keyframe, va_surface, picture);
  344. FRAME_TYPE libvpx_frame_type =
  345. is_keyframe ? FRAME_TYPE::KEY_FRAME : FRAME_TYPE::INTER_FRAME;
  346. EXPECT_CALL(
  347. *mock_rate_ctrl_,
  348. ComputeQP(MatchFrameParam(libvpx_frame_type, expected_temporal_layer_id,
  349. expected_spatial_layer_id)))
  350. .WillOnce(Return());
  351. constexpr int kDefaultQP = 34;
  352. constexpr int kDefaultLoopFilterLevel = 8;
  353. EXPECT_CALL(*mock_rate_ctrl_, GetQP()).WillOnce(Return(kDefaultQP));
  354. EXPECT_CALL(*mock_rate_ctrl_, GetLoopfilterLevel())
  355. .WillOnce(Return(kDefaultLoopFilterLevel));
  356. EXPECT_CALL(*mock_vaapi_wrapper_,
  357. SubmitBuffer_Locked(MatchVABufferDescriptor(
  358. VAEncSequenceParameterBufferType,
  359. sizeof(VAEncSequenceParameterBufferVP9))))
  360. .WillOnce(Return(true));
  361. EXPECT_CALL(*mock_vaapi_wrapper_,
  362. SubmitBuffer_Locked(MatchVABufferDescriptor(
  363. VAEncPictureParameterBufferType,
  364. sizeof(VAEncPictureParameterBufferVP9))))
  365. .WillOnce(Return(true));
  366. EXPECT_TRUE(encoder_->PrepareEncodeJob(*encode_job.get()));
  367. // TODO(hiroh): Test for encoder_->reference_frames_.
  368. constexpr size_t kDefaultEncodedFrameSize = 123456;
  369. // For BitrateControlUpdate sequence.
  370. EXPECT_CALL(*mock_rate_ctrl_, PostEncodeUpdate(kDefaultEncodedFrameSize))
  371. .WillOnce(Return());
  372. encoder_->BitrateControlUpdate(kDefaultEncodedFrameSize);
  373. }
  374. void VP9VaapiVideoEncoderDelegateTest::UpdateRatesAndEncode(
  375. const VideoBitrateAllocation& bitrate_allocation,
  376. uint32_t framerate,
  377. bool valid_rates_request,
  378. bool is_key_pic,
  379. const std::vector<gfx::Size>& expected_spatial_layer_resolutions,
  380. size_t expected_temporal_layers,
  381. size_t expected_temporal_layer_id) {
  382. ASSERT_TRUE(encoder_->current_params_.bitrate_allocation !=
  383. bitrate_allocation ||
  384. encoder_->current_params_.framerate != framerate);
  385. // Since the request is pended, this is always successful and no call happens
  386. // to VP9SVCLayers and RateControl.
  387. EXPECT_TRUE(encoder_->UpdateRates(bitrate_allocation, framerate));
  388. EXPECT_TRUE(encoder_->pending_update_rates_.has_value());
  389. // The pending update rates request is applied in GetSVCLayerResolutions().
  390. if (!valid_rates_request) {
  391. EXPECT_TRUE(encoder_->GetSVCLayerResolutions().empty());
  392. return;
  393. }
  394. // VideoBitrateAllocation is adapted if some spatial layers are deactivated.
  395. const VideoBitrateAllocation adapted_bitrate_allocation =
  396. AdaptBitrateAllocation(bitrate_allocation);
  397. EXPECT_CALL(*mock_rate_ctrl_, UpdateRateControl(MatchRtcConfigWithRates(
  398. adapted_bitrate_allocation, framerate,
  399. expected_temporal_layers,
  400. expected_spatial_layer_resolutions)))
  401. .Times(1)
  402. .WillOnce(Return());
  403. EXPECT_EQ(encoder_->GetSVCLayerResolutions(),
  404. expected_spatial_layer_resolutions);
  405. EXPECT_FALSE(encoder_->pending_update_rates_.has_value());
  406. EXPECT_EQ(encoder_->current_params_.bitrate_allocation,
  407. adapted_bitrate_allocation);
  408. EXPECT_EQ(encoder_->current_params_.framerate, framerate);
  409. const size_t num_spatial_layers = expected_spatial_layer_resolutions.size();
  410. for (size_t sid = 0; sid < num_spatial_layers; ++sid) {
  411. const gfx::Size& layer_size = expected_spatial_layer_resolutions[sid];
  412. const bool is_keyframe = is_key_pic && sid == 0;
  413. EncodeConstantQuantizationParameterSequence(
  414. is_keyframe, layer_size,
  415. /*expected_ref_frames_used=*/{}, expected_temporal_layer_id, sid);
  416. }
  417. }
  418. void VP9VaapiVideoEncoderDelegateTest::UpdateRatesTest(
  419. size_t num_spatial_layers,
  420. size_t num_temporal_layers) {
  421. ASSERT_TRUE(num_temporal_layers <= VP9SVCLayers::kMaxSupportedTemporalLayers);
  422. ASSERT_TRUE(num_spatial_layers <= VP9SVCLayers::kMaxSupportedTemporalLayers);
  423. const auto spatial_layer_resolutions =
  424. GetDefaultSpatialLayerResolutions(num_spatial_layers);
  425. auto update_rates_and_encode = [this, num_spatial_layers, num_temporal_layers,
  426. &spatial_layer_resolutions](
  427. bool is_key_pic,
  428. uint8_t expected_temporal_layer_id,
  429. uint32_t bitrate, uint32_t framerate) {
  430. auto bitrate_allocation = AllocateDefaultBitrateForTesting(
  431. num_spatial_layers, num_temporal_layers,
  432. media::Bitrate::ConstantBitrate(bitrate));
  433. UpdateRatesAndEncode(bitrate_allocation, framerate,
  434. /*valid_rates_request=*/true, is_key_pic,
  435. spatial_layer_resolutions, num_temporal_layers,
  436. expected_temporal_layer_id);
  437. };
  438. const uint32_t kBitrate =
  439. kDefaultVideoEncodeAcceleratorConfig.bitrate.target_bps();
  440. const uint32_t kFramerate =
  441. *kDefaultVideoEncodeAcceleratorConfig.initial_framerate;
  442. const uint8_t* expected_temporal_ids =
  443. kTemporalLayerPattern[num_temporal_layers - 1];
  444. // Call UpdateRates before Encode.
  445. update_rates_and_encode(true, expected_temporal_ids[0], kBitrate / 2,
  446. kFramerate);
  447. // Bitrate change only.
  448. update_rates_and_encode(false, expected_temporal_ids[1], kBitrate,
  449. kFramerate);
  450. // Framerate change only.
  451. update_rates_and_encode(false, expected_temporal_ids[2], kBitrate,
  452. kFramerate + 2);
  453. // Bitrate + Frame changes.
  454. update_rates_and_encode(false, expected_temporal_ids[3], kBitrate * 3 / 4,
  455. kFramerate - 5);
  456. }
  457. struct VP9VaapiVideoEncoderDelegateTestParam {
  458. size_t num_spatial_layers;
  459. size_t num_temporal_layers;
  460. } kTestCasesForVP9VaapiVideoEncoderDelegateTest[] = {
  461. {1u, 1u}, {1u, 2u}, {1u, 3u}, {2u, 1u}, {2u, 2u},
  462. {2u, 3u}, {3u, 1u}, {3u, 2u}, {3u, 3u},
  463. };
  464. TEST_P(VP9VaapiVideoEncoderDelegateTest, Initialize) {
  465. InitializeVP9VaapiVideoEncoderDelegate(GetParam().num_spatial_layers,
  466. GetParam().num_temporal_layers);
  467. }
  468. TEST_P(VP9VaapiVideoEncoderDelegateTest, EncodeWithSoftwareBitrateControl) {
  469. const size_t num_spatial_layers = GetParam().num_spatial_layers;
  470. const size_t num_temporal_layers = GetParam().num_temporal_layers;
  471. InitializeVP9VaapiVideoEncoderDelegate(num_spatial_layers,
  472. num_temporal_layers);
  473. const std::vector<gfx::Size> layer_sizes =
  474. GetDefaultSpatialLayerResolutions(num_spatial_layers);
  475. constexpr size_t kEncodeFrames = 20;
  476. for (size_t frame_num = 0; frame_num < kEncodeFrames; ++frame_num) {
  477. for (size_t sid = 0; sid < num_spatial_layers; ++sid) {
  478. const bool is_keyframe = (frame_num == 0 && sid == 0);
  479. std::array<bool, kVp9NumRefsPerFrame> ref_frames_used;
  480. uint8_t temporal_layer_id;
  481. GetTemporalLayer(is_keyframe, frame_num, num_spatial_layers,
  482. num_temporal_layers, &ref_frames_used,
  483. &temporal_layer_id);
  484. EncodeConstantQuantizationParameterSequence(is_keyframe, layer_sizes[sid],
  485. ref_frames_used,
  486. temporal_layer_id, sid);
  487. }
  488. }
  489. }
  490. TEST_P(VP9VaapiVideoEncoderDelegateTest,
  491. ForceKeyFrameWithSoftwareBitrateControl) {
  492. const size_t num_spatial_layers = GetParam().num_spatial_layers;
  493. const size_t num_temporal_layers = GetParam().num_temporal_layers;
  494. InitializeVP9VaapiVideoEncoderDelegate(num_spatial_layers,
  495. num_temporal_layers);
  496. constexpr size_t kNumKeyFrames = 3;
  497. constexpr size_t kKeyFrameInterval = 20;
  498. const std::vector<gfx::Size> layer_sizes =
  499. GetDefaultSpatialLayerResolutions(num_spatial_layers);
  500. for (size_t j = 0; j < kNumKeyFrames; ++j) {
  501. for (size_t i = 0; i < kKeyFrameInterval; ++i) {
  502. for (size_t sid = 0; sid < num_spatial_layers; ++sid) {
  503. const bool keyframe = (i == 0 && sid == 0);
  504. std::array<bool, kVp9NumRefsPerFrame> ref_frames_used;
  505. uint8_t temporal_layer_id;
  506. GetTemporalLayer(keyframe, i, num_spatial_layers, num_temporal_layers,
  507. &ref_frames_used, &temporal_layer_id);
  508. EncodeConstantQuantizationParameterSequence(keyframe, layer_sizes[sid],
  509. ref_frames_used,
  510. temporal_layer_id, sid);
  511. }
  512. }
  513. }
  514. }
  515. TEST_P(VP9VaapiVideoEncoderDelegateTest, UpdateRates) {
  516. const size_t num_spatial_layers = GetParam().num_spatial_layers;
  517. const size_t num_temporal_layers = GetParam().num_temporal_layers;
  518. InitializeVP9VaapiVideoEncoderDelegate(num_spatial_layers,
  519. num_temporal_layers);
  520. UpdateRatesTest(num_spatial_layers, num_temporal_layers);
  521. }
  522. TEST_P(VP9VaapiVideoEncoderDelegateTest, DeactivateActivateSpatialLayers) {
  523. const size_t num_spatial_layers = GetParam().num_spatial_layers;
  524. const size_t num_temporal_layers = GetParam().num_temporal_layers;
  525. if (num_spatial_layers == 1)
  526. GTEST_SKIP() << "Skip a single spatial layer";
  527. InitializeVP9VaapiVideoEncoderDelegate(num_spatial_layers,
  528. num_temporal_layers);
  529. const std::vector<std::vector<size_t>> kActivateExercise[2] = {
  530. {
  531. // Two spatial layers.
  532. {0}, // Deactivate the top layer.
  533. {0, 1}, // Activate the top layer.
  534. {1}, // Deactivate the bottom layer.
  535. {0, 1}, // Activate the bottom layer.
  536. },
  537. {
  538. // Three spatial layers.
  539. {0, 1}, // Deactivate the top layer.
  540. {1}, // Deactivate the bottom layer.
  541. {0}, // Activate the bottom layer and deactivate the top two layers.
  542. {1,
  543. 2}, // Activate the top two layers and deactivate the bottom layer.
  544. {0, 1, 2}, // Activate the bottom layer.
  545. {2}, // Deactivate the bottom two layers.
  546. {0, 1, 2}, // Activate the bottom two layers.
  547. },
  548. };
  549. const VideoBitrateAllocation kDefaultBitrateAllocation =
  550. AllocateDefaultBitrateForTesting(
  551. num_spatial_layers, num_temporal_layers,
  552. kDefaultVideoEncodeAcceleratorConfig.bitrate);
  553. const std::vector<gfx::Size> kDefaultSpatialLayers =
  554. GetDefaultSpatialLayerResolutions(num_spatial_layers);
  555. const uint32_t kFramerate =
  556. *kDefaultVideoEncodeAcceleratorConfig.initial_framerate;
  557. for (auto& active_layers : kActivateExercise[num_spatial_layers - 2]) {
  558. const VideoBitrateAllocation bitrate_allocation =
  559. CreateBitrateAllocationWithActiveLayers(kDefaultBitrateAllocation,
  560. active_layers);
  561. std::vector<gfx::Size> spatial_layer_resolutions;
  562. for (size_t active_sid : active_layers)
  563. spatial_layer_resolutions.emplace_back(kDefaultSpatialLayers[active_sid]);
  564. // Always is_key_pic=true and temporal_layer_id=0 because the active spatial
  565. // layers are changed.
  566. UpdateRatesAndEncode(bitrate_allocation, kFramerate,
  567. /*valid_rates_request=*/true,
  568. /*is_key_pic=*/true, spatial_layer_resolutions,
  569. num_temporal_layers,
  570. /*expected_temporal_layer_id=*/0u);
  571. }
  572. }
  573. TEST_P(VP9VaapiVideoEncoderDelegateTest, FailsWithInvalidSpatialLayers) {
  574. const size_t num_spatial_layers = GetParam().num_spatial_layers;
  575. const size_t num_temporal_layers = GetParam().num_temporal_layers;
  576. const VideoBitrateAllocation kDefaultBitrateAllocation =
  577. AllocateDefaultBitrateForTesting(
  578. num_spatial_layers, num_temporal_layers,
  579. kDefaultVideoEncodeAcceleratorConfig.bitrate);
  580. std::vector<VideoBitrateAllocation> invalid_bitrate_allocations;
  581. constexpr uint32_t kBitrate = 1234u;
  582. auto bitrate_allocation = kDefaultBitrateAllocation;
  583. // Activate one more top spatial layer.
  584. ASSERT_LE(num_spatial_layers + 1, VideoBitrateAllocation::kMaxSpatialLayers);
  585. bitrate_allocation.SetBitrate(num_spatial_layers, /*temporal_index=*/0,
  586. kBitrate);
  587. invalid_bitrate_allocations.push_back(bitrate_allocation);
  588. // Deactivate a middle spatial layer.
  589. if (num_spatial_layers == 3) {
  590. bitrate_allocation = kDefaultBitrateAllocation;
  591. for (size_t ti = 0; ti < VideoBitrateAllocation::kMaxTemporalLayers; ++ti)
  592. bitrate_allocation.SetBitrate(1, ti, 0u);
  593. invalid_bitrate_allocations.push_back(bitrate_allocation);
  594. }
  595. // Increase the number of temporal layers.
  596. bitrate_allocation = kDefaultBitrateAllocation;
  597. ASSERT_LE(num_temporal_layers + 1,
  598. VideoBitrateAllocation::kMaxTemporalLayers);
  599. for (size_t si = 0; si < num_spatial_layers; ++si)
  600. bitrate_allocation.SetBitrate(si, num_temporal_layers, kBitrate);
  601. invalid_bitrate_allocations.push_back(bitrate_allocation);
  602. // Decrease the number of temporal layers.
  603. if (num_temporal_layers > 1) {
  604. bitrate_allocation = kDefaultBitrateAllocation;
  605. for (size_t si = 0; si < num_spatial_layers; ++si)
  606. bitrate_allocation.SetBitrate(si, num_temporal_layers - 1, 0u);
  607. invalid_bitrate_allocations.push_back(bitrate_allocation);
  608. }
  609. // Set 0 in the bottom temporal layer.
  610. if (num_temporal_layers > 1) {
  611. bitrate_allocation = kDefaultBitrateAllocation;
  612. bitrate_allocation.SetBitrate(/*spatial_index=*/0, /*temporal_index=*/0,
  613. 0u);
  614. invalid_bitrate_allocations.push_back(bitrate_allocation);
  615. }
  616. // Set 0 in the middle temporal layer
  617. if (num_temporal_layers == 3) {
  618. bitrate_allocation = kDefaultBitrateAllocation;
  619. bitrate_allocation.SetBitrate(/*spatial_index=*/0, /*temporal_index=*/1,
  620. 0u);
  621. invalid_bitrate_allocations.push_back(bitrate_allocation);
  622. }
  623. const uint32_t kFramerate =
  624. *kDefaultVideoEncodeAcceleratorConfig.initial_framerate;
  625. for (const auto& invalid_allocation : invalid_bitrate_allocations) {
  626. InitializeVP9VaapiVideoEncoderDelegate(num_spatial_layers,
  627. num_temporal_layers);
  628. // The values of expected_spatial_layer_resolutions, is_key_pic,
  629. // expected_temporal_layers and expected_temporal_layer_id are meaningless
  630. // because UpdateRatesAndEncode will returns before checking them due to the
  631. // invalid VideoBitrateAllocation request.
  632. UpdateRatesAndEncode(invalid_allocation, kFramerate,
  633. /*valid_rates_request=*/false,
  634. /*is_key_pic=*/true,
  635. /*expected_spatial_layer_resolutions=*/{},
  636. /*expected_temporal_layers=*/0u,
  637. /*expected_temporal_layer_id=*/0u);
  638. ResetEncoder();
  639. }
  640. }
  641. INSTANTIATE_TEST_SUITE_P(
  642. ,
  643. VP9VaapiVideoEncoderDelegateTest,
  644. ::testing::ValuesIn(kTestCasesForVP9VaapiVideoEncoderDelegateTest));
  645. } // namespace media