video_capture_client_unittest.cc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // Copyright 2018 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 "components/mirroring/service/video_capture_client.h"
  5. #include "base/bind.h"
  6. #include "base/memory/read_only_shared_memory_region.h"
  7. #include "base/memory/unsafe_shared_memory_region.h"
  8. #include "base/run_loop.h"
  9. #include "base/test/mock_callback.h"
  10. #include "base/test/task_environment.h"
  11. #include "components/mirroring/service/fake_video_capture_host.h"
  12. #include "media/base/video_frame.h"
  13. #include "media/base/video_frame_metadata.h"
  14. #include "media/capture/mojom/video_capture_buffer.mojom.h"
  15. #include "media/capture/mojom/video_capture_types.mojom.h"
  16. #include "mojo/public/cpp/bindings/pending_remote.h"
  17. #include "testing/gmock/include/gmock/gmock.h"
  18. #include "testing/gtest/include/gtest/gtest.h"
  19. using ::testing::InvokeWithoutArgs;
  20. using ::testing::_;
  21. namespace mirroring {
  22. namespace {
  23. const media::VideoCaptureFeedback kFeedback(0.6, 30.0, 1000);
  24. constexpr bool kNotPremapped = false;
  25. media::mojom::VideoFrameInfoPtr GetVideoFrameInfo(const gfx::Size& size) {
  26. media::VideoFrameMetadata metadata;
  27. metadata.frame_rate = 30;
  28. metadata.reference_time = base::TimeTicks();
  29. return media::mojom::VideoFrameInfo::New(
  30. base::TimeDelta(), metadata, media::PIXEL_FORMAT_I420, size,
  31. gfx::Rect(size), kNotPremapped, gfx::ColorSpace::CreateREC709(), nullptr);
  32. }
  33. } // namespace
  34. class VideoCaptureClientTest : public ::testing::Test,
  35. public ::testing::WithParamInterface<bool> {
  36. public:
  37. VideoCaptureClientTest() {
  38. mojo::PendingRemote<media::mojom::VideoCaptureHost> host;
  39. host_impl_ = std::make_unique<FakeVideoCaptureHost>(
  40. host.InitWithNewPipeAndPassReceiver());
  41. client_ = std::make_unique<VideoCaptureClient>(media::VideoCaptureParams(),
  42. std::move(host));
  43. }
  44. VideoCaptureClientTest(const VideoCaptureClientTest&) = delete;
  45. VideoCaptureClientTest& operator=(const VideoCaptureClientTest&) = delete;
  46. ~VideoCaptureClientTest() override {
  47. if (client_) {
  48. base::RunLoop run_loop;
  49. EXPECT_CALL(*host_impl_, OnStopped())
  50. .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
  51. client_->Stop();
  52. run_loop.Run();
  53. }
  54. task_environment_.RunUntilIdle();
  55. }
  56. MOCK_METHOD1(OnFrameReceived, void(const gfx::Size&));
  57. void OnFrameReady(scoped_refptr<media::VideoFrame> video_frame) {
  58. client_->ProcessFeedback(kFeedback);
  59. OnFrameReceived(video_frame->coded_size());
  60. }
  61. protected:
  62. void StartCapturing() {
  63. EXPECT_CALL(error_cb_, Run()).Times(0);
  64. base::RunLoop run_loop;
  65. // Expect to call RequestRefreshFrame() after capturing started.
  66. EXPECT_CALL(*host_impl_, RequestRefreshFrame(_))
  67. .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
  68. client_->Start(base::BindRepeating(&VideoCaptureClientTest::OnFrameReady,
  69. base::Unretained(this)),
  70. error_cb_.Get());
  71. run_loop.Run();
  72. task_environment_.RunUntilIdle();
  73. }
  74. void OnNewBuffer(int buffer_id, int buffer_size) {
  75. EXPECT_CALL(error_cb_, Run()).Times(0);
  76. const bool use_shared_buffer = GetParam();
  77. if (use_shared_buffer) {
  78. client_->OnNewBuffer(
  79. buffer_id, media::mojom::VideoBufferHandle::NewUnsafeShmemRegion(
  80. base::UnsafeSharedMemoryRegion::Create(buffer_size)));
  81. } else {
  82. client_->OnNewBuffer(
  83. buffer_id,
  84. media::mojom::VideoBufferHandle::NewReadOnlyShmemRegion(
  85. base::ReadOnlySharedMemoryRegion::Create(buffer_size).region));
  86. }
  87. task_environment_.RunUntilIdle();
  88. }
  89. void OnBufferReady(int buffer_id, const gfx::Size& frame_size) {
  90. EXPECT_CALL(error_cb_, Run()).Times(0);
  91. base::RunLoop run_loop;
  92. // Expects to receive one frame.
  93. EXPECT_CALL(*this, OnFrameReceived(frame_size)).Times(1);
  94. // Expects to return the buffer after the frame is consumed.
  95. EXPECT_CALL(*host_impl_, ReleaseBuffer(_, 0, kFeedback))
  96. .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
  97. client_->OnBufferReady(media::mojom::ReadyBuffer::New(
  98. buffer_id, GetVideoFrameInfo(frame_size)),
  99. {});
  100. run_loop.Run();
  101. task_environment_.RunUntilIdle();
  102. }
  103. private:
  104. base::test::TaskEnvironment task_environment_;
  105. base::MockCallback<base::OnceClosure> error_cb_;
  106. std::unique_ptr<FakeVideoCaptureHost> host_impl_;
  107. std::unique_ptr<VideoCaptureClient> client_;
  108. };
  109. TEST_P(VideoCaptureClientTest, Basic) {
  110. StartCapturing();
  111. // A new buffer is created.
  112. OnNewBuffer(0, 100000);
  113. // One captured frame is ready. Expects to receive the frame.
  114. OnBufferReady(0, gfx::Size(126, 64));
  115. // A smaller size video frame is received in the same buffer.
  116. OnBufferReady(0, gfx::Size(64, 32));
  117. // A larger size video frame is received in the same buffer.
  118. OnBufferReady(0, gfx::Size(320, 180));
  119. }
  120. INSTANTIATE_TEST_SUITE_P(All,
  121. VideoCaptureClientTest,
  122. ::testing::Values(true, false));
  123. } // namespace mirroring