Returns a NULL frame on all platforms if the captured window is closed.
Part of the fix for crbug/360181. On Mac/Linux, it previously continues capturing even if the window is closed. Now it stops by returning a NULL frame. On Windows, it used to stop capturing when the window is minimized. Now fixed to match other platforms. Note: the crbug still needs a chrome side fix to close the notification bar. This fix only stops the stream (i.e. stream onended event fired). BUG=crbug/360181 TESTED=manually tested in Chrome R=sergeyu@chromium.org Review URL: https://webrtc-codereview.appspot.com/12329007 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5977 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
cd70119a10
commit
cc1ba15fe7
@ -42,6 +42,18 @@ bool CFStringRefToUtf8(const CFStringRef string, std::string* str_utf8) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsWindowValid(CGWindowID id) {
|
||||
CFArrayRef window_id_array =
|
||||
CFArrayCreate(NULL, reinterpret_cast<const void **>(&id), 1, NULL);
|
||||
CFArrayRef window_array =
|
||||
CGWindowListCreateDescriptionFromArray(window_id_array);
|
||||
bool valid = window_array && CFArrayGetCount(window_array);
|
||||
CFRelease(window_id_array);
|
||||
CFRelease(window_array);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
class WindowCapturerMac : public WindowCapturer {
|
||||
public:
|
||||
WindowCapturerMac();
|
||||
@ -115,22 +127,8 @@ bool WindowCapturerMac::GetWindowList(WindowList* windows) {
|
||||
}
|
||||
|
||||
bool WindowCapturerMac::SelectWindow(WindowId id) {
|
||||
// Request description for the specified window to make sure |id| is valid.
|
||||
CGWindowID ids[1];
|
||||
ids[0] = id;
|
||||
CFArrayRef window_id_array =
|
||||
CFArrayCreate(NULL, reinterpret_cast<const void **>(&ids), 1, NULL);
|
||||
CFArrayRef window_array =
|
||||
CGWindowListCreateDescriptionFromArray(window_id_array);
|
||||
int results_count = window_array ? CFArrayGetCount(window_array) : 0;
|
||||
CFRelease(window_id_array);
|
||||
CFRelease(window_array);
|
||||
|
||||
if (results_count == 0) {
|
||||
// Could not find the window. It might have been closed.
|
||||
if (!IsWindowValid(id))
|
||||
return false;
|
||||
}
|
||||
|
||||
window_id_ = id;
|
||||
return true;
|
||||
}
|
||||
@ -180,6 +178,11 @@ void WindowCapturerMac::Start(Callback* callback) {
|
||||
}
|
||||
|
||||
void WindowCapturerMac::Capture(const DesktopRegion& region) {
|
||||
if (!IsWindowValid(window_id_)) {
|
||||
callback_->OnCaptureCompleted(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
CGImageRef window_image = CGWindowListCreateImage(
|
||||
CGRectNull, kCGWindowListOptionIncludingWindow,
|
||||
window_id_, kCGWindowImageBoundsIgnoreFraming);
|
||||
|
||||
@ -182,8 +182,8 @@ void WindowCapturerWin::Capture(const DesktopRegion& region) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop capturing if the window has been minimized or hidden.
|
||||
if (IsIconic(window_) || !IsWindowVisible(window_)) {
|
||||
// Stop capturing if the window has been closed or hidden.
|
||||
if (!IsWindow(window_) || !IsWindowVisible(window_)) {
|
||||
callback_->OnCaptureCompleted(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -278,6 +278,12 @@ void WindowCapturerLinux::Start(Callback* callback) {
|
||||
}
|
||||
|
||||
void WindowCapturerLinux::Capture(const DesktopRegion& region) {
|
||||
if (!x_server_pixel_buffer_.IsWindowValid()) {
|
||||
LOG(LS_INFO) << "The window is no longer valid.";
|
||||
callback_->OnCaptureCompleted(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
x_display_->ProcessPendingXEvents();
|
||||
|
||||
if (!has_composite_extension_) {
|
||||
|
||||
@ -213,6 +213,18 @@ bool XServerPixelBuffer::InitPixmaps(int depth) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool XServerPixelBuffer::IsWindowValid() const {
|
||||
XWindowAttributes attributes;
|
||||
{
|
||||
XErrorTrap error_trap(display_);
|
||||
if (!XGetWindowAttributes(display_, window_, &attributes) ||
|
||||
error_trap.GetLastErrorAndDisable() != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void XServerPixelBuffer::Synchronize() {
|
||||
if (shm_segment_info_ && !shm_pixmap_) {
|
||||
// XShmGetImage can fail if the display is being reconfigured.
|
||||
|
||||
@ -40,6 +40,9 @@ class XServerPixelBuffer {
|
||||
// Returns the size of the window the buffer was initialized for.
|
||||
const DesktopSize& window_size() { return window_size_; }
|
||||
|
||||
// Returns true if the window can be found.
|
||||
bool IsWindowValid() const;
|
||||
|
||||
// If shared memory is being used without pixmaps, synchronize this pixel
|
||||
// buffer with the root window contents (otherwise, this is a no-op).
|
||||
// This is to avoid doing a full-screen capture for each individual
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user