Update XServerPixelBuffer to handle errors returned from XGetImage().
XGetImage() may return NULL and XServerPixelBuffer wasn't handling this case properly. BUG=649487 Review-Url: https://codereview.webrtc.org/2446733003 Cr-Commit-Position: refs/heads/master@{#14754}
This commit is contained in:
@ -256,6 +256,11 @@ void ScreenCapturerLinux::CaptureFrame() {
|
||||
}
|
||||
|
||||
std::unique_ptr<DesktopFrame> result = CaptureScreen();
|
||||
if (!result) {
|
||||
callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
last_invalid_region_ = result->updated_region();
|
||||
result->set_capture_time_ms((rtc::TimeNanos() - capture_start_time_nanos) /
|
||||
rtc::kNumNanosecsPerMillisec);
|
||||
@ -334,7 +339,8 @@ std::unique_ptr<DesktopFrame> ScreenCapturerLinux::CaptureScreen() {
|
||||
|
||||
for (DesktopRegion::Iterator it(*updated_region);
|
||||
!it.IsAtEnd(); it.Advance()) {
|
||||
x_server_pixel_buffer_.CaptureRect(it.rect(), frame.get());
|
||||
if (!x_server_pixel_buffer_.CaptureRect(it.rect(), frame.get()))
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
// Doing full-screen polling, or this is the first capture after a
|
||||
|
||||
@ -293,8 +293,11 @@ void WindowCapturerLinux::CaptureFrame() {
|
||||
new BasicDesktopFrame(x_server_pixel_buffer_.window_size()));
|
||||
|
||||
x_server_pixel_buffer_.Synchronize();
|
||||
x_server_pixel_buffer_.CaptureRect(DesktopRect::MakeSize(frame->size()),
|
||||
frame.get());
|
||||
if (!x_server_pixel_buffer_.CaptureRect(DesktopRect::MakeSize(frame->size()),
|
||||
frame.get())) {
|
||||
callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
frame->mutable_updated_region()->SetRect(
|
||||
DesktopRect::MakeSize(frame->size()));
|
||||
|
||||
@ -231,7 +231,7 @@ void XServerPixelBuffer::Synchronize() {
|
||||
}
|
||||
}
|
||||
|
||||
void XServerPixelBuffer::CaptureRect(const DesktopRect& rect,
|
||||
bool XServerPixelBuffer::CaptureRect(const DesktopRect& rect,
|
||||
DesktopFrame* frame) {
|
||||
assert(rect.right() <= window_size_.width());
|
||||
assert(rect.bottom() <= window_size_.height());
|
||||
@ -253,6 +253,9 @@ void XServerPixelBuffer::CaptureRect(const DesktopRect& rect,
|
||||
XDestroyImage(x_image_);
|
||||
x_image_ = XGetImage(display_, window_, rect.left(), rect.top(),
|
||||
rect.width(), rect.height(), AllPlanes, ZPixmap);
|
||||
if (!x_image_)
|
||||
return false;
|
||||
|
||||
data = reinterpret_cast<uint8_t*>(x_image_->data);
|
||||
}
|
||||
|
||||
@ -261,6 +264,8 @@ void XServerPixelBuffer::CaptureRect(const DesktopRect& rect,
|
||||
} else {
|
||||
SlowBlit(data, rect, frame);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void XServerPixelBuffer::FastBlit(uint8_t* image,
|
||||
|
||||
@ -55,7 +55,7 @@ class XServerPixelBuffer {
|
||||
// where the full-screen data is captured by Synchronize(), this simply
|
||||
// returns the pointer without doing any more work. The caller must ensure
|
||||
// that |rect| is not larger than window_size().
|
||||
void CaptureRect(const DesktopRect& rect, DesktopFrame* frame);
|
||||
bool CaptureRect(const DesktopRect& rect, DesktopFrame* frame);
|
||||
|
||||
private:
|
||||
void InitShm(const XWindowAttributes& attributes);
|
||||
|
||||
Reference in New Issue
Block a user