• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <stdint.h>
14 
15 #include <utility>
16 
17 #include "modules/desktop_capture/desktop_geometry.h"
18 #include "modules/desktop_capture/desktop_region.h"
19 #include "rtc_base/checks.h"
20 #include "system_wrappers/include/metrics.h"
21 
22 namespace webrtc {
23 
BlankDetectorDesktopCapturerWrapper(std::unique_ptr<DesktopCapturer> capturer,RgbaColor blank_pixel)24 BlankDetectorDesktopCapturerWrapper::BlankDetectorDesktopCapturerWrapper(
25     std::unique_ptr<DesktopCapturer> capturer,
26     RgbaColor blank_pixel)
27     : capturer_(std::move(capturer)), blank_pixel_(blank_pixel) {
28   RTC_DCHECK(capturer_);
29 }
30 
31 BlankDetectorDesktopCapturerWrapper::~BlankDetectorDesktopCapturerWrapper() =
32     default;
33 
Start(DesktopCapturer::Callback * callback)34 void BlankDetectorDesktopCapturerWrapper::Start(
35     DesktopCapturer::Callback* callback) {
36   callback_ = callback;
37   capturer_->Start(this);
38 }
39 
SetSharedMemoryFactory(std::unique_ptr<SharedMemoryFactory> shared_memory_factory)40 void BlankDetectorDesktopCapturerWrapper::SetSharedMemoryFactory(
41     std::unique_ptr<SharedMemoryFactory> shared_memory_factory) {
42   capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory));
43 }
44 
CaptureFrame()45 void BlankDetectorDesktopCapturerWrapper::CaptureFrame() {
46   RTC_DCHECK(callback_);
47   capturer_->CaptureFrame();
48 }
49 
SetExcludedWindow(WindowId window)50 void BlankDetectorDesktopCapturerWrapper::SetExcludedWindow(WindowId window) {
51   capturer_->SetExcludedWindow(window);
52 }
53 
GetSourceList(SourceList * sources)54 bool BlankDetectorDesktopCapturerWrapper::GetSourceList(SourceList* sources) {
55   return capturer_->GetSourceList(sources);
56 }
57 
SelectSource(SourceId id)58 bool BlankDetectorDesktopCapturerWrapper::SelectSource(SourceId id) {
59   return capturer_->SelectSource(id);
60 }
61 
FocusOnSelectedSource()62 bool BlankDetectorDesktopCapturerWrapper::FocusOnSelectedSource() {
63   return capturer_->FocusOnSelectedSource();
64 }
65 
IsOccluded(const DesktopVector & pos)66 bool BlankDetectorDesktopCapturerWrapper::IsOccluded(const DesktopVector& pos) {
67   return capturer_->IsOccluded(pos);
68 }
69 
OnCaptureResult(Result result,std::unique_ptr<DesktopFrame> frame)70 void BlankDetectorDesktopCapturerWrapper::OnCaptureResult(
71     Result result,
72     std::unique_ptr<DesktopFrame> frame) {
73   RTC_DCHECK(callback_);
74   if (result != Result::SUCCESS || non_blank_frame_received_) {
75     callback_->OnCaptureResult(result, std::move(frame));
76     return;
77   }
78 
79   RTC_DCHECK(frame);
80 
81   // If nothing has been changed in current frame, we do not need to check it
82   // again.
83   if (!frame->updated_region().is_empty() || is_first_frame_) {
84     last_frame_is_blank_ = IsBlankFrame(*frame);
85     is_first_frame_ = false;
86   }
87   RTC_HISTOGRAM_BOOLEAN("WebRTC.DesktopCapture.BlankFrameDetected",
88                         last_frame_is_blank_);
89   if (!last_frame_is_blank_) {
90     non_blank_frame_received_ = true;
91     callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
92     return;
93   }
94 
95   callback_->OnCaptureResult(Result::ERROR_TEMPORARY,
96                              std::unique_ptr<DesktopFrame>());
97 }
98 
IsBlankFrame(const DesktopFrame & frame) const99 bool BlankDetectorDesktopCapturerWrapper::IsBlankFrame(
100     const DesktopFrame& frame) const {
101   // We will check 7489 pixels for a frame with 1024 x 768 resolution.
102   for (int i = 0; i < frame.size().width() * frame.size().height(); i += 105) {
103     const int x = i % frame.size().width();
104     const int y = i / frame.size().width();
105     if (!IsBlankPixel(frame, x, y)) {
106       return false;
107     }
108   }
109 
110   // We are verifying the pixel in the center as well.
111   return IsBlankPixel(frame, frame.size().width() / 2,
112                       frame.size().height() / 2);
113 }
114 
IsBlankPixel(const DesktopFrame & frame,int x,int y) const115 bool BlankDetectorDesktopCapturerWrapper::IsBlankPixel(
116     const DesktopFrame& frame,
117     int x,
118     int y) const {
119   uint8_t* pixel_data = frame.GetFrameDataAtPos(DesktopVector(x, y));
120   return RgbaColor(pixel_data) == blank_pixel_;
121 }
122 
123 }  // namespace webrtc
124