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:
@ -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
|
||||
|
||||
Reference in New Issue
Block a user