1 /*
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/desktop_capture/blank_detector_desktop_capturer_wrapper.h"
12
13 #include <memory>
14 #include <utility>
15
16 #include "modules/desktop_capture/desktop_capturer.h"
17 #include "modules/desktop_capture/desktop_frame.h"
18 #include "modules/desktop_capture/desktop_frame_generator.h"
19 #include "modules/desktop_capture/desktop_geometry.h"
20 #include "modules/desktop_capture/desktop_region.h"
21 #include "modules/desktop_capture/fake_desktop_capturer.h"
22 #include "test/gtest.h"
23
24 namespace webrtc {
25
26 class BlankDetectorDesktopCapturerWrapperTest
27 : public ::testing::Test,
28 public DesktopCapturer::Callback {
29 public:
30 BlankDetectorDesktopCapturerWrapperTest();
31 ~BlankDetectorDesktopCapturerWrapperTest() override;
32
33 protected:
34 void PerfTest(DesktopCapturer* capturer);
35
36 const int frame_width_ = 1024;
37 const int frame_height_ = 768;
38 std::unique_ptr<BlankDetectorDesktopCapturerWrapper> wrapper_;
39 DesktopCapturer* capturer_ = nullptr;
40 BlackWhiteDesktopFramePainter painter_;
41 int num_frames_captured_ = 0;
42 DesktopCapturer::Result last_result_ = DesktopCapturer::Result::SUCCESS;
43 std::unique_ptr<DesktopFrame> last_frame_;
44
45 private:
46 // DesktopCapturer::Callback interface.
47 void OnCaptureResult(DesktopCapturer::Result result,
48 std::unique_ptr<DesktopFrame> frame) override;
49
50 PainterDesktopFrameGenerator frame_generator_;
51 };
52
53 BlankDetectorDesktopCapturerWrapperTest::
BlankDetectorDesktopCapturerWrapperTest()54 BlankDetectorDesktopCapturerWrapperTest() {
55 frame_generator_.size()->set(frame_width_, frame_height_);
56 frame_generator_.set_desktop_frame_painter(&painter_);
57 std::unique_ptr<DesktopCapturer> capturer(new FakeDesktopCapturer());
58 FakeDesktopCapturer* fake_capturer =
59 static_cast<FakeDesktopCapturer*>(capturer.get());
60 fake_capturer->set_frame_generator(&frame_generator_);
61 capturer_ = fake_capturer;
62 wrapper_.reset(new BlankDetectorDesktopCapturerWrapper(
63 std::move(capturer), RgbaColor(0, 0, 0, 0)));
64 wrapper_->Start(this);
65 }
66
67 BlankDetectorDesktopCapturerWrapperTest::
68 ~BlankDetectorDesktopCapturerWrapperTest() = default;
69
OnCaptureResult(DesktopCapturer::Result result,std::unique_ptr<DesktopFrame> frame)70 void BlankDetectorDesktopCapturerWrapperTest::OnCaptureResult(
71 DesktopCapturer::Result result,
72 std::unique_ptr<DesktopFrame> frame) {
73 last_result_ = result;
74 last_frame_ = std::move(frame);
75 num_frames_captured_++;
76 }
77
PerfTest(DesktopCapturer * capturer)78 void BlankDetectorDesktopCapturerWrapperTest::PerfTest(
79 DesktopCapturer* capturer) {
80 for (int i = 0; i < 10000; i++) {
81 capturer->CaptureFrame();
82 ASSERT_EQ(num_frames_captured_, i + 1);
83 }
84 }
85
TEST_F(BlankDetectorDesktopCapturerWrapperTest,ShouldDetectBlankFrame)86 TEST_F(BlankDetectorDesktopCapturerWrapperTest, ShouldDetectBlankFrame) {
87 wrapper_->CaptureFrame();
88 ASSERT_EQ(num_frames_captured_, 1);
89 ASSERT_EQ(last_result_, DesktopCapturer::Result::ERROR_TEMPORARY);
90 ASSERT_FALSE(last_frame_);
91 }
92
TEST_F(BlankDetectorDesktopCapturerWrapperTest,ShouldPassBlankDetection)93 TEST_F(BlankDetectorDesktopCapturerWrapperTest, ShouldPassBlankDetection) {
94 painter_.updated_region()->AddRect(DesktopRect::MakeXYWH(0, 0, 100, 100));
95 wrapper_->CaptureFrame();
96 ASSERT_EQ(num_frames_captured_, 1);
97 ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS);
98 ASSERT_TRUE(last_frame_);
99
100 painter_.updated_region()->AddRect(
101 DesktopRect::MakeXYWH(frame_width_ - 100, frame_height_ - 100, 100, 100));
102 wrapper_->CaptureFrame();
103 ASSERT_EQ(num_frames_captured_, 2);
104 ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS);
105 ASSERT_TRUE(last_frame_);
106
107 painter_.updated_region()->AddRect(
108 DesktopRect::MakeXYWH(0, frame_height_ - 100, 100, 100));
109 wrapper_->CaptureFrame();
110 ASSERT_EQ(num_frames_captured_, 3);
111 ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS);
112 ASSERT_TRUE(last_frame_);
113
114 painter_.updated_region()->AddRect(
115 DesktopRect::MakeXYWH(frame_width_ - 100, 0, 100, 100));
116 wrapper_->CaptureFrame();
117 ASSERT_EQ(num_frames_captured_, 4);
118 ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS);
119 ASSERT_TRUE(last_frame_);
120
121 painter_.updated_region()->AddRect(DesktopRect::MakeXYWH(
122 (frame_width_ >> 1) - 50, (frame_height_ >> 1) - 50, 100, 100));
123 wrapper_->CaptureFrame();
124 ASSERT_EQ(num_frames_captured_, 5);
125 ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS);
126 ASSERT_TRUE(last_frame_);
127 }
128
TEST_F(BlankDetectorDesktopCapturerWrapperTest,ShouldNotCheckAfterANonBlankFrameReceived)129 TEST_F(BlankDetectorDesktopCapturerWrapperTest,
130 ShouldNotCheckAfterANonBlankFrameReceived) {
131 wrapper_->CaptureFrame();
132 ASSERT_EQ(num_frames_captured_, 1);
133 ASSERT_EQ(last_result_, DesktopCapturer::Result::ERROR_TEMPORARY);
134 ASSERT_FALSE(last_frame_);
135
136 painter_.updated_region()->AddRect(
137 DesktopRect::MakeXYWH(frame_width_ - 100, 0, 100, 100));
138 wrapper_->CaptureFrame();
139 ASSERT_EQ(num_frames_captured_, 2);
140 ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS);
141 ASSERT_TRUE(last_frame_);
142
143 for (int i = 0; i < 100; i++) {
144 wrapper_->CaptureFrame();
145 ASSERT_EQ(num_frames_captured_, i + 3);
146 ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS);
147 ASSERT_TRUE(last_frame_);
148 }
149 }
150
151 // There is no perceptible impact by using BlankDetectorDesktopCapturerWrapper.
152 // i.e. less than 0.2ms per frame.
153 // [ OK ] DISABLED_Performance (10210 ms)
154 // [ OK ] DISABLED_PerformanceComparison (8791 ms)
TEST_F(BlankDetectorDesktopCapturerWrapperTest,DISABLED_Performance)155 TEST_F(BlankDetectorDesktopCapturerWrapperTest, DISABLED_Performance) {
156 PerfTest(wrapper_.get());
157 }
158
TEST_F(BlankDetectorDesktopCapturerWrapperTest,DISABLED_PerformanceComparison)159 TEST_F(BlankDetectorDesktopCapturerWrapperTest,
160 DISABLED_PerformanceComparison) {
161 capturer_->Start(this);
162 PerfTest(capturer_);
163 }
164
165 } // namespace webrtc
166