Chromium Code Reviews| Index: webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.cc | 
| diff --git a/webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.cc b/webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..1b50d291e06aae4ba0706079a99c197d447a3394 | 
| --- /dev/null | 
| +++ b/webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.cc | 
| @@ -0,0 +1,126 @@ | 
| +/* | 
| + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 
| + * | 
| + * Use of this source code is governed by a BSD-style license | 
| + * that can be found in the LICENSE file in the root of the source | 
| + * tree. An additional intellectual property rights grant can be found | 
| + * in the file PATENTS. All contributing project authors may | 
| + * be found in the AUTHORS file in the root of the source tree. | 
| + */ | 
| + | 
| +#include <utility> | 
| + | 
| +#include "webrtc/base/checks.h" | 
| +#include "webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.h" | 
| +#include "webrtc/modules/desktop_capture/desktop_geometry.h" | 
| + | 
| +namespace webrtc { | 
| + | 
| +BlankDetectorDesktopCapturerWrapper::BlankDetectorDesktopCapturerWrapper( | 
| + std::unique_ptr<DesktopCapturer> capturer, | 
| + RgbaColor blank_pixel, | 
| + int permenant_failure_threshold) | 
| + : capturer_(std::move(capturer)), | 
| + blank_pixel_(blank_pixel), | 
| + permenant_failure_threshold_(permenant_failure_threshold) { | 
| + RTC_DCHECK(capturer_); | 
| +} | 
| + | 
| +BlankDetectorDesktopCapturerWrapper::~BlankDetectorDesktopCapturerWrapper() = | 
| + default; | 
| + | 
| +void BlankDetectorDesktopCapturerWrapper::Start( | 
| + DesktopCapturer::Callback* callback) { | 
| + capturer_->Start(this); | 
| + callback_ = callback; | 
| +} | 
| + | 
| +void BlankDetectorDesktopCapturerWrapper::SetSharedMemoryFactory( | 
| + std::unique_ptr<SharedMemoryFactory> shared_memory_factory) { | 
| + capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory)); | 
| +} | 
| + | 
| +void BlankDetectorDesktopCapturerWrapper::CaptureFrame() { | 
| + RTC_DCHECK(callback_); | 
| + capturer_->CaptureFrame(); | 
| +} | 
| + | 
| +void BlankDetectorDesktopCapturerWrapper::SetExcludedWindow(WindowId window) { | 
| + capturer_->SetExcludedWindow(window); | 
| +} | 
| + | 
| +bool BlankDetectorDesktopCapturerWrapper::GetSourceList(SourceList* sources) { | 
| + return capturer_->GetSourceList(sources); | 
| +} | 
| + | 
| +bool BlankDetectorDesktopCapturerWrapper::SelectSource(SourceId id) { | 
| + return capturer_->SelectSource(id); | 
| +} | 
| + | 
| +bool BlankDetectorDesktopCapturerWrapper::FocusOnSelectedSource() { | 
| + return capturer_->FocusOnSelectedSource(); | 
| +} | 
| + | 
| +void BlankDetectorDesktopCapturerWrapper::OnCaptureResult( | 
| + Result result, | 
| + std::unique_ptr<DesktopFrame> frame) { | 
| + RTC_DCHECK(callback_); | 
| + if (result != Result::SUCCESS) { | 
| + callback_->OnCaptureResult(result, std::move(frame)); | 
| + return; | 
| + } | 
| + | 
| + if (!frame) { | 
| + callback_->OnCaptureResult(Result::ERROR_TEMPORARY, | 
| + std::unique_ptr<DesktopFrame>()); | 
| + return; | 
| + } | 
| + | 
| + if (!IsBlankFrame(*frame)) { | 
| 
 
Sergey Ulanov
2017/02/21 21:58:48
Do we need to check every frame only only a few fi
 
Hzj_jie
2017/02/21 22:59:40
Oh, yes, at least when permanent_failure_threshold
 
 | 
| + failure_count_ = 0; | 
| + callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); | 
| + return; | 
| + } | 
| + | 
| + if (permenant_failure_threshold_ >= 0) { | 
| + failure_count_++; | 
| + if (failure_count_ >= permenant_failure_threshold_) { | 
| + callback_->OnCaptureResult(Result::ERROR_PERMANENT, | 
| + std::unique_ptr<DesktopFrame>()); | 
| + return; | 
| + } | 
| + } | 
| + callback_->OnCaptureResult(Result::ERROR_TEMPORARY, | 
| + std::unique_ptr<DesktopFrame>()); | 
| +} | 
| + | 
| +bool BlankDetectorDesktopCapturerWrapper::IsBlankFrame( | 
| + const DesktopFrame& frame) const { | 
| + const int size = | 
| + (frame.size().width() < frame.size().height() ? frame.size().width() | 
| + : frame.size().height()); | 
| + // We will check 303 pixels for a frame with 1024 x 768 resolution. | 
| + for (int i = 0; i < size; i += 10) { | 
| + const int x1 = i; | 
| + const int x2 = frame.size().width() - i - 1; | 
| + const int y1 = i; | 
| + const int y2 = frame.size().height() - i - 1; | 
| + if (!IsBlankPixel(frame, x1, y1) || !IsBlankPixel(frame, x1, y2) || | 
| + !IsBlankPixel(frame, x2, y1) || !IsBlankPixel(frame, x2, y2)) { | 
| + return false; | 
| + } | 
| + } | 
| + | 
| + return IsBlankPixel(frame, frame.size().width() >> 1, | 
| + frame.size().height() >> 1); | 
| +} | 
| + | 
| +bool BlankDetectorDesktopCapturerWrapper::IsBlankPixel( | 
| + const DesktopFrame& frame, | 
| + int x, | 
| + int y) const { | 
| + uint8_t* pixel_data = frame.GetFrameDataAtPos(DesktopVector(x, y)); | 
| + return RgbaColor(pixel_data) == blank_pixel_; | 
| +} | 
| + | 
| +} // namespace webrtc |