OLD | NEW |
---|---|
(Empty) | |
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 "webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper .h" | |
12 | |
13 #include <algorithm> | |
14 #include <utility> | |
15 | |
16 #include "webrtc/base/checks.h" | |
17 #include "webrtc/modules/desktop_capture/desktop_geometry.h" | |
18 #include "webrtc/system_wrappers/include/metrics.h" | |
19 | |
20 namespace webrtc { | |
21 | |
22 BlankDetectorDesktopCapturerWrapper::BlankDetectorDesktopCapturerWrapper( | |
23 std::unique_ptr<DesktopCapturer> capturer, | |
24 RgbaColor blank_pixel, | |
25 int permanent_failure_threshold) | |
26 : capturer_(std::move(capturer)), | |
27 blank_pixel_(blank_pixel), | |
28 permanent_failure_threshold_(permanent_failure_threshold) { | |
29 RTC_DCHECK(capturer_); | |
30 } | |
31 | |
32 BlankDetectorDesktopCapturerWrapper::~BlankDetectorDesktopCapturerWrapper() = | |
33 default; | |
34 | |
35 void BlankDetectorDesktopCapturerWrapper::Start( | |
36 DesktopCapturer::Callback* callback) { | |
37 capturer_->Start(this); | |
38 callback_ = callback; | |
39 } | |
40 | |
41 void BlankDetectorDesktopCapturerWrapper::SetSharedMemoryFactory( | |
42 std::unique_ptr<SharedMemoryFactory> shared_memory_factory) { | |
43 capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory)); | |
44 } | |
45 | |
46 void BlankDetectorDesktopCapturerWrapper::CaptureFrame() { | |
47 RTC_DCHECK(callback_); | |
48 capturer_->CaptureFrame(); | |
Sergey Ulanov
2017/03/01 22:18:32
Maybe check permanent_failure_reached() here inste
Hzj_jie
2017/03/01 23:31:37
Done.
| |
49 } | |
50 | |
51 void BlankDetectorDesktopCapturerWrapper::SetExcludedWindow(WindowId window) { | |
52 capturer_->SetExcludedWindow(window); | |
53 } | |
54 | |
55 bool BlankDetectorDesktopCapturerWrapper::GetSourceList(SourceList* sources) { | |
56 return capturer_->GetSourceList(sources); | |
57 } | |
58 | |
59 bool BlankDetectorDesktopCapturerWrapper::SelectSource(SourceId id) { | |
60 return capturer_->SelectSource(id); | |
61 } | |
62 | |
63 bool BlankDetectorDesktopCapturerWrapper::FocusOnSelectedSource() { | |
64 return capturer_->FocusOnSelectedSource(); | |
65 } | |
66 | |
67 void BlankDetectorDesktopCapturerWrapper::OnCaptureResult( | |
68 Result result, | |
69 std::unique_ptr<DesktopFrame> frame) { | |
70 RTC_DCHECK(callback_); | |
71 if (result != Result::SUCCESS || non_blank_frame_received_) { | |
72 callback_->OnCaptureResult(result, std::move(frame)); | |
73 return; | |
74 } | |
75 | |
76 if (!frame) { | |
Sergey Ulanov
2017/03/01 22:18:32
This is a bug in the underlying capturer. DCHECK()
Hzj_jie
2017/03/01 23:31:38
Done.
| |
77 ReturnTemporaryError(); | |
78 return; | |
79 } | |
80 | |
81 if (permanent_failure_reached()) { | |
82 ReturnPermanentError(); | |
83 return; | |
84 } | |
85 | |
86 // If nothing has been changed in current frame, we do not need to check it | |
87 // again. | |
88 if (!frame->updated_region().is_empty() || is_first_frame_) { | |
89 last_frame_is_blank_ = IsBlankFrame(*frame); | |
90 is_first_frame_ = false; | |
91 } | |
92 RTC_HISTOGRAM_BOOLEAN("WebRTC.DesktopCapture.BlankFrameDetected", | |
93 last_frame_is_blank_); | |
94 if (!last_frame_is_blank_) { | |
95 non_blank_frame_received_ = true; | |
96 callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); | |
97 return; | |
98 } | |
99 | |
100 if (permanent_failure_enabled()) { | |
101 failure_count_++; | |
102 if (permanent_failure_reached()) { | |
103 ReturnPermanentError(); | |
104 return; | |
105 } | |
106 } | |
107 | |
108 ReturnTemporaryError(); | |
109 } | |
110 | |
111 bool BlankDetectorDesktopCapturerWrapper::IsBlankFrame( | |
112 const DesktopFrame& frame) const { | |
113 // We will check 768 pixels for a frame with 1024 x 768 resolution. | |
114 for (int i = 0; i < frame.size().width() * frame.size().height(); i += 1000) { | |
Sergey Ulanov
2017/03/01 22:18:32
Hm. I think this filter can still be problematic i
Hzj_jie
2017/03/01 23:31:37
According to DesktopCapturerDifferWrapperTest, it
| |
115 const int x = i % frame.size().width(); | |
116 const int y = i / frame.size().width(); | |
117 if (!IsBlankPixel(frame, x, y)) { | |
118 return false; | |
119 } | |
120 } | |
121 | |
122 return IsBlankPixel(frame, frame.size().width() >> 1, | |
Sergey Ulanov
2017/03/01 22:18:32
Add a comment that we are verifying the pixel in t
Hzj_jie
2017/03/01 23:31:37
Done.
| |
123 frame.size().height() >> 1); | |
124 } | |
125 | |
126 bool BlankDetectorDesktopCapturerWrapper::IsBlankPixel( | |
127 const DesktopFrame& frame, | |
128 int x, | |
129 int y) const { | |
130 uint8_t* pixel_data = frame.GetFrameDataAtPos(DesktopVector(x, y)); | |
131 return RgbaColor(pixel_data) == blank_pixel_; | |
Sergey Ulanov
2017/03/01 22:18:32
Do we want to verify the alpha byte? Is it guarant
Hzj_jie
2017/03/01 23:31:37
Yes, so the constructor of BlankDetectorDesktopCap
| |
132 } | |
133 | |
134 bool BlankDetectorDesktopCapturerWrapper::permanent_failure_enabled() const { | |
135 return permanent_failure_threshold_ >= 0; | |
Sergey Ulanov
2017/03/01 22:18:32
It's not documented in the header that permanent_f
Hzj_jie
2017/03/01 23:31:38
Done.
| |
136 } | |
137 | |
138 bool BlankDetectorDesktopCapturerWrapper::permanent_failure_reached() const { | |
139 return permanent_failure_enabled() && | |
140 failure_count_ >= permanent_failure_threshold_; | |
141 } | |
142 | |
143 void BlankDetectorDesktopCapturerWrapper::ReturnPermanentError() { | |
144 callback_->OnCaptureResult(Result::ERROR_PERMANENT, | |
145 std::unique_ptr<DesktopFrame>()); | |
146 } | |
147 | |
148 void BlankDetectorDesktopCapturerWrapper::ReturnTemporaryError() { | |
149 callback_->OnCaptureResult(Result::ERROR_TEMPORARY, | |
150 std::unique_ptr<DesktopFrame>()); | |
151 } | |
152 | |
153 } // namespace webrtc | |
OLD | NEW |