| Index: webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper_unittest.cc
 | 
| diff --git a/webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper_unittest.cc b/webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper_unittest.cc
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..05ecef50c439ea398fb90e20cec4c38e781d1c8a
 | 
| --- /dev/null
 | 
| +++ b/webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper_unittest.cc
 | 
| @@ -0,0 +1,161 @@
 | 
| +/*
 | 
| + *  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 "webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.h"
 | 
| +
 | 
| +#include <memory>
 | 
| +#include <utility>
 | 
| +
 | 
| +#include "webrtc/modules/desktop_capture/desktop_capturer.h"
 | 
| +#include "webrtc/modules/desktop_capture/desktop_frame.h"
 | 
| +#include "webrtc/modules/desktop_capture/desktop_frame_generator.h"
 | 
| +#include "webrtc/modules/desktop_capture/fake_desktop_capturer.h"
 | 
| +#include "webrtc/test/gtest.h"
 | 
| +
 | 
| +namespace webrtc {
 | 
| +
 | 
| +class BlankDetectorDesktopCapturerWrapperTest
 | 
| +    : public testing::Test,
 | 
| +      public DesktopCapturer::Callback {
 | 
| + public:
 | 
| +  BlankDetectorDesktopCapturerWrapperTest();
 | 
| +  ~BlankDetectorDesktopCapturerWrapperTest() override;
 | 
| +
 | 
| + protected:
 | 
| +  void PerfTest(DesktopCapturer* capturer);
 | 
| +
 | 
| +  const int frame_width_ = 1024;
 | 
| +  const int frame_height_ = 768;
 | 
| +  const int permanent_failure_threshold_ = 100;
 | 
| +  std::unique_ptr<BlankDetectorDesktopCapturerWrapper> wrapper_;
 | 
| +  DesktopCapturer* capturer_ = nullptr;
 | 
| +  BlackWhiteDesktopFramePainter painter_;
 | 
| +  int num_frames_captured_ = 0;
 | 
| +  DesktopCapturer::Result last_result_ = DesktopCapturer::Result::SUCCESS;
 | 
| +  std::unique_ptr<DesktopFrame> last_frame_;
 | 
| +
 | 
| + private:
 | 
| +  // DesktopCapturer::Callback interface.
 | 
| +  void OnCaptureResult(DesktopCapturer::Result result,
 | 
| +                       std::unique_ptr<DesktopFrame> frame) override;
 | 
| +
 | 
| +  PainterDesktopFrameGenerator frame_generator_;
 | 
| +};
 | 
| +
 | 
| +BlankDetectorDesktopCapturerWrapperTest::
 | 
| +    BlankDetectorDesktopCapturerWrapperTest() {
 | 
| +  frame_generator_.size()->set(frame_width_, frame_height_);
 | 
| +  frame_generator_.set_desktop_frame_painter(&painter_);
 | 
| +  std::unique_ptr<DesktopCapturer> capturer(new FakeDesktopCapturer());
 | 
| +  FakeDesktopCapturer* fake_capturer =
 | 
| +      static_cast<FakeDesktopCapturer*>(capturer.get());
 | 
| +  fake_capturer->set_frame_generator(&frame_generator_);
 | 
| +  capturer_ = fake_capturer;
 | 
| +  wrapper_.reset(new BlankDetectorDesktopCapturerWrapper(
 | 
| +      std::move(capturer), RgbaColor(0, 0, 0, 0),
 | 
| +      permanent_failure_threshold_));
 | 
| +  wrapper_->Start(this);
 | 
| +}
 | 
| +
 | 
| +BlankDetectorDesktopCapturerWrapperTest::
 | 
| +    ~BlankDetectorDesktopCapturerWrapperTest() = default;
 | 
| +
 | 
| +void BlankDetectorDesktopCapturerWrapperTest::OnCaptureResult(
 | 
| +    DesktopCapturer::Result result,
 | 
| +    std::unique_ptr<DesktopFrame> frame) {
 | 
| +  last_result_ = result;
 | 
| +  last_frame_ = std::move(frame);
 | 
| +  num_frames_captured_++;
 | 
| +}
 | 
| +
 | 
| +void BlankDetectorDesktopCapturerWrapperTest::PerfTest(
 | 
| +    DesktopCapturer* capturer) {
 | 
| +  for (int i = 0; i < 10000; i++) {
 | 
| +    // According to the implementation detail, this pixel is checked at last.
 | 
| +    painter_.updated_region()->AddRect(
 | 
| +        DesktopRect::MakeXYWH(frame_width_ >> 1, frame_height_ >> 1, 1, 1));
 | 
| +    capturer->CaptureFrame();
 | 
| +    ASSERT_EQ(num_frames_captured_, i + 1);
 | 
| +    ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS);
 | 
| +    ASSERT_TRUE(last_frame_);
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +TEST_F(BlankDetectorDesktopCapturerWrapperTest, ShouldDetectBlankFrame) {
 | 
| +  wrapper_->CaptureFrame();
 | 
| +  ASSERT_EQ(num_frames_captured_, 1);
 | 
| +  ASSERT_EQ(last_result_, DesktopCapturer::Result::ERROR_TEMPORARY);
 | 
| +  ASSERT_FALSE(last_frame_);
 | 
| +}
 | 
| +
 | 
| +TEST_F(BlankDetectorDesktopCapturerWrapperTest, ShouldPassBlankDetection) {
 | 
| +  painter_.updated_region()->AddRect(DesktopRect::MakeXYWH(0, 0, 10, 10));
 | 
| +  wrapper_->CaptureFrame();
 | 
| +  ASSERT_EQ(num_frames_captured_, 1);
 | 
| +  ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS);
 | 
| +  ASSERT_TRUE(last_frame_);
 | 
| +
 | 
| +  painter_.updated_region()->AddRect(
 | 
| +      DesktopRect::MakeXYWH(frame_width_ - 10, frame_height_ - 10, 10, 10));
 | 
| +  wrapper_->CaptureFrame();
 | 
| +  ASSERT_EQ(num_frames_captured_, 2);
 | 
| +  ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS);
 | 
| +  ASSERT_TRUE(last_frame_);
 | 
| +
 | 
| +  painter_.updated_region()->AddRect(
 | 
| +      DesktopRect::MakeXYWH(0, frame_height_ - 10, 10, 10));
 | 
| +  wrapper_->CaptureFrame();
 | 
| +  ASSERT_EQ(num_frames_captured_, 3);
 | 
| +  ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS);
 | 
| +  ASSERT_TRUE(last_frame_);
 | 
| +
 | 
| +  painter_.updated_region()->AddRect(
 | 
| +      DesktopRect::MakeXYWH(frame_width_ - 10, 0, 10, 10));
 | 
| +  wrapper_->CaptureFrame();
 | 
| +  ASSERT_EQ(num_frames_captured_, 4);
 | 
| +  ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS);
 | 
| +  ASSERT_TRUE(last_frame_);
 | 
| +
 | 
| +  painter_.updated_region()->AddRect(DesktopRect::MakeXYWH(
 | 
| +      (frame_width_ >> 1) - 5, (frame_height_ >> 1) - 5, 10, 10));
 | 
| +  wrapper_->CaptureFrame();
 | 
| +  ASSERT_EQ(num_frames_captured_, 5);
 | 
| +  ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS);
 | 
| +  ASSERT_TRUE(last_frame_);
 | 
| +}
 | 
| +
 | 
| +TEST_F(BlankDetectorDesktopCapturerWrapperTest, ShouldReturnPermanentError) {
 | 
| +  for (int i = 0; i < permanent_failure_threshold_ - 1; i++) {
 | 
| +    wrapper_->CaptureFrame();
 | 
| +    ASSERT_EQ(num_frames_captured_, i + 1);
 | 
| +    ASSERT_EQ(last_result_, DesktopCapturer::Result::ERROR_TEMPORARY);
 | 
| +    ASSERT_FALSE(last_frame_);
 | 
| +  }
 | 
| +  wrapper_->CaptureFrame();
 | 
| +  ASSERT_EQ(num_frames_captured_, permanent_failure_threshold_);
 | 
| +  ASSERT_EQ(last_result_, DesktopCapturer::Result::ERROR_PERMANENT);
 | 
| +  ASSERT_FALSE(last_frame_);
 | 
| +}
 | 
| +
 | 
| +// There is no perceptible impact by using BlankDetectorDesktopCapturerWrapper.
 | 
| +// i.e. less than 0.01ms per frame.
 | 
| +// [ OK ] DISABLED_Performance (8555 ms)
 | 
| +// [ OK ] DISABLED_PerformanceComparison (8456 ms)
 | 
| +TEST_F(BlankDetectorDesktopCapturerWrapperTest, DISABLED_Performance) {
 | 
| +  PerfTest(wrapper_.get());
 | 
| +}
 | 
| +
 | 
| +TEST_F(BlankDetectorDesktopCapturerWrapperTest,
 | 
| +       DISABLED_PerformanceComparison) {
 | 
| +  capturer_->Start(this);
 | 
| +  PerfTest(capturer_);
 | 
| +}
 | 
| +
 | 
| +}  // namespace webrtc
 | 
| 
 |