From 2cd872a9395219f4bf8e8898edc20d37f171b872 Mon Sep 17 00:00:00 2001 From: zijiehe Date: Wed, 7 Dec 2016 12:40:17 -0800 Subject: [PATCH] Log BitBlt failure BitBlt returns a BOOL value, which should be taken care in ScreenCapturerWinGdi. Meanwhile, this change also replaces assert() / abort() with RTC_DCHECK() / RTC_CHECK() / RTC_NOTREACHED(). This change cannot fix the bug, the reason of the issue is still unknown, but it is still the right thing to do. In ScreenCapturerIntegrationTest, each frame will be captured at most 600 times. Since the test case fails, which means the ScreenCapturerWinGdi consistently returns a white frame for 600 times under a certain state. With this change, instead of returning white frame, ScreenCapturerWinGdi will return a temporary error. But I do not think a ScreenCapturerWinGdi can automatically recover by retrying. BUG=webrtc:6843 Review-Url: https://codereview.webrtc.org/2553353002 Cr-Commit-Position: refs/heads/master@{#15465} --- .../win/screen_capturer_win_gdi.cc | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc b/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc index b22f0387f1..87bc195ce4 100644 --- a/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc +++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc @@ -10,11 +10,10 @@ #include "webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.h" -#include - #include #include "webrtc/base/checks.h" +#include "webrtc/base/logging.h" #include "webrtc/base/timeutils.h" #include "webrtc/modules/desktop_capture/desktop_capture_options.h" #include "webrtc/modules/desktop_capture/desktop_frame.h" @@ -110,8 +109,8 @@ bool ScreenCapturerWinGdi::SelectSource(SourceId id) { } void ScreenCapturerWinGdi::Start(Callback* callback) { - assert(!callback_); - assert(callback); + RTC_DCHECK(!callback_); + RTC_DCHECK(callback); callback_ = callback; @@ -169,15 +168,13 @@ void ScreenCapturerWinGdi::PrepareCaptureResources() { } if (!desktop_dc_) { - assert(!memory_dc_); + RTC_DCHECK(!memory_dc_); // Create GDI device contexts to capture from the desktop into memory. desktop_dc_ = GetDC(nullptr); - if (!desktop_dc_) - abort(); + RTC_CHECK(desktop_dc_); memory_dc_ = CreateCompatibleDC(desktop_dc_); - if (!memory_dc_) - abort(); + RTC_CHECK(memory_dc_); desktop_dc_rect_ = screen_rect; @@ -198,8 +195,8 @@ bool ScreenCapturerWinGdi::CaptureImage() { // may still be reading from them. if (!queue_.current_frame() || !queue_.current_frame()->size().equals(screen_rect.size())) { - assert(desktop_dc_); - assert(memory_dc_); + RTC_DCHECK(desktop_dc_); + RTC_DCHECK(memory_dc_); std::unique_ptr buffer = DesktopFrameWin::Create( size, shared_memory_factory_.get(), desktop_dc_); @@ -213,16 +210,22 @@ bool ScreenCapturerWinGdi::CaptureImage() { DesktopFrameWin* current = static_cast( queue_.current_frame()->GetUnderlyingFrame()); HGDIOBJ previous_object = SelectObject(memory_dc_, current->bitmap()); - if (previous_object) { - BitBlt(memory_dc_, 0, 0, screen_rect.width(), screen_rect.height(), - desktop_dc_, screen_rect.left(), screen_rect.top(), - SRCCOPY | CAPTUREBLT); - - // Select back the previously selected object to that the device contect - // could be destroyed independently of the bitmap if needed. - SelectObject(memory_dc_, previous_object); + if (!previous_object || previous_object == HGDI_ERROR) { + return false; } - return true; + + bool result = (BitBlt(memory_dc_, 0, 0, screen_rect.width(), + screen_rect.height(), desktop_dc_, screen_rect.left(), screen_rect.top(), + SRCCOPY | CAPTUREBLT) != FALSE); + if (!result) { + LOG_GLE(LS_WARNING) << "BitBlt failed"; + } + + // Select back the previously selected object to that the device contect + // could be destroyed independently of the bitmap if needed. + SelectObject(memory_dc_, previous_object); + + return result; } } // namespace webrtc