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-Original-Commit-Position: refs/heads/master@{#14248}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: e9a3c7f43c697c3c1e7c8956baebeaf2a1a867f6
diff --git a/modules/desktop_capture/desktop_capture_options.h b/modules/desktop_capture/desktop_capture_options.h
index 2aa3e51..d872d7d 100644
--- a/modules/desktop_capture/desktop_capture_options.h
+++ b/modules/desktop_capture/desktop_capture_options.h
@@ -72,6 +72,16 @@
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 @@
bool use_update_notifications_ = true;
#endif
bool disable_effects_ = true;
+ bool detect_updated_region_ = false;
};
} // namespace webrtc
diff --git a/modules/desktop_capture/screen_capturer_mac.mm b/modules/desktop_capture/screen_capturer_mac.mm
index 7cb1720..451cd9e 100644
--- a/modules/desktop_capture/screen_capturer_mac.mm
+++ b/modules/desktop_capture/screen_capturer_mac.mm
@@ -14,6 +14,7 @@
#include <memory>
#include <set>
+#include <utility>
#include <ApplicationServices/ApplicationServices.h>
#include <Cocoa/Cocoa.h>
@@ -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 @@
if (!options.configuration_monitor())
return nullptr;
- std::unique_ptr<ScreenCapturerMac> capturer(
+ std::unique_ptr<ScreenCapturer> capturer(
new ScreenCapturerMac(options.configuration_monitor()));
- if (!capturer->Init())
- capturer.reset();
+ if (!static_cast<ScreenCapturerMac*>(capturer.get())->Init()) {
+ return nullptr;
+ }
+
+ if (options.detect_updated_region()) {
+ capturer.reset(new ScreenCapturerDifferWrapper(std::move(capturer)));
+ }
+
return capturer.release();
}
diff --git a/modules/desktop_capture/screen_capturer_unittest.cc b/modules/desktop_capture/screen_capturer_unittest.cc
index 0236e3b..5c36716 100644
--- a/modules/desktop_capture/screen_capturer_unittest.cc
+++ b/modules/desktop_capture/screen_capturer_unittest.cc
@@ -129,15 +129,21 @@
}
#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 @@
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/modules/desktop_capture/screen_capturer_win.cc b/modules/desktop_capture/screen_capturer_win.cc
index 6a83bec..1d05961 100644
--- a/modules/desktop_capture/screen_capturer_win.cc
+++ b/modules/desktop_capture/screen_capturer_win.cc
@@ -14,6 +14,7 @@
#include <utility>
#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 @@
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/modules/desktop_capture/screen_capturer_x11.cc b/modules/desktop_capture/screen_capturer_x11.cc
index 57c2e5f..d274140 100644
--- a/modules/desktop_capture/screen_capturer_x11.cc
+++ b/modules/desktop_capture/screen_capturer_x11.cc
@@ -14,6 +14,7 @@
#include <memory>
#include <set>
+#include <utility>
#include <X11/extensions/Xdamage.h>
#include <X11/extensions/Xfixes.h>
@@ -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 @@
if (!options.x_display())
return nullptr;
- std::unique_ptr<ScreenCapturerLinux> capturer(new ScreenCapturerLinux());
- if (!capturer->Init(options))
- capturer.reset();
+ std::unique_ptr<ScreenCapturer> capturer(new ScreenCapturerLinux());
+ if (!static_cast<ScreenCapturerLinux*>(capturer.get())->Init(options)) {
+ return nullptr;
+ }
+
+ if (options.detect_updated_region()) {
+ capturer.reset(new ScreenCapturerDifferWrapper(std::move(capturer)));
+ }
+
return capturer.release();
}
diff --git a/modules/desktop_capture/win/screen_capturer_win_directx.cc b/modules/desktop_capture/win/screen_capturer_win_directx.cc
index e4b2c3e..9e3f58b 100644
--- a/modules/desktop_capture/win/screen_capturer_win_directx.cc
+++ b/modules/desktop_capture/win/screen_capturer_win_directx.cc
@@ -21,6 +21,7 @@
using Microsoft::WRL::ComPtr;
+// static
bool ScreenCapturerWinDirectx::IsSupported() {
// Forward IsSupported function call to DxgiDuplicatorController.
return DxgiDuplicatorController::Instance()->IsSupported();
diff --git a/modules/desktop_capture/win/screen_capturer_win_directx.h b/modules/desktop_capture/win/screen_capturer_win_directx.h
index 119ffae..86232c7 100644
--- a/modules/desktop_capture/win/screen_capturer_win_directx.h
+++ b/modules/desktop_capture/win/screen_capturer_win_directx.h
@@ -28,10 +28,11 @@
// 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;