From 3fa87f782e0a11f1ce24e56a61f0b926e99670dc Mon Sep 17 00:00:00 2001 From: zijiehe Date: Wed, 22 Feb 2017 13:47:00 -0800 Subject: [PATCH] Use FallbackDesktopCapturerWrapper in ScreenCapturerWinMagnifier This is a trivial change to remove duplicate logic, i.e. fallback capturer, from ScreenCapturerWinMagnifier. BUG=webrtc:7215 Review-Url: https://codereview.webrtc.org/2704943002 Cr-Commit-Position: refs/heads/master@{#16781} --- .../desktop_capture/screen_capturer_win.cc | 8 ++- .../win/screen_capturer_win_magnifier.cc | 61 +++++++------------ .../win/screen_capturer_win_magnifier.h | 11 +--- 3 files changed, 29 insertions(+), 51 deletions(-) diff --git a/webrtc/modules/desktop_capture/screen_capturer_win.cc b/webrtc/modules/desktop_capture/screen_capturer_win.cc index 1aec5aaa0f..602600be89 100644 --- a/webrtc/modules/desktop_capture/screen_capturer_win.cc +++ b/webrtc/modules/desktop_capture/screen_capturer_win.cc @@ -13,6 +13,7 @@ #include "webrtc/modules/desktop_capture/desktop_capturer.h" #include "webrtc/modules/desktop_capture/desktop_capture_options.h" +#include "webrtc/modules/desktop_capture/fallback_desktop_capturer_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" @@ -31,7 +32,12 @@ std::unique_ptr DesktopCapturer::CreateRawScreenCapturer( } if (options.allow_use_magnification_api()) { - capturer.reset(new ScreenCapturerWinMagnifier(std::move(capturer))); + // ScreenCapturerWinMagnifier cannot work on Windows XP or earlier, as well + // as 64-bit only Windows, and it may randomly crash on multi-screen + // systems. So we may need to fallback to use original capturer. + capturer.reset(new FallbackDesktopCapturerWrapper( + std::unique_ptr(new ScreenCapturerWinMagnifier()), + std::move(capturer))); } return capturer; diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc b/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc index 96348ca494..2a686c4384 100644 --- a/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc +++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc @@ -35,10 +35,7 @@ static LPCTSTR kMagnifierWindowName = L"MagnifierWindow"; Atomic32 ScreenCapturerWinMagnifier::tls_index_(TLS_OUT_OF_INDEXES); -ScreenCapturerWinMagnifier::ScreenCapturerWinMagnifier( - std::unique_ptr fallback_capturer) - : fallback_capturer_(std::move(fallback_capturer)) {} - +ScreenCapturerWinMagnifier::ScreenCapturerWinMagnifier() = default; ScreenCapturerWinMagnifier::~ScreenCapturerWinMagnifier() { // DestroyWindow must be called before MagUninitialize. magnifier_window_ is // destroyed automatically when host_window_ is destroyed. @@ -61,9 +58,7 @@ void ScreenCapturerWinMagnifier::Start(Callback* callback) { callback_ = callback; if (!InitializeMagnifier()) { - LOG_F(LS_WARNING) << "Switching to fallback screen capturer becuase " - "magnifier initialization failed."; - StartFallbackCapturer(); + LOG_F(LS_WARNING) << "Magnifier initialization failed."; } } @@ -73,16 +68,10 @@ void ScreenCapturerWinMagnifier::SetSharedMemoryFactory( } void ScreenCapturerWinMagnifier::CaptureFrame() { - if (!magnifier_initialized_ || - !magnifier_capture_succeeded_ || - GetSystemMetrics(SM_CMONITORS) != 1) { - // Do not try to use the magnifier if it failed before and in multi-screen - // setup (where the API crashes sometimes). - LOG_F(LS_WARNING) << "Switching to the fallback screen capturer because " - "initialization or last capture attempt failed, or " - "execute on multi-screen system."; - StartFallbackCapturer(); - fallback_capturer_->CaptureFrame(); + RTC_DCHECK(callback_); + if (!magnifier_initialized_) { + LOG_F(LS_WARNING) << "Magnifier initialization failed."; + callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); return; } @@ -108,10 +97,8 @@ void ScreenCapturerWinMagnifier::CaptureFrame() { // CaptureImage may fail in some situations, e.g. windows8 metro mode. So // defer to the fallback capturer if magnifier capturer did not work. if (!CaptureImage(rect)) { - LOG_F(LS_WARNING) << "Switching to the fallback screen capturer because " - "last capture attempt failed."; - StartFallbackCapturer(); - fallback_capturer_->CaptureFrame(); + LOG_F(LS_WARNING) << "Magnifier capturer failed to capture a frame."; + callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); return; } @@ -131,17 +118,12 @@ bool ScreenCapturerWinMagnifier::GetSourceList(SourceList* sources) { } bool ScreenCapturerWinMagnifier::SelectSource(SourceId id) { - bool valid = IsScreenValid(id, ¤t_device_key_); - - // Set current_screen_id_ even if the fallback capturer is being used, so we - // can switch back to the magnifier when possible. - if (valid) + if (IsScreenValid(id, ¤t_device_key_)) { current_screen_id_ = id; + return true; + } - if (fallback_capturer_started_) - fallback_capturer_->SelectSource(id); - - return valid; + return false; } void ScreenCapturerWinMagnifier::SetExcludedWindow(WindowId excluded_window) { @@ -210,6 +192,15 @@ BOOL ScreenCapturerWinMagnifier::OnMagImageScalingCallback( // include and function calls instead of a dynamical loaded library. bool ScreenCapturerWinMagnifier::InitializeMagnifier() { RTC_DCHECK(!magnifier_initialized_); + + if (GetSystemMetrics(SM_CMONITORS) != 1) { + // Do not try to use the magnifier in multi-screen setup (where the API + // crashes sometimes). + LOG_F(LS_WARNING) << "Magnifier capturer cannot work on multi-screen " + "system."; + return false; + } + desktop_dc_ = GetDC(nullptr); mag_lib_handle_ = LoadLibrary(L"Magnification.dll"); @@ -376,14 +367,4 @@ void ScreenCapturerWinMagnifier::CreateCurrentFrameIfNecessary( } } -void ScreenCapturerWinMagnifier::StartFallbackCapturer() { - RTC_DCHECK(fallback_capturer_); - if (!fallback_capturer_started_) { - fallback_capturer_started_ = true; - - fallback_capturer_->Start(callback_); - fallback_capturer_->SelectSource(current_screen_id_); - } -} - } // namespace webrtc diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h b/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h index 96622afbed..7f1f55a121 100644 --- a/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h +++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h @@ -40,11 +40,7 @@ class DesktopRect; // be used if that functionality is necessary. class ScreenCapturerWinMagnifier : public DesktopCapturer { public: - // |fallback_capturer| will be used to capture the screen if a non-primary - // screen is being captured, or the OS does not support Magnification API, or - // the magnifier capturer fails (e.g. in Windows8 Metro mode). - explicit ScreenCapturerWinMagnifier( - std::unique_ptr fallback_capturer); + ScreenCapturerWinMagnifier(); ~ScreenCapturerWinMagnifier() override; // Overridden from ScreenCapturer: @@ -103,13 +99,8 @@ class ScreenCapturerWinMagnifier : public DesktopCapturer { // Makes sure the current frame exists and matches |size|. void CreateCurrentFrameIfNecessary(const DesktopSize& size); - // Start the fallback capturer and select the screen. - void StartFallbackCapturer(); - static Atomic32 tls_index_; - std::unique_ptr fallback_capturer_; - bool fallback_capturer_started_ = false; Callback* callback_ = nullptr; std::unique_ptr shared_memory_factory_; ScreenId current_screen_id_ = kFullDesktopScreenId;