Attach top-left to DesktopFrames generated by DesktopCapturer implementations
This change attaches top-left to the DesktopFrames generated by DesktopCapturer
implementations. Some implementations won't need to attach the top-left because
of the platform specification, e.g. coordinates in X11 always starts from
(0, 0), and we support only one screen.
After this change, we can use the new MouseCursorMonitor::Create() function in
DesktopCaptureDevice.
Bug: webrtc:7950
Change-Id: I82c24f4dd9451e32afafb6474f82c32cadcb425c
Reviewed-on: https://chromium-review.googlesource.com/644787
Reviewed-by: Jamie Walch <jamiewalch@chromium.org>
Commit-Queue: Zijie He <zijiehe@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#19675}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 7fdf857d261539b4c03c90ddab1b1256b099dc6a
diff --git a/modules/desktop_capture/mac/window_list_utils.cc b/modules/desktop_capture/mac/window_list_utils.cc
index 10c12c1..0bd6d5a 100644
--- a/modules/desktop_capture/mac/window_list_utils.cc
+++ b/modules/desktop_capture/mac/window_list_utils.cc
@@ -21,6 +21,44 @@
namespace webrtc {
+namespace {
+
+// Get CFDictionaryRef from |id| and call |on_window| against it. This function
+// returns false if native APIs fail, typically it indicates that the |id| does
+// not represent a window. |on_window| will not be called if false is returned
+// from this function.
+bool GetWindowRef(CGWindowID id,
+ rtc::FunctionView<void(CFDictionaryRef)> on_window) {
+ RTC_DCHECK(on_window);
+
+ // TODO(zijiehe): |id| is a 32-bit integer, casting it to an array seems not
+ // safe enough. Maybe we should create a new
+ // const void* arr[] = {
+ // reinterpret_cast<void*>(id) }
+ // };
+ CFArrayRef window_id_array =
+ CFArrayCreate(NULL, reinterpret_cast<const void**>(&id), 1, NULL);
+ CFArrayRef window_array =
+ CGWindowListCreateDescriptionFromArray(window_id_array);
+
+ bool result = false;
+ // TODO(zijiehe): CFArrayGetCount(window_array) should always return 1.
+ // Otherwise, we should treat it as failure.
+ if (window_array && CFArrayGetCount(window_array)) {
+ on_window(reinterpret_cast<CFDictionaryRef>(
+ CFArrayGetValueAtIndex(window_array, 0)));
+ result = true;
+ }
+
+ if (window_array) {
+ CFRelease(window_array);
+ }
+ CFRelease(window_id_array);
+ return result;
+}
+
+} // namespace
+
bool GetWindowList(rtc::FunctionView<bool(CFDictionaryRef)> on_window,
bool ignore_minimized) {
RTC_DCHECK(on_window);
@@ -145,21 +183,14 @@
}
bool IsWindowOnScreen(CGWindowID id) {
- CFArrayRef window_id_array =
- CFArrayCreate(NULL, reinterpret_cast<const void **>(&id), 1, NULL);
- CFArrayRef window_array =
- CGWindowListCreateDescriptionFromArray(window_id_array);
- bool on_screen = false;
-
- if (window_array && CFArrayGetCount(window_array)) {
- on_screen = IsWindowOnScreen(reinterpret_cast<CFDictionaryRef>(
- CFArrayGetValueAtIndex(window_array, 0)));
+ bool on_screen;
+ if (GetWindowRef(id,
+ [&on_screen](CFDictionaryRef window) {
+ on_screen = IsWindowOnScreen(window);
+ })) {
+ return on_screen;
}
-
- CFRelease(window_id_array);
- CFRelease(window_array);
-
- return on_screen;
+ return false;
}
std::string GetWindowTitle(CFDictionaryRef window) {
@@ -205,4 +236,15 @@
gc_window_rect.size.height);
}
+DesktopRect GetWindowBounds(CGWindowID id) {
+ DesktopRect result;
+ if (GetWindowRef(id,
+ [&result](CFDictionaryRef window) {
+ result = GetWindowBounds(window);
+ })) {
+ return result;
+ }
+ return DesktopRect();
+}
+
} // namespace webrtc
diff --git a/modules/desktop_capture/mac/window_list_utils.h b/modules/desktop_capture/mac/window_list_utils.h
index 5e204a7..be7aeea 100644
--- a/modules/desktop_capture/mac/window_list_utils.h
+++ b/modules/desktop_capture/mac/window_list_utils.h
@@ -58,6 +58,11 @@
// from (0, 0).
DesktopRect GetWindowBounds(CFDictionaryRef window);
+// Returns the bounds of window with |id|. If |id| does not represent a window
+// or the bounds cannot be retrieved, this function returns an empty
+// DesktopRect. The returned DesktopRect is in system coordinates.
+DesktopRect GetWindowBounds(CGWindowID id);
+
} // namespace webrtc
#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_MAC_WINDOW_LIST_UTILS_H_
diff --git a/modules/desktop_capture/screen_capturer_mac.mm b/modules/desktop_capture/screen_capturer_mac.mm
index 66b04f7..9fab819 100644
--- a/modules/desktop_capture/screen_capturer_mac.mm
+++ b/modules/desktop_capture/screen_capturer_mac.mm
@@ -373,9 +373,7 @@
frame->data() + (frame->size().height() - 1) * frame->stride(),
frame->shared_memory()) {
original_frame_ = std::move(frame);
- set_dpi(original_frame_->dpi());
- set_capture_time_ms(original_frame_->capture_time_ms());
- mutable_updated_region()->Swap(original_frame_->mutable_updated_region());
+ MoveFrameInfoFrom(original_frame_.get());
}
~InvertedDesktopFrame() override {}
@@ -494,6 +492,15 @@
if (flip)
new_frame.reset(new InvertedDesktopFrame(std::move(new_frame)));
+ if (current_display_) {
+ const MacDisplayConfiguration* config =
+ desktop_config_.FindDisplayConfigurationById(current_display_);
+ if (config) {
+ new_frame->set_top_left(config->bounds.top_left().subtract(
+ desktop_config_.bounds.top_left()));
+ }
+ }
+
helper_.set_size_most_recent(new_frame->size());
// Signal that we are done capturing data from the display framebuffer,
diff --git a/modules/desktop_capture/win/dxgi_duplicator_controller.cc b/modules/desktop_capture/win/dxgi_duplicator_controller.cc
index 4a6ab8e..38bf437 100644
--- a/modules/desktop_capture/win/dxgi_duplicator_controller.cc
+++ b/modules/desktop_capture/win/dxgi_duplicator_controller.cc
@@ -333,6 +333,7 @@
} else {
if (duplicators_[i].DuplicateMonitor(&context->contexts[i], monitor_id,
target)) {
+ target->set_top_left(duplicators_[i].ScreenRect(monitor_id).top_left());
return true;
}
return false;
diff --git a/modules/desktop_capture/win/screen_capturer_win_gdi.cc b/modules/desktop_capture/win/screen_capturer_win_gdi.cc
index 427cb93..b342e9f 100644
--- a/modules/desktop_capture/win/screen_capturer_win_gdi.cc
+++ b/modules/desktop_capture/win/screen_capturer_win_gdi.cc
@@ -195,6 +195,7 @@
return false;
queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(buffer)));
}
+ queue_.current_frame()->set_top_left(screen_rect.top_left());
// Select the target bitmap into the memory dc and copy the rect from desktop
// to memory.
diff --git a/modules/desktop_capture/window_capturer_mac.mm b/modules/desktop_capture/window_capturer_mac.mm
index 4f1c191..fa1ddcd 100644
--- a/modules/desktop_capture/window_capturer_mac.mm
+++ b/modules/desktop_capture/window_capturer_mac.mm
@@ -204,6 +204,14 @@
frame->mutable_updated_region()->SetRect(
DesktopRect::MakeSize(frame->size()));
+ DesktopVector top_left = GetWindowBounds(on_screen_window).top_left();
+ if (configuration_monitor_) {
+ configuration_monitor_->Lock();
+ auto configuration = configuration_monitor_->desktop_configuration();
+ configuration_monitor_->Unlock();
+ top_left = top_left.subtract(configuration.bounds.top_left());
+ }
+ frame->set_top_left(top_left);
callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
diff --git a/modules/desktop_capture/window_capturer_win.cc b/modules/desktop_capture/window_capturer_win.cc
index 77a6cce..01b4e4d 100644
--- a/modules/desktop_capture/window_capturer_win.cc
+++ b/modules/desktop_capture/window_capturer_win.cc
@@ -316,6 +316,8 @@
frame->mutable_updated_region()->SetRect(
DesktopRect::MakeSize(frame->size()));
+ frame->set_top_left(
+ cropped_rect.top_left().subtract(GetFullscreenRect().top_left()));
if (result) {
callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
diff --git a/modules/desktop_capture/window_capturer_x11.cc b/modules/desktop_capture/window_capturer_x11.cc
index 5d01a15..987ceb7 100644
--- a/modules/desktop_capture/window_capturer_x11.cc
+++ b/modules/desktop_capture/window_capturer_x11.cc
@@ -216,6 +216,7 @@
frame->mutable_updated_region()->SetRect(
DesktopRect::MakeSize(frame->size()));
+ frame->set_top_left(x_server_pixel_buffer_.window_rect().top_left());
callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
}