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}
This commit is contained in:
zijiehe
2016-12-07 12:40:17 -08:00
committed by Commit bot
parent c4adabf967
commit 2cd872a939

View File

@ -10,11 +10,10 @@
#include "webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.h"
#include <assert.h>
#include <utility>
#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<DesktopFrame> buffer = DesktopFrameWin::Create(
size, shared_memory_factory_.get(), desktop_dc_);
@ -213,16 +210,22 @@ bool ScreenCapturerWinGdi::CaptureImage() {
DesktopFrameWin* current = static_cast<DesktopFrameWin*>(
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