From e9a3c7f43c697c3c1e7c8956baebeaf2a1a867f6 Mon Sep 17 00:00:00 2001 From: zijiehe Date: Fri, 16 Sep 2016 00:03:15 -0700 Subject: [PATCH] Wrap ScreenCapturer with ScreenCapturerDifferWrapper This change is to add an DesktopCapturerOptions accurate_updated_region() with default value as false to indicate whether a pixel-wise differentiation is required. And ScreenCapturer::Create() function will wrap the implementation with ScreenCapturerDifferWrapper. Chromoting will use this option to filter out unchanged frames. BUG=314516 Review-Url: https://codereview.webrtc.org/2314323002 Cr-Commit-Position: refs/heads/master@{#14248} --- .../desktop_capture/desktop_capture_options.h | 11 ++++++++++ .../desktop_capture/screen_capturer_mac.mm | 14 +++++++++--- .../screen_capturer_unittest.cc | 22 ++++++++++++++++--- .../desktop_capture/screen_capturer_win.cc | 10 +++++++-- .../desktop_capture/screen_capturer_x11.cc | 14 +++++++++--- .../win/screen_capturer_win_directx.cc | 1 + .../win/screen_capturer_win_directx.h | 3 ++- 7 files changed, 63 insertions(+), 12 deletions(-) diff --git a/webrtc/modules/desktop_capture/desktop_capture_options.h b/webrtc/modules/desktop_capture/desktop_capture_options.h index 2aa3e5197c..d872d7d15f 100644 --- a/webrtc/modules/desktop_capture/desktop_capture_options.h +++ b/webrtc/modules/desktop_capture/desktop_capture_options.h @@ -72,6 +72,16 @@ class DesktopCaptureOptions { disable_effects_ = disable_effects; } + // Flag that should be set if the consumer uses updated_region() and the + // capturer should try to provide correct updated_region() for the frames it + // generates (e.g. by comparing each frame with the previous one). + // TODO(zijiehe): WindowCapturer ignores this opinion until we merge + // ScreenCapturer and WindowCapturer interfaces. + bool detect_updated_region() const { return detect_updated_region_; } + void set_detect_updated_region(bool detect_updated_region) { + detect_updated_region_ = detect_updated_region; + } + #if defined(WEBRTC_WIN) bool allow_use_magnification_api() const { return allow_use_magnification_api_; @@ -110,6 +120,7 @@ class DesktopCaptureOptions { bool use_update_notifications_ = true; #endif bool disable_effects_ = true; + bool detect_updated_region_ = false; }; } // namespace webrtc diff --git a/webrtc/modules/desktop_capture/screen_capturer_mac.mm b/webrtc/modules/desktop_capture/screen_capturer_mac.mm index 7cb1720ed9..451cd9ed9d 100644 --- a/webrtc/modules/desktop_capture/screen_capturer_mac.mm +++ b/webrtc/modules/desktop_capture/screen_capturer_mac.mm @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -33,6 +34,7 @@ #include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h" #include "webrtc/modules/desktop_capture/mac/scoped_pixel_buffer_object.h" #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h" +#include "webrtc/modules/desktop_capture/screen_capturer_differ_wrapper.h" #include "webrtc/modules/desktop_capture/screen_capturer_helper.h" #include "webrtc/modules/desktop_capture/shared_desktop_frame.h" #include "webrtc/system_wrappers/include/logging.h" @@ -937,10 +939,16 @@ ScreenCapturer* ScreenCapturer::Create(const DesktopCaptureOptions& options) { if (!options.configuration_monitor()) return nullptr; - std::unique_ptr capturer( + std::unique_ptr capturer( new ScreenCapturerMac(options.configuration_monitor())); - if (!capturer->Init()) - capturer.reset(); + if (!static_cast(capturer.get())->Init()) { + return nullptr; + } + + if (options.detect_updated_region()) { + capturer.reset(new ScreenCapturerDifferWrapper(std::move(capturer))); + } + return capturer.release(); } diff --git a/webrtc/modules/desktop_capture/screen_capturer_unittest.cc b/webrtc/modules/desktop_capture/screen_capturer_unittest.cc index 0236e3b668..5c3671672a 100644 --- a/webrtc/modules/desktop_capture/screen_capturer_unittest.cc +++ b/webrtc/modules/desktop_capture/screen_capturer_unittest.cc @@ -129,15 +129,21 @@ class ScreenCapturerTest : public testing::Test { } #if defined(WEBRTC_WIN) + // Enable allow_directx_capturer in DesktopCaptureOptions, but let + // ScreenCapturer::Create to decide whether a DirectX capturer should be used. + void MaybeCreateDirectxCapturer() { + DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault()); + options.set_allow_directx_capturer(true); + capturer_.reset(ScreenCapturer::Create(options)); + } + bool CreateDirectxCapturer() { if (!ScreenCapturerWinDirectx::IsSupported()) { LOG(LS_WARNING) << "Directx capturer is not supported"; return false; } - DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault()); - options.set_allow_directx_capturer(true); - capturer_.reset(ScreenCapturer::Create(options)); + MaybeCreateDirectxCapturer(); return true; } @@ -382,6 +388,16 @@ TEST_F(ScreenCapturerTest, DISABLED_TwoMagnifierCapturers) { TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); } +// Disabled due to being flaky due to the fact that it useds rendering / UI, +// see webrtc/6366. +TEST_F(ScreenCapturerTest, + DISABLED_MaybeCaptureUpdatedRegionWithDirectxCapturer) { + // Even DirectX capturer is not supported in current system, we should be able + // to select a usable capturer. + MaybeCreateDirectxCapturer(); + TestCaptureUpdatedRegion(); +} + #endif // defined(WEBRTC_WIN) } // namespace webrtc diff --git a/webrtc/modules/desktop_capture/screen_capturer_win.cc b/webrtc/modules/desktop_capture/screen_capturer_win.cc index 6a83bec1c5..1d05961aff 100644 --- a/webrtc/modules/desktop_capture/screen_capturer_win.cc +++ b/webrtc/modules/desktop_capture/screen_capturer_win.cc @@ -14,6 +14,7 @@ #include #include "webrtc/modules/desktop_capture/desktop_capture_options.h" +#include "webrtc/modules/desktop_capture/screen_capturer_differ_wrapper.h" #include "webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h" #include "webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.h" #include "webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h" @@ -30,8 +31,13 @@ ScreenCapturer* ScreenCapturer::Create(const DesktopCaptureOptions& options) { capturer.reset(new ScreenCapturerWinGdi(options)); } - if (options.allow_use_magnification_api()) - return new ScreenCapturerWinMagnifier(std::move(capturer)); + if (options.allow_use_magnification_api()) { + capturer.reset(new ScreenCapturerWinMagnifier(std::move(capturer))); + } + + if (options.detect_updated_region()) { + capturer.reset(new ScreenCapturerDifferWrapper(std::move(capturer))); + } return capturer.release(); } diff --git a/webrtc/modules/desktop_capture/screen_capturer_x11.cc b/webrtc/modules/desktop_capture/screen_capturer_x11.cc index 57c2e5fc16..d274140e98 100644 --- a/webrtc/modules/desktop_capture/screen_capturer_x11.cc +++ b/webrtc/modules/desktop_capture/screen_capturer_x11.cc @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -27,6 +28,7 @@ #include "webrtc/modules/desktop_capture/desktop_frame.h" #include "webrtc/modules/desktop_capture/differ.h" #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h" +#include "webrtc/modules/desktop_capture/screen_capturer_differ_wrapper.h" #include "webrtc/modules/desktop_capture/screen_capturer_helper.h" #include "webrtc/modules/desktop_capture/shared_desktop_frame.h" #include "webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.h" @@ -426,9 +428,15 @@ ScreenCapturer* ScreenCapturer::Create(const DesktopCaptureOptions& options) { if (!options.x_display()) return nullptr; - std::unique_ptr capturer(new ScreenCapturerLinux()); - if (!capturer->Init(options)) - capturer.reset(); + std::unique_ptr capturer(new ScreenCapturerLinux()); + if (!static_cast(capturer.get())->Init(options)) { + return nullptr; + } + + if (options.detect_updated_region()) { + capturer.reset(new ScreenCapturerDifferWrapper(std::move(capturer))); + } + return capturer.release(); } diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc b/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc index e4b2c3e8a2..9e3f58b11e 100644 --- a/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc +++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc @@ -21,6 +21,7 @@ namespace webrtc { using Microsoft::WRL::ComPtr; +// static bool ScreenCapturerWinDirectx::IsSupported() { // Forward IsSupported function call to DxgiDuplicatorController. return DxgiDuplicatorController::Instance()->IsSupported(); diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h b/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h index 119ffaecdf..86232c74ff 100644 --- a/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h +++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h @@ -28,10 +28,11 @@ namespace webrtc { // implementation won't work when ScreenCaptureFrameQueue.kQueueLength is not 2. class ScreenCapturerWinDirectx : public ScreenCapturer { public: - // Whether the system support DirectX based capturing. + // Whether the system supports DirectX based capturing. static bool IsSupported(); explicit ScreenCapturerWinDirectx(const DesktopCaptureOptions& options); + virtual ~ScreenCapturerWinDirectx(); void Start(Callback* callback) override;