Several minor changes to ScreenCapturerWinMagnifier

1. Remove legacy screen-saver-blocking logic
2. tls_index_ is not a good choice, we can use thread-static
3. ScreenCapturerHelper is not designed for this scenario
4. Disable this capturer on 2+ monitors system

BUG=638802

Review-Url: https://codereview.webrtc.org/2319383002
Cr-Commit-Position: refs/heads/master@{#14342}
This commit is contained in:
zijiehe
2016-09-21 17:25:41 -07:00
committed by Commit bot
parent 66cadfc0e3
commit 05bba2be48
3 changed files with 62 additions and 71 deletions

View File

@ -277,15 +277,14 @@ TEST_F(ScreenCapturerTest, Capture) {
EXPECT_TRUE(it.IsAtEnd());
}
// Disabled due to being flaky due to the fact that it useds rendering / UI,
// see webrtc/6366.
// Disabled due to being flaky due to the fact that it uses rendering / UI, see
// webrtc/6366.
TEST_F(ScreenCapturerTest, DISABLED_CaptureUpdatedRegion) {
TestCaptureUpdatedRegion();
}
// Disabled due to being flaky due to the fact that it useds rendering / UI,
// see webrtc/6366.
// TODO(zijiehe): Find out the reason of failure of this test on trybot.
// Disabled due to being flaky due to the fact that it uses rendering / UI, see
// webrtc/6366.
TEST_F(ScreenCapturerTest, DISABLED_TwoCapturers) {
std::unique_ptr<ScreenCapturer> capturer2 = std::move(capturer_);
SetUp();
@ -357,8 +356,8 @@ TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) {
EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
}
// Disabled due to being flaky due to the fact that it useds rendering / UI,
// see webrtc/6366.
// Disabled due to being flaky due to the fact that it uses rendering / UI, see
// webrtc/6366.
TEST_F(ScreenCapturerTest, DISABLED_CaptureUpdatedRegionWithDirectxCapturer) {
if (!CreateDirectxCapturer()) {
return;
@ -367,8 +366,8 @@ TEST_F(ScreenCapturerTest, DISABLED_CaptureUpdatedRegionWithDirectxCapturer) {
TestCaptureUpdatedRegion();
}
// Disabled due to being flaky due to the fact that it useds rendering / UI,
// see webrtc/6366.
// Disabled due to being flaky due to the fact that it uses rendering / UI, see
// webrtc/6366.
TEST_F(ScreenCapturerTest, DISABLED_TwoDirectxCapturers) {
if (!CreateDirectxCapturer()) {
return;
@ -379,8 +378,15 @@ TEST_F(ScreenCapturerTest, DISABLED_TwoDirectxCapturers) {
TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()});
}
// Disabled due to being flaky due to the fact that it useds rendering / UI,
// see webrtc/6366.
// Disabled due to being flaky due to the fact that it uses rendering / UI, see
// webrtc/6366.
TEST_F(ScreenCapturerTest, DISABLED_CaptureUpdatedRegionWithMagnifierCapturer) {
CreateMagnifierCapturer();
TestCaptureUpdatedRegion();
}
// Disabled due to being flaky due to the fact that it uses rendering / UI, see
// webrtc/6366.
TEST_F(ScreenCapturerTest, DISABLED_TwoMagnifierCapturers) {
CreateMagnifierCapturer();
std::unique_ptr<ScreenCapturer> capturer2 = std::move(capturer_);
@ -388,8 +394,8 @@ 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.
// Disabled due to being flaky due to the fact that it uses rendering / UI, see
// webrtc/6366.
TEST_F(ScreenCapturerTest,
DISABLED_MaybeCaptureUpdatedRegionWithDirectxCapturer) {
// Even DirectX capturer is not supported in current system, we should be able

View File

@ -10,10 +10,9 @@
#include "webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h"
#include <assert.h>
#include <utility>
#include "webrtc/base/checks.h"
#include "webrtc/base/timeutils.h"
#include "webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "webrtc/modules/desktop_capture/desktop_frame.h"
@ -58,11 +57,15 @@ ScreenCapturerWinMagnifier::~ScreenCapturerWinMagnifier() {
}
void ScreenCapturerWinMagnifier::Start(Callback* callback) {
assert(!callback_);
assert(callback);
RTC_DCHECK(!callback_);
RTC_DCHECK(callback);
callback_ = callback;
InitializeMagnifier();
if (!InitializeMagnifier()) {
LOG_F(LS_WARNING) << "Switching to fallback screen capturer becuase "
"magnifier initialization failed.";
StartFallbackCapturer();
}
}
void ScreenCapturerWinMagnifier::SetSharedMemoryFactory(
@ -71,18 +74,21 @@ void ScreenCapturerWinMagnifier::SetSharedMemoryFactory(
}
void ScreenCapturerWinMagnifier::Capture(const DesktopRegion& region) {
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_->Capture(region);
return;
}
int64_t capture_start_time_nanos = rtc::TimeNanos();
queue_.MoveToNextFrame();
// Request that the system not power-down the system, or the display hardware.
if (!SetThreadExecutionState(ES_DISPLAY_REQUIRED | ES_SYSTEM_REQUIRED)) {
if (!set_thread_execution_state_failed_) {
set_thread_execution_state_failed_ = true;
LOG_F(LS_WARNING) << "Failed to make system & display power assertion: "
<< GetLastError();
}
}
// Switch to the desktop receiving user input if different from the current
// one.
std::unique_ptr<Desktop> input_desktop(Desktop::GetInputDesktop());
@ -97,22 +103,14 @@ void ScreenCapturerWinMagnifier::Capture(const DesktopRegion& region) {
desktop_.SetThreadDesktop(input_desktop.release());
}
bool succeeded = false;
// Do not try to use the magnifier if it failed before and in multi-screen
// setup (where the API crashes sometimes).
if (magnifier_initialized_ && (GetSystemMetrics(SM_CMONITORS) == 1) &&
magnifier_capture_succeeded_) {
DesktopRect rect = GetScreenRect(current_screen_id_, current_device_key_);
CreateCurrentFrameIfNecessary(rect.size());
// CaptureImage may fail in some situations, e.g. windows8 metro mode.
succeeded = CaptureImage(rect);
}
// Defer to the fallback capturer if magnifier capturer did not work.
if (!succeeded) {
LOG_F(LS_WARNING) << "Switching to the fallback screen capturer.";
DesktopRect rect = GetScreenRect(current_screen_id_, current_device_key_);
queue_.MoveToNextFrame();
CreateCurrentFrameIfNecessary(rect.size());
// 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_->Capture(region);
return;
@ -120,6 +118,7 @@ void ScreenCapturerWinMagnifier::Capture(const DesktopRegion& region) {
const DesktopFrame* current_frame = queue_.current_frame();
const DesktopFrame* last_frame = queue_.previous_frame();
DesktopRegion updated_region;
if (last_frame && last_frame->size().equals(current_frame->size())) {
// Make sure the differencer is set up correctly for these previous and
// current screens.
@ -133,24 +132,17 @@ void ScreenCapturerWinMagnifier::Capture(const DesktopRegion& region) {
}
// Calculate difference between the two last captured frames.
DesktopRegion region;
differ_->CalcDirtyRegion(
last_frame->data(), current_frame->data(), &region);
helper_.InvalidateRegion(region);
last_frame->data(), current_frame->data(), &updated_region);
} else {
// No previous frame is available, or the screen is resized. Invalidate the
// whole screen.
helper_.InvalidateScreen(current_frame->size());
updated_region.SetRect(DesktopRect::MakeSize(current_frame->size()));
}
helper_.set_size_most_recent(current_frame->size());
// Emit the current frame.
std::unique_ptr<DesktopFrame> frame = queue_.current_frame()->Share();
frame->set_dpi(DesktopVector(GetDeviceCaps(desktop_dc_, LOGPIXELSX),
GetDeviceCaps(desktop_dc_, LOGPIXELSY)));
frame->mutable_updated_region()->Clear();
helper_.TakeInvalidRegion(frame->mutable_updated_region());
frame->mutable_updated_region()->Swap(&updated_region);
frame->set_capture_time_ms((rtc::TimeNanos() - capture_start_time_nanos) /
rtc::kNumNanosecsPerMillisec);
callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
@ -183,7 +175,7 @@ void ScreenCapturerWinMagnifier::SetExcludedWindow(WindowId excluded_window) {
}
bool ScreenCapturerWinMagnifier::CaptureImage(const DesktopRect& rect) {
assert(magnifier_initialized_);
RTC_DCHECK(magnifier_initialized_);
// Set the magnifier control to cover the captured rect. The content of the
// magnifier control will be the captured image.
@ -200,6 +192,8 @@ bool ScreenCapturerWinMagnifier::CaptureImage(const DesktopRect& rect) {
RECT native_rect = {rect.left(), rect.top(), rect.right(), rect.bottom()};
RTC_DCHECK(tls_index_.Value() != static_cast<int32_t>(TLS_OUT_OF_INDEXES));
TlsSetValue(tls_index_.Value(), this);
// OnCaptured will be called via OnMagImageScalingCallback and fill in the
// frame before set_window_source_func_ returns.
result = set_window_source_func_(magnifier_window_, native_rect);
@ -223,20 +217,21 @@ BOOL ScreenCapturerWinMagnifier::OnMagImageScalingCallback(
RECT unclipped,
RECT clipped,
HRGN dirty) {
assert(tls_index_.Value() != static_cast<int32_t>(TLS_OUT_OF_INDEXES));
RTC_DCHECK(tls_index_.Value() != static_cast<int32_t>(TLS_OUT_OF_INDEXES));
ScreenCapturerWinMagnifier* owner =
reinterpret_cast<ScreenCapturerWinMagnifier*>(
TlsGetValue(tls_index_.Value()));
TlsSetValue(tls_index_.Value(), nullptr);
owner->OnCaptured(srcdata, srcheader);
return TRUE;
}
// TODO(zijiehe): These functions are available on Windows Vista or upper, so we
// do not need to use LoadLibrary and GetProcAddress anymore. Use regular
// include and function calls instead of a dynamical loaded library.
bool ScreenCapturerWinMagnifier::InitializeMagnifier() {
assert(!magnifier_initialized_);
RTC_DCHECK(!magnifier_initialized_);
desktop_dc_ = GetDC(nullptr);
mag_lib_handle_ = LoadLibrary(L"Magnification.dll");
@ -353,9 +348,6 @@ bool ScreenCapturerWinMagnifier::InitializeMagnifier() {
TlsFree(new_tls_index);
}
assert(tls_index_.Value() != static_cast<int32_t>(TLS_OUT_OF_INDEXES));
TlsSetValue(tls_index_.Value(), this);
magnifier_initialized_ = true;
return true;
}
@ -407,7 +399,7 @@ void ScreenCapturerWinMagnifier::CreateCurrentFrameIfNecessary(
}
void ScreenCapturerWinMagnifier::StartFallbackCapturer() {
assert(fallback_capturer_);
RTC_DCHECK(fallback_capturer_);
if (!fallback_capturer_started_) {
fallback_capturer_started_ = true;

View File

@ -113,19 +113,12 @@ class ScreenCapturerWinMagnifier : public ScreenCapturer {
std::wstring current_device_key_;
HWND excluded_window_ = NULL;
// A thread-safe list of invalid rectangles, and the size of the most
// recently captured screen.
ScreenCapturerHelper helper_;
// Queue of the frames buffers.
ScreenCaptureFrameQueue<SharedDesktopFrame> queue_;
// Class to calculate the difference between two screen bitmaps.
std::unique_ptr<Differ> differ_;
// Used to suppress duplicate logging of SetThreadExecutionState errors.
bool set_thread_execution_state_failed_ = false;
ScopedThreadDesktop desktop_;
// Used for getting the screen dpi.