stable_video_decoder_service_unittest.cc 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  1. // Copyright 2022 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/mojo/services/stable_video_decoder_service.h"
  5. #include "base/test/mock_callback.h"
  6. #include "base/test/task_environment.h"
  7. #include "media/mojo/common/mojo_decoder_buffer_converter.h"
  8. #include "media/mojo/mojom/media_log.mojom.h"
  9. #include "media/mojo/mojom/video_decoder.mojom.h"
  10. #include "media/mojo/services/stable_video_decoder_factory_service.h"
  11. #include "mojo/public/cpp/bindings/associated_receiver.h"
  12. #include "mojo/public/cpp/bindings/remote.h"
  13. #include "mojo/public/cpp/system/data_pipe.h"
  14. #include "testing/gmock/include/gmock/gmock.h"
  15. #include "testing/gtest/include/gtest/gtest.h"
  16. using testing::_;
  17. using testing::ByMove;
  18. using testing::Mock;
  19. using testing::Return;
  20. using testing::SaveArg;
  21. using testing::StrictMock;
  22. namespace media {
  23. namespace {
  24. VideoDecoderConfig CreateValidVideoDecoderConfig() {
  25. const VideoDecoderConfig config(
  26. VideoCodec::kH264, VideoCodecProfile::H264PROFILE_BASELINE,
  27. VideoDecoderConfig::AlphaMode::kHasAlpha, VideoColorSpace::REC709(),
  28. VideoTransformation(VIDEO_ROTATION_90, /*mirrored=*/true),
  29. /*coded_size=*/gfx::Size(640, 368),
  30. /*visible_rect=*/gfx::Rect(1, 1, 630, 360),
  31. /*natural_size=*/gfx::Size(1260, 720),
  32. /*extra_data=*/std::vector<uint8_t>{1, 2, 3},
  33. EncryptionScheme::kUnencrypted);
  34. DCHECK(config.IsValidConfig());
  35. return config;
  36. }
  37. class MockVideoFrameHandleReleaser : public mojom::VideoFrameHandleReleaser {
  38. public:
  39. explicit MockVideoFrameHandleReleaser(
  40. mojo::PendingReceiver<mojom::VideoFrameHandleReleaser>
  41. video_frame_handle_releaser)
  42. : video_frame_handle_releaser_receiver_(
  43. this,
  44. std::move(video_frame_handle_releaser)) {}
  45. MockVideoFrameHandleReleaser(const MockVideoFrameHandleReleaser&) = delete;
  46. MockVideoFrameHandleReleaser& operator=(const MockVideoFrameHandleReleaser&) =
  47. delete;
  48. ~MockVideoFrameHandleReleaser() override = default;
  49. // mojom::VideoFrameHandleReleaser implementation.
  50. MOCK_METHOD2(ReleaseVideoFrame,
  51. void(const base::UnguessableToken& release_token,
  52. const absl::optional<gpu::SyncToken>& release_sync_token));
  53. private:
  54. mojo::Receiver<mojom::VideoFrameHandleReleaser>
  55. video_frame_handle_releaser_receiver_;
  56. };
  57. class MockVideoDecoder : public mojom::VideoDecoder {
  58. public:
  59. MockVideoDecoder() = default;
  60. MockVideoDecoder(const MockVideoDecoder&) = delete;
  61. MockVideoDecoder& operator=(const MockVideoDecoder&) = delete;
  62. ~MockVideoDecoder() override = default;
  63. mojo::AssociatedRemote<mojom::VideoDecoderClient> TakeClientRemote() {
  64. return std::move(client_remote_);
  65. }
  66. mojo::Remote<mojom::MediaLog> TakeMediaLogRemote() {
  67. return std::move(media_log_remote_);
  68. }
  69. std::unique_ptr<StrictMock<MockVideoFrameHandleReleaser>>
  70. TakeVideoFrameHandleReleaser() {
  71. return std::move(video_frame_handle_releaser_);
  72. }
  73. std::unique_ptr<MojoDecoderBufferReader> TakeMojoDecoderBufferReader() {
  74. return std::move(mojo_decoder_buffer_reader_);
  75. };
  76. // mojom::VideoDecoder implementation.
  77. MOCK_METHOD1(GetSupportedConfigs, void(GetSupportedConfigsCallback callback));
  78. void Construct(
  79. mojo::PendingAssociatedRemote<mojom::VideoDecoderClient> client,
  80. mojo::PendingRemote<mojom::MediaLog> media_log,
  81. mojo::PendingReceiver<mojom::VideoFrameHandleReleaser>
  82. video_frame_handle_releaser,
  83. mojo::ScopedDataPipeConsumerHandle decoder_buffer_pipe,
  84. mojom::CommandBufferIdPtr command_buffer_id,
  85. const gfx::ColorSpace& target_color_space) final {
  86. client_remote_.Bind(std::move(client));
  87. media_log_remote_.Bind(std::move(media_log));
  88. video_frame_handle_releaser_ =
  89. std::make_unique<StrictMock<MockVideoFrameHandleReleaser>>(
  90. std::move(video_frame_handle_releaser));
  91. mojo_decoder_buffer_reader_ = std::make_unique<MojoDecoderBufferReader>(
  92. std::move(decoder_buffer_pipe));
  93. DoConstruct(std::move(command_buffer_id), target_color_space);
  94. }
  95. MOCK_METHOD2(DoConstruct,
  96. void(mojom::CommandBufferIdPtr command_buffer_id,
  97. const gfx::ColorSpace& target_color_space));
  98. MOCK_METHOD4(Initialize,
  99. void(const VideoDecoderConfig& config,
  100. bool low_delay,
  101. const absl::optional<base::UnguessableToken>& cdm_id,
  102. InitializeCallback callback));
  103. MOCK_METHOD2(Decode,
  104. void(mojom::DecoderBufferPtr buffer, DecodeCallback callback));
  105. MOCK_METHOD1(Reset, void(ResetCallback callback));
  106. MOCK_METHOD1(OnOverlayInfoChanged, void(const OverlayInfo& overlay_info));
  107. private:
  108. mojo::AssociatedRemote<mojom::VideoDecoderClient> client_remote_;
  109. mojo::Remote<mojom::MediaLog> media_log_remote_;
  110. std::unique_ptr<StrictMock<MockVideoFrameHandleReleaser>>
  111. video_frame_handle_releaser_;
  112. std::unique_ptr<MojoDecoderBufferReader> mojo_decoder_buffer_reader_;
  113. };
  114. class MockStableVideoDecoderClient : public stable::mojom::VideoDecoderClient {
  115. public:
  116. explicit MockStableVideoDecoderClient(
  117. mojo::PendingAssociatedReceiver<stable::mojom::VideoDecoderClient>
  118. pending_receiver)
  119. : receiver_(this, std::move(pending_receiver)) {}
  120. MockStableVideoDecoderClient(const MockStableVideoDecoderClient&) = delete;
  121. MockStableVideoDecoderClient& operator=(const MockStableVideoDecoderClient&) =
  122. delete;
  123. ~MockStableVideoDecoderClient() override = default;
  124. // stable::mojom::VideoDecoderClient implementation.
  125. MOCK_METHOD3(OnVideoFrameDecoded,
  126. void(const scoped_refptr<VideoFrame>& frame,
  127. bool can_read_without_stalling,
  128. const base::UnguessableToken& release_token));
  129. MOCK_METHOD1(OnWaiting, void(WaitingReason reason));
  130. private:
  131. mojo::AssociatedReceiver<stable::mojom::VideoDecoderClient> receiver_;
  132. };
  133. class MockStableMediaLog : public stable::mojom::MediaLog {
  134. public:
  135. explicit MockStableMediaLog(
  136. mojo::PendingReceiver<stable::mojom::MediaLog> pending_receiver)
  137. : receiver_(this, std::move(pending_receiver)) {}
  138. MockStableMediaLog(const MockStableMediaLog&) = delete;
  139. MockStableMediaLog& operator=(const MockStableMediaLog&) = delete;
  140. ~MockStableMediaLog() override = default;
  141. // stable::mojom::MediaLog implementation.
  142. MOCK_METHOD1(AddLogRecord, void(const MediaLogRecord& event));
  143. private:
  144. mojo::Receiver<stable::mojom::MediaLog> receiver_;
  145. };
  146. // AuxiliaryEndpoints groups the endpoints that support the operation of a
  147. // StableVideoDecoderService and that come from the Construct() call. That way,
  148. // tests can easily poke at one endpoint and set expectations on the other. For
  149. // example, a test might want to simulate the scenario in which a frame has been
  150. // decoded by the underlying mojom::VideoDecoder. In this case, the test can
  151. // call |video_decoder_client_remote|->OnVideoFrameDecoded() and then set an
  152. // expectation on |mock_stable_video_decoder_client|->OnVideoFrameDecoded().
  153. struct AuxiliaryEndpoints {
  154. // |video_decoder_client_remote| is the client that the underlying
  155. // mojom::VideoDecoder receives through the Construct() call. Tests can make
  156. // calls on it and those calls should ultimately be received by the
  157. // |mock_stable_video_decoder_client|.
  158. mojo::AssociatedRemote<mojom::VideoDecoderClient> video_decoder_client_remote;
  159. std::unique_ptr<StrictMock<MockStableVideoDecoderClient>>
  160. mock_stable_video_decoder_client;
  161. // |media_log_remote| is the MediaLog that the underlying mojom::VideoDecoder
  162. // receives through the Construct() call. Tests can make calls on it and those
  163. // calls should ultimately be received by the |mock_stable_media_log|.
  164. mojo::Remote<mojom::MediaLog> media_log_remote;
  165. std::unique_ptr<StrictMock<MockStableMediaLog>> mock_stable_media_log;
  166. // Tests can use |stable_video_frame_handle_releaser_remote| to simulate
  167. // releasing a VideoFrame.
  168. // |mock_video_frame_handle_releaser| is the VideoFrameHandleReleaser that's
  169. // setup when the underlying mojom::VideoDecoder receives a Construct() call.
  170. // Tests can make calls on |stable_video_frame_handle_releaser_remote| and
  171. // they should be ultimately received by the
  172. // |mock_video_frame_handle_releaser|.
  173. mojo::Remote<stable::mojom::VideoFrameHandleReleaser>
  174. stable_video_frame_handle_releaser_remote;
  175. std::unique_ptr<StrictMock<MockVideoFrameHandleReleaser>>
  176. mock_video_frame_handle_releaser;
  177. // |mojo_decoder_buffer_reader| wraps the reading end of the data pipe that
  178. // the underlying mojom::VideoDecoder receives through the Construct() call.
  179. // Tests can write data using the |mojo_decoder_buffer_writer| and that data
  180. // should be ultimately received by the |mojo_decoder_buffer_reader|.
  181. std::unique_ptr<MojoDecoderBufferWriter> mojo_decoder_buffer_writer;
  182. std::unique_ptr<MojoDecoderBufferReader> mojo_decoder_buffer_reader;
  183. };
  184. // Calls Construct() on |stable_video_decoder_remote| and, if
  185. // |expect_construct_call| is true, expects a corresponding Construct() call on
  186. // |mock_video_decoder| which is assumed to be the backing decoder of
  187. // |stable_video_decoder_remote|. Returns nullptr if the expectations on
  188. // |mock_video_decoder| are violated. Otherwise, returns an AuxiliaryEndpoints
  189. // instance that contains the supporting endpoints that tests can use to
  190. // interact with the auxiliary interfaces used by the
  191. // |stable_video_decoder_remote|.
  192. std::unique_ptr<AuxiliaryEndpoints> ConstructStableVideoDecoder(
  193. mojo::Remote<stable::mojom::StableVideoDecoder>&
  194. stable_video_decoder_remote,
  195. StrictMock<MockVideoDecoder>& mock_video_decoder,
  196. bool expect_construct_call) {
  197. constexpr gfx::ColorSpace kTargetColorSpace = gfx::ColorSpace::CreateSRGB();
  198. if (expect_construct_call) {
  199. EXPECT_CALL(mock_video_decoder,
  200. DoConstruct(/*command_buffer_id=*/_,
  201. /*target_color_space=*/kTargetColorSpace));
  202. }
  203. mojo::PendingAssociatedRemote<stable::mojom::VideoDecoderClient>
  204. stable_video_decoder_client_remote;
  205. auto mock_stable_video_decoder_client =
  206. std::make_unique<StrictMock<MockStableVideoDecoderClient>>(
  207. stable_video_decoder_client_remote
  208. .InitWithNewEndpointAndPassReceiver());
  209. mojo::PendingRemote<stable::mojom::MediaLog> stable_media_log_remote;
  210. auto mock_stable_media_log = std::make_unique<StrictMock<MockStableMediaLog>>(
  211. stable_media_log_remote.InitWithNewPipeAndPassReceiver());
  212. mojo::Remote<stable::mojom::VideoFrameHandleReleaser>
  213. video_frame_handle_releaser_remote;
  214. mojo::ScopedDataPipeConsumerHandle remote_consumer_handle;
  215. std::unique_ptr<MojoDecoderBufferWriter> mojo_decoder_buffer_writer =
  216. MojoDecoderBufferWriter::Create(
  217. GetDefaultDecoderBufferConverterCapacity(DemuxerStream::VIDEO),
  218. &remote_consumer_handle);
  219. stable_video_decoder_remote->Construct(
  220. std::move(stable_video_decoder_client_remote),
  221. std::move(stable_media_log_remote),
  222. video_frame_handle_releaser_remote.BindNewPipeAndPassReceiver(),
  223. std::move(remote_consumer_handle), kTargetColorSpace);
  224. stable_video_decoder_remote.FlushForTesting();
  225. if (!Mock::VerifyAndClearExpectations(&mock_video_decoder))
  226. return nullptr;
  227. auto auxiliary_endpoints = std::make_unique<AuxiliaryEndpoints>();
  228. auxiliary_endpoints->video_decoder_client_remote =
  229. mock_video_decoder.TakeClientRemote();
  230. auxiliary_endpoints->mock_stable_video_decoder_client =
  231. std::move(mock_stable_video_decoder_client);
  232. auxiliary_endpoints->media_log_remote =
  233. mock_video_decoder.TakeMediaLogRemote();
  234. auxiliary_endpoints->mock_stable_media_log = std::move(mock_stable_media_log);
  235. auxiliary_endpoints->stable_video_frame_handle_releaser_remote =
  236. std::move(video_frame_handle_releaser_remote);
  237. auxiliary_endpoints->mock_video_frame_handle_releaser =
  238. mock_video_decoder.TakeVideoFrameHandleReleaser();
  239. auxiliary_endpoints->mojo_decoder_buffer_writer =
  240. std::move(mojo_decoder_buffer_writer);
  241. auxiliary_endpoints->mojo_decoder_buffer_reader =
  242. mock_video_decoder.TakeMojoDecoderBufferReader();
  243. return auxiliary_endpoints;
  244. }
  245. class StableVideoDecoderServiceTest : public testing::Test {
  246. public:
  247. StableVideoDecoderServiceTest() {
  248. stable_video_decoder_factory_service_
  249. .SetVideoDecoderCreationCallbackForTesting(
  250. video_decoder_creation_cb_.Get());
  251. }
  252. StableVideoDecoderServiceTest(const StableVideoDecoderServiceTest&) = delete;
  253. StableVideoDecoderServiceTest& operator=(
  254. const StableVideoDecoderServiceTest&) = delete;
  255. ~StableVideoDecoderServiceTest() override = default;
  256. void SetUp() override {
  257. mojo::PendingReceiver<stable::mojom::StableVideoDecoderFactory>
  258. stable_video_decoder_factory_receiver;
  259. stable_video_decoder_factory_remote_ =
  260. mojo::Remote<stable::mojom::StableVideoDecoderFactory>(
  261. stable_video_decoder_factory_receiver
  262. .InitWithNewPipeAndPassRemote());
  263. stable_video_decoder_factory_service_.BindReceiver(
  264. std::move(stable_video_decoder_factory_receiver));
  265. ASSERT_TRUE(stable_video_decoder_factory_remote_.is_connected());
  266. }
  267. protected:
  268. mojo::Remote<stable::mojom::StableVideoDecoder> CreateStableVideoDecoder(
  269. std::unique_ptr<StrictMock<MockVideoDecoder>> dst_video_decoder) {
  270. // Each CreateStableVideoDecoder() should result in exactly one call to the
  271. // video decoder creation callback, i.e., the
  272. // StableVideoDecoderFactoryService should not re-use mojom::VideoDecoder
  273. // implementation instances.
  274. EXPECT_CALL(video_decoder_creation_cb_, Run(_, _))
  275. .WillOnce(Return(ByMove(std::move(dst_video_decoder))));
  276. mojo::PendingReceiver<stable::mojom::StableVideoDecoder>
  277. stable_video_decoder_receiver;
  278. mojo::Remote<stable::mojom::StableVideoDecoder> video_decoder_remote(
  279. stable_video_decoder_receiver.InitWithNewPipeAndPassRemote());
  280. stable_video_decoder_factory_remote_->CreateStableVideoDecoder(
  281. std::move(stable_video_decoder_receiver));
  282. stable_video_decoder_factory_remote_.FlushForTesting();
  283. if (!Mock::VerifyAndClearExpectations(&video_decoder_creation_cb_))
  284. return {};
  285. return video_decoder_remote;
  286. }
  287. base::test::TaskEnvironment task_environment_;
  288. StrictMock<base::MockRepeatingCallback<std::unique_ptr<
  289. mojom::VideoDecoder>(MojoMediaClient*, MojoCdmServiceContext*)>>
  290. video_decoder_creation_cb_;
  291. StableVideoDecoderFactoryService stable_video_decoder_factory_service_;
  292. mojo::Remote<stable::mojom::StableVideoDecoderFactory>
  293. stable_video_decoder_factory_remote_;
  294. mojo::Remote<stable::mojom::StableVideoDecoder> stable_video_decoder_remote_;
  295. };
  296. // Tests that we can create multiple StableVideoDecoder implementation instances
  297. // through the StableVideoDecoderFactory and that they can exist concurrently.
  298. TEST_F(StableVideoDecoderServiceTest, FactoryCanCreateStableVideoDecoders) {
  299. std::vector<mojo::Remote<stable::mojom::StableVideoDecoder>>
  300. stable_video_decoder_remotes;
  301. constexpr size_t kNumConcurrentDecoders = 5u;
  302. for (size_t i = 0u; i < kNumConcurrentDecoders; i++) {
  303. auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
  304. auto stable_video_decoder_remote =
  305. CreateStableVideoDecoder(std::move(mock_video_decoder));
  306. stable_video_decoder_remotes.push_back(
  307. std::move(stable_video_decoder_remote));
  308. }
  309. for (const auto& remote : stable_video_decoder_remotes) {
  310. ASSERT_TRUE(remote.is_bound());
  311. ASSERT_TRUE(remote.is_connected());
  312. }
  313. }
  314. // Tests that a call to stable::mojom::VideoDecoder::Construct() gets routed
  315. // correctly to the underlying mojom::VideoDecoder.
  316. TEST_F(StableVideoDecoderServiceTest, StableVideoDecoderCanBeConstructed) {
  317. auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
  318. auto* mock_video_decoder_raw = mock_video_decoder.get();
  319. auto stable_video_decoder_remote =
  320. CreateStableVideoDecoder(std::move(mock_video_decoder));
  321. ASSERT_TRUE(stable_video_decoder_remote.is_bound());
  322. ASSERT_TRUE(stable_video_decoder_remote.is_connected());
  323. ASSERT_TRUE(ConstructStableVideoDecoder(stable_video_decoder_remote,
  324. *mock_video_decoder_raw,
  325. /*expect_construct_call=*/true));
  326. }
  327. // Tests that if two calls to stable::mojom::VideoDecoder::Construct() are made,
  328. // only one is routed to the underlying mojom::VideoDecoder.
  329. TEST_F(StableVideoDecoderServiceTest,
  330. StableVideoDecoderCannotBeConstructedTwice) {
  331. auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
  332. auto* mock_video_decoder_raw = mock_video_decoder.get();
  333. auto stable_video_decoder_remote =
  334. CreateStableVideoDecoder(std::move(mock_video_decoder));
  335. ASSERT_TRUE(stable_video_decoder_remote.is_bound());
  336. ASSERT_TRUE(stable_video_decoder_remote.is_connected());
  337. EXPECT_TRUE(ConstructStableVideoDecoder(stable_video_decoder_remote,
  338. *mock_video_decoder_raw,
  339. /*expect_construct_call=*/true));
  340. EXPECT_TRUE(ConstructStableVideoDecoder(stable_video_decoder_remote,
  341. *mock_video_decoder_raw,
  342. /*expect_construct_call=*/false));
  343. }
  344. // Tests that a call to stable::mojom::VideoDecoder::GetSupportedConfigs() gets
  345. // routed correctly to the underlying mojom::VideoDecoder. Also tests that the
  346. // underlying mojom::VideoDecoder's reply gets routed correctly back to the
  347. // client.
  348. TEST_F(StableVideoDecoderServiceTest,
  349. StableVideoDecoderCanGetSupportedConfigs) {
  350. auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
  351. auto* mock_video_decoder_raw = mock_video_decoder.get();
  352. auto stable_video_decoder_remote =
  353. CreateStableVideoDecoder(std::move(mock_video_decoder));
  354. ASSERT_TRUE(stable_video_decoder_remote.is_bound());
  355. ASSERT_TRUE(stable_video_decoder_remote.is_connected());
  356. StrictMock<base::MockOnceCallback<void(
  357. const std::vector<SupportedVideoDecoderConfig>& supported_configs,
  358. VideoDecoderType decoder_type)>>
  359. get_supported_configs_cb_to_send;
  360. mojom::VideoDecoder::GetSupportedConfigsCallback
  361. received_get_supported_configs_cb;
  362. constexpr VideoDecoderType kDecoderTypeToReplyWith = VideoDecoderType::kVaapi;
  363. const std::vector<SupportedVideoDecoderConfig>
  364. supported_configs_to_reply_with({
  365. {/*profile_min=*/H264PROFILE_MIN, /*profile_max=*/H264PROFILE_MAX,
  366. /*coded_size_min=*/gfx::Size(320, 180),
  367. /*coded_size_max=*/gfx::Size(1280, 720), /*allow_encrypted=*/false,
  368. /*require_encrypted=*/false},
  369. {/*profile_min=*/VP9PROFILE_MIN, /*profile_max=*/VP9PROFILE_MAX,
  370. /*coded_size_min=*/gfx::Size(8, 8),
  371. /*coded_size_max=*/gfx::Size(640, 360), /*allow_encrypted=*/true,
  372. /*require_encrypted=*/true},
  373. });
  374. std::vector<SupportedVideoDecoderConfig> received_supported_configs;
  375. EXPECT_CALL(*mock_video_decoder_raw, GetSupportedConfigs(/*callback=*/_))
  376. .WillOnce([&](mojom::VideoDecoder::GetSupportedConfigsCallback callback) {
  377. received_get_supported_configs_cb = std::move(callback);
  378. });
  379. EXPECT_CALL(get_supported_configs_cb_to_send, Run(_, kDecoderTypeToReplyWith))
  380. .WillOnce(SaveArg<0>(&received_supported_configs));
  381. stable_video_decoder_remote->GetSupportedConfigs(
  382. get_supported_configs_cb_to_send.Get());
  383. stable_video_decoder_remote.FlushForTesting();
  384. ASSERT_TRUE(Mock::VerifyAndClearExpectations(mock_video_decoder_raw));
  385. std::move(received_get_supported_configs_cb)
  386. .Run(supported_configs_to_reply_with, kDecoderTypeToReplyWith);
  387. task_environment_.RunUntilIdle();
  388. EXPECT_EQ(received_supported_configs, supported_configs_to_reply_with);
  389. }
  390. // Tests that a call to stable::mojom::VideoDecoder::Initialize() gets routed
  391. // correctly to the underlying mojom::VideoDecoder. Also tests that when the
  392. // underlying mojom::VideoDecoder calls the initialization callback, the call
  393. // gets routed to the client.
  394. TEST_F(StableVideoDecoderServiceTest, StableVideoDecoderCanBeInitialized) {
  395. auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
  396. auto* mock_video_decoder_raw = mock_video_decoder.get();
  397. auto stable_video_decoder_remote =
  398. CreateStableVideoDecoder(std::move(mock_video_decoder));
  399. ASSERT_TRUE(stable_video_decoder_remote.is_bound());
  400. ASSERT_TRUE(stable_video_decoder_remote.is_connected());
  401. auto auxiliary_endpoints = ConstructStableVideoDecoder(
  402. stable_video_decoder_remote, *mock_video_decoder_raw,
  403. /*expect_construct_call=*/true);
  404. ASSERT_TRUE(auxiliary_endpoints);
  405. const VideoDecoderConfig config_to_send = CreateValidVideoDecoderConfig();
  406. VideoDecoderConfig received_config;
  407. constexpr bool kLowDelay = true;
  408. constexpr absl::optional<base::UnguessableToken> kCdmId = absl::nullopt;
  409. StrictMock<base::MockOnceCallback<void(
  410. const media::DecoderStatus& status, bool needs_bitstream_conversion,
  411. int32_t max_decode_requests, VideoDecoderType decoder_type)>>
  412. initialize_cb_to_send;
  413. mojom::VideoDecoder::InitializeCallback received_initialize_cb;
  414. const DecoderStatus kDecoderStatus = DecoderStatus::Codes::kAborted;
  415. constexpr bool kNeedsBitstreamConversion = true;
  416. constexpr int32_t kMaxDecodeRequests = 123;
  417. constexpr VideoDecoderType kDecoderType = VideoDecoderType::kVda;
  418. EXPECT_CALL(*mock_video_decoder_raw,
  419. Initialize(/*config=*/_, kLowDelay, kCdmId,
  420. /*callback=*/_))
  421. .WillOnce([&](const VideoDecoderConfig& config, bool low_delay,
  422. const absl::optional<base::UnguessableToken>& cdm_id,
  423. mojom::VideoDecoder::InitializeCallback callback) {
  424. received_config = config;
  425. received_initialize_cb = std::move(callback);
  426. });
  427. EXPECT_CALL(initialize_cb_to_send,
  428. Run(kDecoderStatus, kNeedsBitstreamConversion, kMaxDecodeRequests,
  429. kDecoderType));
  430. stable_video_decoder_remote->Initialize(
  431. config_to_send, kLowDelay,
  432. mojo::PendingRemote<stable::mojom::StableCdmContext>(),
  433. initialize_cb_to_send.Get());
  434. stable_video_decoder_remote.FlushForTesting();
  435. ASSERT_TRUE(Mock::VerifyAndClearExpectations(mock_video_decoder_raw));
  436. std::move(received_initialize_cb)
  437. .Run(kDecoderStatus, kNeedsBitstreamConversion, kMaxDecodeRequests,
  438. kDecoderType);
  439. task_environment_.RunUntilIdle();
  440. }
  441. // Tests that the StableVideoDecoderService rejects a call to
  442. // stable::mojom::VideoDecoder::Initialize() before
  443. // stable::mojom::VideoDecoder::Construct() gets called.
  444. TEST_F(StableVideoDecoderServiceTest,
  445. StableVideoDecoderCannotBeInitializedBeforeConstruction) {
  446. auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
  447. auto stable_video_decoder_remote =
  448. CreateStableVideoDecoder(std::move(mock_video_decoder));
  449. ASSERT_TRUE(stable_video_decoder_remote.is_bound());
  450. ASSERT_TRUE(stable_video_decoder_remote.is_connected());
  451. const VideoDecoderConfig config_to_send = CreateValidVideoDecoderConfig();
  452. constexpr bool kLowDelay = true;
  453. StrictMock<base::MockOnceCallback<void(
  454. const media::DecoderStatus& status, bool needs_bitstream_conversion,
  455. int32_t max_decode_requests, VideoDecoderType decoder_type)>>
  456. initialize_cb_to_send;
  457. EXPECT_CALL(initialize_cb_to_send,
  458. Run(DecoderStatus(DecoderStatus::Codes::kFailed),
  459. /*needs_bitstream_conversion=*/false,
  460. /*max_decode_requests=*/1, VideoDecoderType::kUnknown));
  461. stable_video_decoder_remote->Initialize(
  462. config_to_send, kLowDelay,
  463. mojo::PendingRemote<stable::mojom::StableCdmContext>(),
  464. initialize_cb_to_send.Get());
  465. stable_video_decoder_remote.FlushForTesting();
  466. }
  467. // Tests that a call to stable::mojom::VideoDecoder::Decode() gets routed
  468. // correctly to the underlying mojom::VideoDecoder and that the data pipe is
  469. // plumbed correctly. Also tests that when the underlying mojom::VideoDecoder
  470. // calls the decode callback, the call gets routed to the client.
  471. TEST_F(StableVideoDecoderServiceTest, StableVideoDecoderCanDecode) {
  472. auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
  473. auto* mock_video_decoder_raw = mock_video_decoder.get();
  474. auto stable_video_decoder_remote =
  475. CreateStableVideoDecoder(std::move(mock_video_decoder));
  476. ASSERT_TRUE(stable_video_decoder_remote.is_bound());
  477. ASSERT_TRUE(stable_video_decoder_remote.is_connected());
  478. auto auxiliary_endpoints = ConstructStableVideoDecoder(
  479. stable_video_decoder_remote, *mock_video_decoder_raw,
  480. /*expect_construct_call=*/true);
  481. ASSERT_TRUE(auxiliary_endpoints);
  482. ASSERT_TRUE(auxiliary_endpoints->mojo_decoder_buffer_writer);
  483. ASSERT_TRUE(auxiliary_endpoints->mojo_decoder_buffer_reader);
  484. constexpr uint8_t kEncodedData[] = {1, 2, 3};
  485. constexpr uint8_t kSideData[] = {5, 6, 7, 8};
  486. scoped_refptr<DecoderBuffer> decoder_buffer_to_send = DecoderBuffer::CopyFrom(
  487. kEncodedData, std::size(kEncodedData), kSideData, std::size(kSideData));
  488. ASSERT_TRUE(decoder_buffer_to_send);
  489. mojom::DecoderBufferPtr received_decoder_buffer_ptr;
  490. scoped_refptr<DecoderBuffer> received_decoder_buffer;
  491. StrictMock<base::MockOnceCallback<void(const media::DecoderStatus& status)>>
  492. decode_cb_to_send;
  493. mojom::VideoDecoder::DecodeCallback received_decode_cb;
  494. const DecoderStatus kDecoderStatus = DecoderStatus::Codes::kAborted;
  495. EXPECT_CALL(*mock_video_decoder_raw, Decode(/*buffer=*/_, /*callback=*/_))
  496. .WillOnce([&](mojom::DecoderBufferPtr buffer,
  497. mojom::VideoDecoder::DecodeCallback callback) {
  498. received_decoder_buffer_ptr = std::move(buffer);
  499. received_decode_cb = std::move(callback);
  500. });
  501. EXPECT_CALL(decode_cb_to_send, Run(kDecoderStatus));
  502. ASSERT_TRUE(
  503. auxiliary_endpoints->mojo_decoder_buffer_writer->WriteDecoderBuffer(
  504. decoder_buffer_to_send));
  505. stable_video_decoder_remote->Decode(decoder_buffer_to_send,
  506. decode_cb_to_send.Get());
  507. stable_video_decoder_remote.FlushForTesting();
  508. ASSERT_TRUE(Mock::VerifyAndClearExpectations(mock_video_decoder_raw));
  509. ASSERT_TRUE(received_decoder_buffer_ptr);
  510. auxiliary_endpoints->mojo_decoder_buffer_reader->ReadDecoderBuffer(
  511. std::move(received_decoder_buffer_ptr),
  512. base::BindOnce(
  513. [](scoped_refptr<DecoderBuffer>* dst_buffer,
  514. scoped_refptr<DecoderBuffer> buffer) {
  515. *dst_buffer = std::move(buffer);
  516. },
  517. &received_decoder_buffer));
  518. task_environment_.RunUntilIdle();
  519. ASSERT_TRUE(received_decoder_buffer);
  520. EXPECT_TRUE(
  521. received_decoder_buffer->MatchesForTesting(*decoder_buffer_to_send));
  522. std::move(received_decode_cb).Run(kDecoderStatus);
  523. task_environment_.RunUntilIdle();
  524. }
  525. // Tests that the StableVideoDecoderService rejects a call to
  526. // stable::mojom::VideoDecoder::Decode() before
  527. // stable::mojom::VideoDecoder::Construct() gets called.
  528. TEST_F(StableVideoDecoderServiceTest,
  529. StableVideoDecoderCannotDecodeBeforeConstruction) {
  530. auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
  531. auto stable_video_decoder_remote =
  532. CreateStableVideoDecoder(std::move(mock_video_decoder));
  533. ASSERT_TRUE(stable_video_decoder_remote.is_bound());
  534. ASSERT_TRUE(stable_video_decoder_remote.is_connected());
  535. constexpr uint8_t kEncodedData[] = {1, 2, 3};
  536. constexpr uint8_t kSideData[] = {5, 6, 7, 8};
  537. scoped_refptr<DecoderBuffer> decoder_buffer_to_send = DecoderBuffer::CopyFrom(
  538. kEncodedData, std::size(kEncodedData), kSideData, std::size(kSideData));
  539. ASSERT_TRUE(decoder_buffer_to_send);
  540. StrictMock<base::MockOnceCallback<void(const media::DecoderStatus& status)>>
  541. decode_cb_to_send;
  542. EXPECT_CALL(decode_cb_to_send,
  543. Run(DecoderStatus(DecoderStatus::Codes::kFailed)));
  544. stable_video_decoder_remote->Decode(decoder_buffer_to_send,
  545. decode_cb_to_send.Get());
  546. stable_video_decoder_remote.FlushForTesting();
  547. }
  548. // Tests that a call to stable::mojom::VideoDecoder::Reset() gets routed
  549. // correctly to the underlying mojom::VideoDecoder. Also tests that when the
  550. // underlying mojom::VideoDecoder calls the reset callback, the call gets routed
  551. // to the client.
  552. TEST_F(StableVideoDecoderServiceTest, StableVideoDecoderCanBeReset) {
  553. auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
  554. auto* mock_video_decoder_raw = mock_video_decoder.get();
  555. auto stable_video_decoder_remote =
  556. CreateStableVideoDecoder(std::move(mock_video_decoder));
  557. ASSERT_TRUE(stable_video_decoder_remote.is_bound());
  558. ASSERT_TRUE(stable_video_decoder_remote.is_connected());
  559. auto auxiliary_endpoints = ConstructStableVideoDecoder(
  560. stable_video_decoder_remote, *mock_video_decoder_raw,
  561. /*expect_construct_call=*/true);
  562. ASSERT_TRUE(auxiliary_endpoints);
  563. StrictMock<base::MockOnceCallback<void()>> reset_cb_to_send;
  564. mojom::VideoDecoder::ResetCallback received_reset_cb;
  565. EXPECT_CALL(*mock_video_decoder_raw, Reset(/*callback=*/_))
  566. .WillOnce([&](mojom::VideoDecoder::ResetCallback callback) {
  567. received_reset_cb = std::move(callback);
  568. });
  569. EXPECT_CALL(reset_cb_to_send, Run());
  570. stable_video_decoder_remote->Reset(reset_cb_to_send.Get());
  571. stable_video_decoder_remote.FlushForTesting();
  572. ASSERT_TRUE(Mock::VerifyAndClearExpectations(mock_video_decoder_raw));
  573. std::move(received_reset_cb).Run();
  574. task_environment_.RunUntilIdle();
  575. }
  576. // Tests that the StableVideoDecoderService doesn't route a
  577. // stable::mojom::VideoDecoder::Reset() call to the underlying
  578. // mojom::VideoDecoder before stable::mojom::VideoDecoder::Construct() gets
  579. // called and that it just calls the reset callback.
  580. TEST_F(StableVideoDecoderServiceTest,
  581. StableVideoDecoderCannotBeResetBeforeConstruction) {
  582. auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
  583. auto stable_video_decoder_remote =
  584. CreateStableVideoDecoder(std::move(mock_video_decoder));
  585. ASSERT_TRUE(stable_video_decoder_remote.is_bound());
  586. ASSERT_TRUE(stable_video_decoder_remote.is_connected());
  587. StrictMock<base::MockOnceCallback<void()>> reset_cb_to_send;
  588. EXPECT_CALL(reset_cb_to_send, Run());
  589. stable_video_decoder_remote->Reset(reset_cb_to_send.Get());
  590. stable_video_decoder_remote.FlushForTesting();
  591. }
  592. // Tests that a call to
  593. // stable::mojom::VideoFrameHandleReleaser::ReleaseVideoFrame() gets routed
  594. // correctly to the underlying mojom::VideoFrameHandleReleaser.
  595. TEST_F(StableVideoDecoderServiceTest, VideoFramesCanBeReleased) {
  596. auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
  597. auto* mock_video_decoder_raw = mock_video_decoder.get();
  598. auto stable_video_decoder_remote =
  599. CreateStableVideoDecoder(std::move(mock_video_decoder));
  600. ASSERT_TRUE(stable_video_decoder_remote.is_bound());
  601. ASSERT_TRUE(stable_video_decoder_remote.is_connected());
  602. auto auxiliary_endpoints = ConstructStableVideoDecoder(
  603. stable_video_decoder_remote, *mock_video_decoder_raw,
  604. /*expect_construct_call=*/true);
  605. ASSERT_TRUE(auxiliary_endpoints);
  606. ASSERT_TRUE(auxiliary_endpoints->stable_video_frame_handle_releaser_remote);
  607. ASSERT_TRUE(auxiliary_endpoints->mock_video_frame_handle_releaser);
  608. const base::UnguessableToken release_token_to_send =
  609. base::UnguessableToken::Create();
  610. const absl::optional<gpu::SyncToken> expected_release_sync_token =
  611. absl::nullopt;
  612. EXPECT_CALL(
  613. *auxiliary_endpoints->mock_video_frame_handle_releaser,
  614. ReleaseVideoFrame(release_token_to_send, expected_release_sync_token));
  615. auxiliary_endpoints->stable_video_frame_handle_releaser_remote
  616. ->ReleaseVideoFrame(release_token_to_send);
  617. auxiliary_endpoints->stable_video_frame_handle_releaser_remote
  618. .FlushForTesting();
  619. }
  620. TEST_F(StableVideoDecoderServiceTest,
  621. StableVideoDecoderClientReceivesOnVideoFrameDecodedEvent) {
  622. auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
  623. auto* mock_video_decoder_raw = mock_video_decoder.get();
  624. auto stable_video_decoder_remote =
  625. CreateStableVideoDecoder(std::move(mock_video_decoder));
  626. ASSERT_TRUE(stable_video_decoder_remote.is_bound());
  627. ASSERT_TRUE(stable_video_decoder_remote.is_connected());
  628. auto auxiliary_endpoints = ConstructStableVideoDecoder(
  629. stable_video_decoder_remote, *mock_video_decoder_raw,
  630. /*expect_construct_call=*/true);
  631. ASSERT_TRUE(auxiliary_endpoints);
  632. ASSERT_TRUE(auxiliary_endpoints->video_decoder_client_remote);
  633. ASSERT_TRUE(auxiliary_endpoints->mock_stable_video_decoder_client);
  634. const auto token_for_release = base::UnguessableToken::Create();
  635. scoped_refptr<VideoFrame> video_frame_to_send = VideoFrame::CreateEOSFrame();
  636. scoped_refptr<VideoFrame> video_frame_received;
  637. constexpr bool kCanReadWithoutStalling = true;
  638. EXPECT_CALL(
  639. *auxiliary_endpoints->mock_stable_video_decoder_client,
  640. OnVideoFrameDecoded(_, kCanReadWithoutStalling, token_for_release))
  641. .WillOnce(SaveArg<0>(&video_frame_received));
  642. auxiliary_endpoints->video_decoder_client_remote->OnVideoFrameDecoded(
  643. video_frame_to_send, kCanReadWithoutStalling, token_for_release);
  644. auxiliary_endpoints->video_decoder_client_remote.FlushForTesting();
  645. ASSERT_TRUE(video_frame_received);
  646. EXPECT_TRUE(video_frame_received->metadata().end_of_stream);
  647. }
  648. // Tests that a mojom::VideoDecoderClient::OnWaiting() call originating from the
  649. // underlying mojom::VideoDecoder gets forwarded to the
  650. // stable::mojom::VideoDecoderClient correctly.
  651. TEST_F(StableVideoDecoderServiceTest,
  652. StableVideoDecoderClientReceivesOnWaitingEvent) {
  653. auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
  654. auto* mock_video_decoder_raw = mock_video_decoder.get();
  655. auto stable_video_decoder_remote =
  656. CreateStableVideoDecoder(std::move(mock_video_decoder));
  657. ASSERT_TRUE(stable_video_decoder_remote.is_bound());
  658. ASSERT_TRUE(stable_video_decoder_remote.is_connected());
  659. auto auxiliary_endpoints = ConstructStableVideoDecoder(
  660. stable_video_decoder_remote, *mock_video_decoder_raw,
  661. /*expect_construct_call=*/true);
  662. ASSERT_TRUE(auxiliary_endpoints);
  663. ASSERT_TRUE(auxiliary_endpoints->video_decoder_client_remote);
  664. ASSERT_TRUE(auxiliary_endpoints->mock_stable_video_decoder_client);
  665. constexpr WaitingReason kWaitingReason = WaitingReason::kNoDecryptionKey;
  666. EXPECT_CALL(*auxiliary_endpoints->mock_stable_video_decoder_client,
  667. OnWaiting(kWaitingReason));
  668. auxiliary_endpoints->video_decoder_client_remote->OnWaiting(kWaitingReason);
  669. auxiliary_endpoints->video_decoder_client_remote.FlushForTesting();
  670. }
  671. // Tests that a mojom::MediaLog::AddLogRecord() call originating from the
  672. // underlying mojom::VideoDecoder gets forwarded to the stable::mojom::MediaLog
  673. // correctly.
  674. TEST_F(StableVideoDecoderServiceTest,
  675. StableVideoDecoderClientReceivesAddLogRecordEvent) {
  676. auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
  677. auto* mock_video_decoder_raw = mock_video_decoder.get();
  678. auto stable_video_decoder_remote =
  679. CreateStableVideoDecoder(std::move(mock_video_decoder));
  680. ASSERT_TRUE(stable_video_decoder_remote.is_bound());
  681. ASSERT_TRUE(stable_video_decoder_remote.is_connected());
  682. auto auxiliary_endpoints = ConstructStableVideoDecoder(
  683. stable_video_decoder_remote, *mock_video_decoder_raw,
  684. /*expect_construct_call=*/true);
  685. ASSERT_TRUE(auxiliary_endpoints);
  686. ASSERT_TRUE(auxiliary_endpoints->media_log_remote);
  687. ASSERT_TRUE(auxiliary_endpoints->mock_stable_media_log);
  688. MediaLogRecord media_log_record_to_send;
  689. media_log_record_to_send.id = 2;
  690. media_log_record_to_send.type = MediaLogRecord::Type::kMediaStatus;
  691. media_log_record_to_send.params.SetStringKey("Test", "Value");
  692. media_log_record_to_send.time = base::TimeTicks::Now();
  693. EXPECT_CALL(*auxiliary_endpoints->mock_stable_media_log,
  694. AddLogRecord(media_log_record_to_send));
  695. auxiliary_endpoints->media_log_remote->AddLogRecord(media_log_record_to_send);
  696. auxiliary_endpoints->media_log_remote.FlushForTesting();
  697. }
  698. } // namespace
  699. } // namespace media