vaapi_video_decode_accelerator_unittest.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. // Copyright 2017 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/vaapi_video_decode_accelerator.h"
  5. #include "base/bind.h"
  6. #include "base/callback_helpers.h"
  7. #include "base/memory/ptr_util.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "base/run_loop.h"
  10. #include "base/test/gmock_callback_support.h"
  11. #include "base/test/task_environment.h"
  12. #include "base/time/time.h"
  13. #include "media/gpu/accelerated_video_decoder.h"
  14. #include "media/gpu/vaapi/vaapi_picture.h"
  15. #include "media/gpu/vaapi/vaapi_picture_factory.h"
  16. #include "media/gpu/vaapi/vaapi_video_decoder_delegate.h"
  17. #include "media/gpu/vaapi/vaapi_wrapper.h"
  18. #include "testing/gmock/include/gmock/gmock.h"
  19. #include "testing/gtest/include/gtest/gtest.h"
  20. using base::test::RunClosure;
  21. using ::testing::_;
  22. using ::testing::DoAll;
  23. using ::testing::Invoke;
  24. using ::testing::Return;
  25. using ::testing::TestWithParam;
  26. using ::testing::ValuesIn;
  27. using ::testing::WithArg;
  28. namespace media {
  29. namespace {
  30. struct TestParams {
  31. VideoCodecProfile video_codec;
  32. bool decode_using_client_picture_buffers;
  33. };
  34. constexpr int32_t kBitstreamId = 123;
  35. constexpr size_t kInputSize = 256;
  36. constexpr size_t kNumPictures = 14;
  37. const gfx::Size kPictureSize(64, 48);
  38. constexpr size_t kNewNumPictures = 13;
  39. const gfx::Size kNewPictureSize(64, 48);
  40. MATCHER_P2(IsExpectedDecoderBuffer, data_size, decrypt_config, "") {
  41. return arg.data_size() == data_size && arg.decrypt_config() == decrypt_config;
  42. }
  43. } // namespace
  44. class MockAcceleratedVideoDecoder : public AcceleratedVideoDecoder {
  45. public:
  46. MockAcceleratedVideoDecoder() = default;
  47. ~MockAcceleratedVideoDecoder() override = default;
  48. MOCK_METHOD2(SetStream, void(int32_t id, const DecoderBuffer&));
  49. MOCK_METHOD0(Flush, bool());
  50. MOCK_METHOD0(Reset, void());
  51. MOCK_METHOD0(Decode, DecodeResult());
  52. MOCK_CONST_METHOD0(GetPicSize, gfx::Size());
  53. MOCK_CONST_METHOD0(GetProfile, VideoCodecProfile());
  54. MOCK_CONST_METHOD0(GetBitDepth, uint8_t());
  55. MOCK_CONST_METHOD0(GetChromaSampling, VideoChromaSampling());
  56. MOCK_CONST_METHOD0(GetVisibleRect, gfx::Rect());
  57. MOCK_CONST_METHOD0(GetRequiredNumOfPictures, size_t());
  58. MOCK_CONST_METHOD0(GetNumReferenceFrames, size_t());
  59. };
  60. class MockVaapiWrapper : public VaapiWrapper {
  61. public:
  62. MockVaapiWrapper(CodecMode mode) : VaapiWrapper(mode) {}
  63. MOCK_METHOD5(CreateContextAndSurfaces,
  64. bool(unsigned int,
  65. const gfx::Size&,
  66. const std::vector<SurfaceUsageHint>&,
  67. size_t,
  68. std::vector<VASurfaceID>*));
  69. MOCK_METHOD1(CreateContext, bool(const gfx::Size&));
  70. MOCK_METHOD0(DestroyContext, void());
  71. MOCK_METHOD1(DestroySurface, void(VASurfaceID));
  72. private:
  73. ~MockVaapiWrapper() override = default;
  74. };
  75. class MockVaapiPicture : public VaapiPicture {
  76. public:
  77. MockVaapiPicture(scoped_refptr<VaapiWrapper> vaapi_wrapper,
  78. const MakeGLContextCurrentCallback& make_context_current_cb,
  79. const BindGLImageCallback& bind_image_cb,
  80. int32_t picture_buffer_id,
  81. const gfx::Size& size,
  82. const gfx::Size& visible_size,
  83. uint32_t texture_id,
  84. uint32_t client_texture_id,
  85. uint32_t texture_target)
  86. : VaapiPicture(std::move(vaapi_wrapper),
  87. make_context_current_cb,
  88. bind_image_cb,
  89. picture_buffer_id,
  90. size,
  91. visible_size,
  92. texture_id,
  93. client_texture_id,
  94. texture_target) {}
  95. ~MockVaapiPicture() override = default;
  96. // VaapiPicture implementation.
  97. VaapiStatus Allocate(gfx::BufferFormat format) override {
  98. return VaapiStatus::Codes::kOk;
  99. }
  100. bool ImportGpuMemoryBufferHandle(
  101. gfx::BufferFormat format,
  102. gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle) override {
  103. return true;
  104. }
  105. bool DownloadFromSurface(scoped_refptr<VASurface> va_surface) override {
  106. return true;
  107. }
  108. bool AllowOverlay() const override { return false; }
  109. VASurfaceID va_surface_id() const override {
  110. // Return any number different from VA_INVALID_ID and VaapiPicture specific.
  111. return static_cast<VASurfaceID>(texture_id_);
  112. }
  113. };
  114. class MockVaapiPictureFactory : public VaapiPictureFactory {
  115. public:
  116. MockVaapiPictureFactory() = default;
  117. ~MockVaapiPictureFactory() override = default;
  118. MOCK_METHOD3(MockCreateVaapiPicture,
  119. void(VaapiWrapper*, const gfx::Size&, const gfx::Size&));
  120. std::unique_ptr<VaapiPicture> Create(
  121. scoped_refptr<VaapiWrapper> vaapi_wrapper,
  122. const MakeGLContextCurrentCallback& make_context_current_cb,
  123. const BindGLImageCallback& bind_image_cb,
  124. const PictureBuffer& picture_buffer,
  125. const gfx::Size& visible_size) override {
  126. const uint32_t service_texture_id = picture_buffer.service_texture_ids()[0];
  127. const uint32_t client_texture_id = picture_buffer.client_texture_ids()[0];
  128. MockCreateVaapiPicture(vaapi_wrapper.get(), picture_buffer.size(),
  129. visible_size);
  130. return std::make_unique<MockVaapiPicture>(
  131. std::move(vaapi_wrapper), make_context_current_cb, bind_image_cb,
  132. picture_buffer.id(), picture_buffer.size(), visible_size,
  133. service_texture_id, client_texture_id, picture_buffer.texture_target());
  134. }
  135. };
  136. class VaapiVideoDecodeAcceleratorTest : public TestWithParam<TestParams>,
  137. public VideoDecodeAccelerator::Client {
  138. public:
  139. VaapiVideoDecodeAcceleratorTest()
  140. : vda_(
  141. base::BindRepeating([] { return true; }),
  142. base::BindRepeating([](uint32_t client_texture_id,
  143. uint32_t texture_target,
  144. const scoped_refptr<gl::GLImage>& image,
  145. bool can_bind_to_sampler) { return true; })),
  146. decoder_thread_("VaapiVideoDecodeAcceleratorTestThread"),
  147. mock_decoder_(new ::testing::StrictMock<MockAcceleratedVideoDecoder>),
  148. mock_vaapi_picture_factory_(new MockVaapiPictureFactory()),
  149. mock_vaapi_wrapper_(new MockVaapiWrapper(VaapiWrapper::kDecode)),
  150. mock_vpp_vaapi_wrapper_(new MockVaapiWrapper(VaapiWrapper::kDecode)),
  151. weak_ptr_factory_(this) {
  152. decoder_thread_.Start();
  153. // Don't want to go through a vda_->Initialize() because it binds too many
  154. // items of the environment. Instead, do all the necessary steps here.
  155. vda_.decoder_thread_task_runner_ = decoder_thread_.task_runner();
  156. decoder_delegate_ = std::make_unique<VaapiVideoDecoderDelegate>(
  157. &vda_, mock_vaapi_wrapper_, base::DoNothing(), nullptr);
  158. // Plug in all the mocks and ourselves as the |client_|.
  159. vda_.decoder_.reset(mock_decoder_);
  160. vda_.decoder_delegate_ = decoder_delegate_.get();
  161. vda_.client_ = weak_ptr_factory_.GetWeakPtr();
  162. vda_.vaapi_wrapper_ = mock_vaapi_wrapper_;
  163. vda_.vpp_vaapi_wrapper_ = mock_vpp_vaapi_wrapper_;
  164. vda_.vaapi_picture_factory_.reset(mock_vaapi_picture_factory_);
  165. // TODO(crbug.com/917999): add IMPORT mode to test variations.
  166. vda_.output_mode_ = VideoDecodeAccelerator::Config::OutputMode::ALLOCATE;
  167. vda_.profile_ = GetParam().video_codec;
  168. vda_.buffer_allocation_mode_ =
  169. GetParam().decode_using_client_picture_buffers
  170. ? VaapiVideoDecodeAccelerator::BufferAllocationMode::kNone
  171. : VaapiVideoDecodeAccelerator::BufferAllocationMode::kSuperReduced;
  172. vda_.state_ = VaapiVideoDecodeAccelerator::kIdle;
  173. }
  174. VaapiVideoDecodeAcceleratorTest(const VaapiVideoDecodeAcceleratorTest&) =
  175. delete;
  176. VaapiVideoDecodeAcceleratorTest& operator=(
  177. const VaapiVideoDecodeAcceleratorTest&) = delete;
  178. ~VaapiVideoDecodeAcceleratorTest() {}
  179. void SetUp() override {
  180. in_shm_ = base::UnsafeSharedMemoryRegion::Create(kInputSize);
  181. }
  182. void SetVdaStateToUnitialized() {
  183. base::AutoLock auto_lock(vda_.lock_);
  184. vda_.state_ = VaapiVideoDecodeAccelerator::kUninitialized;
  185. }
  186. void QueueInputBuffer(BitstreamBuffer bitstream_buffer) {
  187. auto id = bitstream_buffer.id();
  188. vda_.QueueInputBuffer(bitstream_buffer.ToDecoderBuffer(), id);
  189. }
  190. void AssignPictureBuffers(const std::vector<PictureBuffer>& picture_buffers) {
  191. vda_.AssignPictureBuffers(picture_buffers);
  192. }
  193. // Reset epilogue, needed to get |vda_| worker thread out of its Wait().
  194. void ResetSequence() {
  195. base::RunLoop run_loop;
  196. EXPECT_CALL(*mock_decoder_, Reset());
  197. EXPECT_CALL(*this, NotifyResetDone())
  198. .WillOnce(RunClosure(run_loop.QuitClosure()));
  199. vda_.Reset();
  200. run_loop.Run();
  201. }
  202. // Try and QueueInputBuffer()s, where we pretend that |mock_decoder_| requests
  203. // to kConfigChange: |vda_| will ping us to ProvidePictureBuffers().
  204. // If |expect_dismiss_picture_buffers| is signalled, then we expect as well
  205. // that |vda_| will emit |num_picture_buffers_to_dismiss| DismissPictureBuffer
  206. // calls.
  207. void QueueInputBufferSequence(size_t num_pictures,
  208. const gfx::Size& picture_size,
  209. int32_t bitstream_id,
  210. bool expect_dismiss_picture_buffers = false,
  211. size_t num_picture_buffers_to_dismiss = 0) {
  212. ::testing::InSequence s;
  213. EXPECT_CALL(*mock_decoder_,
  214. SetStream(_, IsExpectedDecoderBuffer(kInputSize, nullptr)))
  215. .WillOnce(Return());
  216. EXPECT_CALL(*mock_decoder_, Decode())
  217. .WillOnce(Return(AcceleratedVideoDecoder::kConfigChange));
  218. EXPECT_CALL(*mock_decoder_, GetBitDepth()).WillOnce(Return(8u));
  219. EXPECT_CALL(*mock_decoder_, GetPicSize()).WillOnce(Return(picture_size));
  220. EXPECT_CALL(*mock_decoder_, GetVisibleRect())
  221. .WillOnce(Return(gfx::Rect(picture_size)));
  222. EXPECT_CALL(*mock_decoder_, GetRequiredNumOfPictures())
  223. .WillOnce(Return(num_pictures));
  224. const size_t kNumReferenceFrames = num_pictures / 2;
  225. EXPECT_CALL(*mock_decoder_, GetNumReferenceFrames())
  226. .WillOnce(Return(kNumReferenceFrames));
  227. EXPECT_CALL(*mock_decoder_, GetProfile())
  228. .WillOnce(Return(GetParam().video_codec));
  229. EXPECT_CALL(*mock_vaapi_wrapper_, DestroyContext());
  230. if (expect_dismiss_picture_buffers) {
  231. EXPECT_CALL(*this, DismissPictureBuffer(_))
  232. .Times(num_picture_buffers_to_dismiss);
  233. }
  234. const size_t expected_num_picture_buffers_requested =
  235. vda_.buffer_allocation_mode_ ==
  236. VaapiVideoDecodeAccelerator::BufferAllocationMode::kSuperReduced
  237. ? num_pictures - kNumReferenceFrames
  238. : num_pictures;
  239. base::RunLoop run_loop;
  240. EXPECT_CALL(*this,
  241. ProvidePictureBuffers(expected_num_picture_buffers_requested, _,
  242. 1, picture_size, _))
  243. .WillOnce(RunClosure(run_loop.QuitClosure()));
  244. BitstreamBuffer bitstream_buffer(bitstream_id, in_shm_.Duplicate(),
  245. kInputSize);
  246. QueueInputBuffer(std::move(bitstream_buffer));
  247. run_loop.Run();
  248. }
  249. // Calls AssignPictureBuffers(), expecting the corresponding mock calls; we
  250. // pretend |mock_decoder_| has kRanOutOfStreamData (i.e. it's finished
  251. // decoding) and expect |vda_| to emit a NotifyEndOfBitstreamBuffer().
  252. // QueueInputBufferSequence() must have been called beforehand.
  253. void AssignPictureBuffersSequence(size_t num_pictures,
  254. const gfx::Size& picture_size,
  255. int32_t bitstream_id) {
  256. ASSERT_TRUE(vda_.curr_input_buffer_)
  257. << "QueueInputBuffer() should have been called";
  258. // |decode_using_client_picture_buffers| determines the concrete method for
  259. // creation of context, surfaces and VaapiPictures.
  260. if (GetParam().decode_using_client_picture_buffers) {
  261. EXPECT_CALL(*mock_vaapi_wrapper_, CreateContext(picture_size))
  262. .WillOnce(Return(true));
  263. EXPECT_CALL(*mock_decoder_, GetVisibleRect())
  264. .WillRepeatedly(Return(gfx::Rect(picture_size)));
  265. EXPECT_CALL(*mock_vaapi_picture_factory_,
  266. MockCreateVaapiPicture(mock_vaapi_wrapper_.get(),
  267. picture_size, picture_size))
  268. .Times(num_pictures);
  269. } else {
  270. EXPECT_EQ(
  271. vda_.buffer_allocation_mode_,
  272. VaapiVideoDecodeAccelerator::BufferAllocationMode::kSuperReduced);
  273. const size_t kNumReferenceFrames = 1 + num_pictures / 2;
  274. EXPECT_CALL(*mock_vaapi_wrapper_,
  275. CreateContextAndSurfaces(
  276. _, picture_size,
  277. std::vector<VaapiWrapper::SurfaceUsageHint>{
  278. VaapiWrapper::SurfaceUsageHint::kVideoDecoder},
  279. kNumReferenceFrames, _))
  280. .WillOnce(DoAll(
  281. WithArg<4>(Invoke([kNumReferenceFrames](
  282. std::vector<VASurfaceID>* va_surface_ids) {
  283. va_surface_ids->resize(kNumReferenceFrames);
  284. })),
  285. Return(true)));
  286. EXPECT_CALL(*mock_vaapi_wrapper_, DestroySurface(_))
  287. .Times(kNumReferenceFrames);
  288. EXPECT_CALL(*mock_decoder_, GetVisibleRect())
  289. .WillRepeatedly(Return(gfx::Rect(picture_size)));
  290. EXPECT_CALL(*mock_vaapi_picture_factory_,
  291. MockCreateVaapiPicture(_, picture_size, picture_size))
  292. .Times(num_pictures);
  293. }
  294. ::testing::InSequence s;
  295. base::RunLoop run_loop;
  296. EXPECT_CALL(*mock_decoder_, Decode())
  297. .WillOnce(Return(AcceleratedVideoDecoder::kRanOutOfStreamData));
  298. EXPECT_CALL(*this, NotifyEndOfBitstreamBuffer(bitstream_id))
  299. .WillOnce(RunClosure(run_loop.QuitClosure()));
  300. const auto tex_target = mock_vaapi_picture_factory_->GetGLTextureTarget();
  301. int32_t irrelevant_id = 2;
  302. std::vector<PictureBuffer> picture_buffers;
  303. for (size_t picture = 0; picture < num_pictures; ++picture) {
  304. // The picture buffer id, client id and service texture ids are
  305. // arbitrarily chosen.
  306. picture_buffers.push_back(
  307. {irrelevant_id++, picture_size,
  308. PictureBuffer::TextureIds{static_cast<uint32_t>(irrelevant_id++)},
  309. PictureBuffer::TextureIds{static_cast<uint32_t>(irrelevant_id++)},
  310. tex_target, PIXEL_FORMAT_XRGB});
  311. }
  312. AssignPictureBuffers(picture_buffers);
  313. run_loop.Run();
  314. }
  315. // Calls QueueInputBuffer(); we instruct from |mock_decoder_| that it has
  316. // kRanOutOfStreamData (i.e. it's finished decoding). This is a fast method
  317. // because the Decode() is (almost) immediate.
  318. void DecodeOneFrameFast(int32_t bitstream_id) {
  319. base::RunLoop run_loop;
  320. EXPECT_CALL(*mock_decoder_,
  321. SetStream(_, IsExpectedDecoderBuffer(kInputSize, nullptr)))
  322. .WillOnce(Return());
  323. EXPECT_CALL(*mock_decoder_, Decode())
  324. .WillOnce(Return(AcceleratedVideoDecoder::kRanOutOfStreamData));
  325. EXPECT_CALL(*this, NotifyEndOfBitstreamBuffer(bitstream_id))
  326. .WillOnce(RunClosure(run_loop.QuitClosure()));
  327. QueueInputBuffer(
  328. BitstreamBuffer(bitstream_id, in_shm_.Duplicate(), kInputSize));
  329. run_loop.Run();
  330. }
  331. // VideoDecodeAccelerator::Client methods.
  332. MOCK_METHOD1(NotifyInitializationComplete, void(DecoderStatus));
  333. MOCK_METHOD5(
  334. ProvidePictureBuffers,
  335. void(uint32_t, VideoPixelFormat, uint32_t, const gfx::Size&, uint32_t));
  336. MOCK_METHOD1(DismissPictureBuffer, void(int32_t));
  337. MOCK_METHOD1(PictureReady, void(const Picture&));
  338. MOCK_METHOD1(NotifyEndOfBitstreamBuffer, void(int32_t));
  339. MOCK_METHOD0(NotifyFlushDone, void());
  340. MOCK_METHOD0(NotifyResetDone, void());
  341. MOCK_METHOD1(NotifyError, void(VideoDecodeAccelerator::Error));
  342. base::test::TaskEnvironment task_environment_;
  343. std::unique_ptr<VaapiVideoDecoderDelegate> decoder_delegate_;
  344. // The class under test and a worker thread for it.
  345. VaapiVideoDecodeAccelerator vda_;
  346. base::Thread decoder_thread_;
  347. // Ownership passed to |vda_|, but we retain a pointer to it for MOCK checks.
  348. raw_ptr<MockAcceleratedVideoDecoder> mock_decoder_;
  349. raw_ptr<MockVaapiPictureFactory> mock_vaapi_picture_factory_;
  350. scoped_refptr<MockVaapiWrapper> mock_vaapi_wrapper_;
  351. scoped_refptr<MockVaapiWrapper> mock_vpp_vaapi_wrapper_;
  352. base::UnsafeSharedMemoryRegion in_shm_;
  353. private:
  354. base::WeakPtrFactory<VaapiVideoDecodeAcceleratorTest> weak_ptr_factory_;
  355. };
  356. // Verify that it is possible to select DRM(egl) and TFP(glx) at runtime.
  357. TEST_P(VaapiVideoDecodeAcceleratorTest, SupportedPlatforms) {
  358. EXPECT_EQ(VaapiPictureFactory::kVaapiImplementationNone,
  359. mock_vaapi_picture_factory_->GetVaapiImplementation(
  360. gl::kGLImplementationNone));
  361. EXPECT_EQ(VaapiPictureFactory::kVaapiImplementationDrm,
  362. mock_vaapi_picture_factory_->GetVaapiImplementation(
  363. gl::kGLImplementationEGLGLES2));
  364. #if BUILDFLAG(USE_VAAPI_X11)
  365. EXPECT_EQ(VaapiPictureFactory::kVaapiImplementationAngle,
  366. mock_vaapi_picture_factory_->GetVaapiImplementation(
  367. gl::kGLImplementationEGLANGLE));
  368. EXPECT_EQ(VaapiPictureFactory::kVaapiImplementationX11,
  369. mock_vaapi_picture_factory_->GetVaapiImplementation(
  370. gl::kGLImplementationDesktopGL));
  371. #elif defined(USE_OZONE)
  372. EXPECT_EQ(VaapiPictureFactory::kVaapiImplementationDrm,
  373. mock_vaapi_picture_factory_->GetVaapiImplementation(
  374. gl::kGLImplementationEGLANGLE));
  375. #endif
  376. }
  377. // This test checks that QueueInputBuffer() fails when state is kUnitialized.
  378. TEST_P(VaapiVideoDecodeAcceleratorTest,
  379. QueueInputBufferAndErrorWhenVDAUninitialized) {
  380. SetVdaStateToUnitialized();
  381. BitstreamBuffer bitstream_buffer(kBitstreamId, in_shm_.Duplicate(),
  382. kInputSize);
  383. EXPECT_CALL(*this,
  384. NotifyError(VaapiVideoDecodeAccelerator::PLATFORM_FAILURE));
  385. QueueInputBuffer(std::move(bitstream_buffer));
  386. }
  387. // Verifies that Decode() returning kDecodeError ends up pinging NotifyError().
  388. TEST_P(VaapiVideoDecodeAcceleratorTest, QueueInputBufferAndDecodeError) {
  389. BitstreamBuffer bitstream_buffer(kBitstreamId, in_shm_.Duplicate(),
  390. kInputSize);
  391. base::RunLoop run_loop;
  392. EXPECT_CALL(*mock_decoder_,
  393. SetStream(_, IsExpectedDecoderBuffer(kInputSize, nullptr)))
  394. .WillOnce(Return());
  395. EXPECT_CALL(*mock_decoder_, Decode())
  396. .WillOnce(Return(AcceleratedVideoDecoder::kDecodeError));
  397. EXPECT_CALL(*this, NotifyError(VaapiVideoDecodeAccelerator::PLATFORM_FAILURE))
  398. .WillOnce(RunClosure(run_loop.QuitClosure()));
  399. QueueInputBuffer(std::move(bitstream_buffer));
  400. run_loop.Run();
  401. }
  402. TEST_P(VaapiVideoDecodeAcceleratorTest, QueueVP9Profile2AndError) {
  403. if (GetParam().video_codec != VP9PROFILE_PROFILE2)
  404. GTEST_SKIP() << "The test parameter is not vp9 profile 2";
  405. BitstreamBuffer bitstream_buffer(kBitstreamId, in_shm_.Duplicate(),
  406. kInputSize);
  407. base::RunLoop run_loop;
  408. EXPECT_CALL(*mock_decoder_,
  409. SetStream(_, IsExpectedDecoderBuffer(kInputSize, nullptr)))
  410. .WillOnce(Return());
  411. EXPECT_CALL(*mock_decoder_, Decode())
  412. .WillOnce(Return(AcceleratedVideoDecoder::kConfigChange));
  413. EXPECT_CALL(*mock_decoder_, GetBitDepth()).WillOnce(Return(10u));
  414. EXPECT_CALL(*this, NotifyError(VaapiVideoDecodeAccelerator::PLATFORM_FAILURE))
  415. .WillOnce(RunClosure(run_loop.QuitClosure()));
  416. QueueInputBuffer(std::move(bitstream_buffer));
  417. run_loop.Run();
  418. }
  419. // Verifies a single fast frame decoding..
  420. TEST_P(VaapiVideoDecodeAcceleratorTest, DecodeOneFrame) {
  421. if (GetParam().video_codec == VP9PROFILE_PROFILE2)
  422. GTEST_SKIP() << "Decoding profile 2 is not supported";
  423. DecodeOneFrameFast(kBitstreamId);
  424. ResetSequence();
  425. }
  426. // Tests usual startup sequence: a BitstreamBuffer is enqueued for decode;
  427. // |vda_| asks for PictureBuffers, that we provide via AssignPictureBuffers().
  428. TEST_P(VaapiVideoDecodeAcceleratorTest,
  429. QueueInputBuffersAndAssignPictureBuffers) {
  430. if (GetParam().video_codec == VP9PROFILE_PROFILE2)
  431. GTEST_SKIP() << "Decoding profile 2 is not supported";
  432. QueueInputBufferSequence(kNumPictures, kPictureSize, kBitstreamId);
  433. AssignPictureBuffersSequence(kNumPictures, kPictureSize, kBitstreamId);
  434. ResetSequence();
  435. }
  436. // Tests a typical resolution change sequence: a BitstreamBuffer is enqueued;
  437. // |vda_| asks for PictureBuffers, we them provide via AssignPictureBuffers().
  438. // We then try to enqueue a few BitstreamBuffers of a different resolution: we
  439. // then expect the old ones to be dismissed and new ones provided.This sequence
  440. // is purely ingress-wise, i.e. there's no decoded output checks.
  441. TEST_P(VaapiVideoDecodeAcceleratorTest,
  442. QueueInputBuffersAndAssignPictureBuffersAndReallocate) {
  443. if (GetParam().video_codec == VP9PROFILE_PROFILE2)
  444. GTEST_SKIP() << "Decoding profile 2 is not supported";
  445. QueueInputBufferSequence(kNumPictures, kPictureSize, kBitstreamId);
  446. AssignPictureBuffersSequence(kNumPictures, kPictureSize, kBitstreamId);
  447. // Decode a few frames. This step is not necessary.
  448. for (int i = 0; i < 5; ++i)
  449. DecodeOneFrameFast(kBitstreamId + i);
  450. QueueInputBufferSequence(kNewNumPictures, kNewPictureSize, kBitstreamId,
  451. true /* expect_dismiss_picture_buffers */,
  452. kNumPictures /* num_picture_buffers_to_dismiss */);
  453. AssignPictureBuffersSequence(kNewNumPictures, kNewPictureSize, kBitstreamId);
  454. ResetSequence();
  455. }
  456. constexpr TestParams kTestCases[] = {
  457. {H264PROFILE_MIN, false /* decode_using_client_picture_buffers */},
  458. {H264PROFILE_MIN, true /* decode_using_client_picture_buffers */},
  459. {VP8PROFILE_MIN, false /* decode_using_client_picture_buffers */},
  460. {VP9PROFILE_MIN, false /* decode_using_client_picture_buffers */},
  461. {VP9PROFILE_MIN, true /* decode_using_client_picture_buffers */},
  462. {VP9PROFILE_PROFILE2, false /* decode_using_client_picture_buffers */},
  463. };
  464. INSTANTIATE_TEST_SUITE_P(All,
  465. VaapiVideoDecodeAcceleratorTest,
  466. ValuesIn(kTestCases));
  467. } // namespace media