From cd66a771edd9a106adf3c819573e566f99aff50f Mon Sep 17 00:00:00 2001 From: Zijie He Date: Fri, 21 Jul 2017 14:13:46 -0700 Subject: [PATCH] Create new constructors and fields to support a better mouse cursor monitor Current implementation requires MouseCursorMonitor to understand the SourceId of a DesktopCapturer implementation. But SourceId has different meanings across various DesktopCapturer implementations. So this change decouples the MouseCursorMonitor from DesktopCapturer, i.e. it does not need to know DesktopCapturer anymore, instead it always returns the absolute position of the mouse cursor. In DesktopAndCursorComposer, it can use the newly added DesktopFrame::top_left() to decide the relative position of mouse cursor and the DesktopFrame. Bug: webrtc:7950 Change-Id: Idfbde5cb0f79ff0acf4ad1e9a0ac5126f1bb2e98 Reviewed-on: https://chromium-review.googlesource.com/575315 Commit-Queue: Zijie He Reviewed-by: Sergey Ulanov Cr-Commit-Position: refs/heads/master@{#19115} --- .../desktop_and_cursor_composer.cc | 13 ++++++++- .../desktop_and_cursor_composer.h | 15 ++++++++--- .../modules/desktop_capture/desktop_frame.cc | 14 ++++++++-- .../modules/desktop_capture/desktop_frame.h | 18 +++++++++++-- .../desktop_capture/mouse_cursor_monitor.h | 27 ++++++++++++++++--- .../mouse_cursor_monitor_mac.mm | 16 +++++++---- .../mouse_cursor_monitor_null.cc | 10 +++++++ .../mouse_cursor_monitor_win.cc | 8 ++++++ .../mouse_cursor_monitor_x11.cc | 12 +++++++-- 9 files changed, 115 insertions(+), 18 deletions(-) diff --git a/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc b/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc index c899a76801..eef8eaf479 100644 --- a/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc +++ b/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc @@ -12,9 +12,13 @@ #include +#include + #include "webrtc/modules/desktop_capture/desktop_capturer.h" #include "webrtc/modules/desktop_capture/desktop_frame.h" #include "webrtc/modules/desktop_capture/mouse_cursor.h" +#include "webrtc/modules/desktop_capture/mouse_cursor_monitor.h" +#include "webrtc/rtc_base/checks.h" #include "webrtc/rtc_base/constructormagic.h" namespace webrtc { @@ -130,9 +134,16 @@ DesktopAndCursorComposer::DesktopAndCursorComposer( MouseCursorMonitor* mouse_monitor) : desktop_capturer_(desktop_capturer), mouse_monitor_(mouse_monitor) { + RTC_DCHECK(desktop_capturer_); } -DesktopAndCursorComposer::~DesktopAndCursorComposer() {} +DesktopAndCursorComposer::DesktopAndCursorComposer( + std::unique_ptr desktop_capturer, + const DesktopCaptureOptions& options) + : DesktopAndCursorComposer(desktop_capturer.release(), + MouseCursorMonitor::Create(options).release()) {} + +DesktopAndCursorComposer::~DesktopAndCursorComposer() = default; void DesktopAndCursorComposer::Start(DesktopCapturer::Callback* callback) { callback_ = callback; diff --git a/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h b/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h index c5cc3aa188..a9da634beb 100644 --- a/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h +++ b/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h @@ -13,6 +13,7 @@ #include +#include "webrtc/modules/desktop_capture/desktop_capture_options.h" #include "webrtc/modules/desktop_capture/desktop_capturer.h" #include "webrtc/modules/desktop_capture/mouse_cursor_monitor.h" #include "webrtc/rtc_base/constructormagic.h" @@ -29,8 +30,16 @@ class DesktopAndCursorComposer : public DesktopCapturer, // renders it into the frames generated by |desktop_capturer|. If // |mouse_monitor| is NULL the frames are passed unmodified. Takes ownership // of both arguments. + // Deprecated: use the constructor below. DesktopAndCursorComposer(DesktopCapturer* desktop_capturer, - MouseCursorMonitor* mouse_monitor); + MouseCursorMonitor* mouse_monitor); + + // Creates a new blender that captures mouse cursor using + // MouseCursorMonitor::Create(options) and renders it into the frames + // generated by |desktop_capturer|. + DesktopAndCursorComposer(std::unique_ptr desktop_capturer, + const DesktopCaptureOptions& options); + ~DesktopAndCursorComposer() override; // DesktopCapturer interface. @@ -50,8 +59,8 @@ class DesktopAndCursorComposer : public DesktopCapturer, void OnMouseCursorPosition(MouseCursorMonitor::CursorState state, const DesktopVector& position) override; - std::unique_ptr desktop_capturer_; - std::unique_ptr mouse_monitor_; + const std::unique_ptr desktop_capturer_; + const std::unique_ptr mouse_monitor_; DesktopCapturer::Callback* callback_; diff --git a/webrtc/modules/desktop_capture/desktop_frame.cc b/webrtc/modules/desktop_capture/desktop_frame.cc index 6756718d64..12a49cb1ff 100644 --- a/webrtc/modules/desktop_capture/desktop_frame.cc +++ b/webrtc/modules/desktop_capture/desktop_frame.cc @@ -14,6 +14,7 @@ #include +#include "webrtc/modules/desktop_capture/desktop_geometry.h" #include "webrtc/rtc_base/checks.h" namespace webrtc { @@ -22,14 +23,23 @@ DesktopFrame::DesktopFrame(DesktopSize size, int stride, uint8_t* data, SharedMemory* shared_memory) + : DesktopFrame(DesktopRect::MakeSize(size), + stride, + data, + shared_memory) {} + +DesktopFrame::DesktopFrame(DesktopRect rect, + int stride, + uint8_t* data, + SharedMemory* shared_memory) : data_(data), shared_memory_(shared_memory), - size_(size), + rect_(rect), stride_(stride), capture_time_ms_(0), capturer_id_(DesktopCapturerId::kUnknown) {} -DesktopFrame::~DesktopFrame() {} +DesktopFrame::~DesktopFrame() = default; void DesktopFrame::CopyPixelsFrom(const uint8_t* src_buffer, int src_stride, const DesktopRect& dest_rect) { diff --git a/webrtc/modules/desktop_capture/desktop_frame.h b/webrtc/modules/desktop_capture/desktop_frame.h index cd60fcce62..c3f0d733c6 100644 --- a/webrtc/modules/desktop_capture/desktop_frame.h +++ b/webrtc/modules/desktop_capture/desktop_frame.h @@ -31,7 +31,14 @@ class DesktopFrame { virtual ~DesktopFrame(); // Size of the frame. - const DesktopSize& size() const { return size_; } + DesktopSize size() const { return rect_.size(); } + + // The top-left of the frame in full desktop coordinates. E.g. the top left + // monitor should start from (0, 0). + DesktopVector top_left() const { return rect_.top_left(); } + + // Rectangle covered by the frame. + const DesktopRect& rect() const { return rect_; } // Distance in the buffer between two neighboring rows in bytes. int stride() const { return stride_; } @@ -78,11 +85,18 @@ class DesktopFrame { } protected: + // Deprecated, use the constructor below. DesktopFrame(DesktopSize size, int stride, uint8_t* data, SharedMemory* shared_memory); + // Preferred. + DesktopFrame(DesktopRect rect, + int stride, + uint8_t* data, + SharedMemory* shared_memory); + // Ownership of the buffers is defined by the classes that inherit from this // class. They must guarantee that the buffer is not deleted before the frame // is deleted. @@ -90,7 +104,7 @@ class DesktopFrame { SharedMemory* const shared_memory_; private: - const DesktopSize size_; + const DesktopRect rect_; const int stride_; DesktopRegion updated_region_; diff --git a/webrtc/modules/desktop_capture/mouse_cursor_monitor.h b/webrtc/modules/desktop_capture/mouse_cursor_monitor.h index 24dfe72dfa..84edb79dff 100644 --- a/webrtc/modules/desktop_capture/mouse_cursor_monitor.h +++ b/webrtc/modules/desktop_capture/mouse_cursor_monitor.h @@ -11,6 +11,8 @@ #ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_MOUSE_CURSOR_MONITOR_H_ #define WEBRTC_MODULES_DESKTOP_CAPTURE_MOUSE_CURSOR_MONITOR_H_ +#include + #include "webrtc/modules/desktop_capture/desktop_capture_types.h" #include "webrtc/modules/desktop_capture/desktop_geometry.h" #include "webrtc/typedefs.h" @@ -24,6 +26,7 @@ class MouseCursor; // Captures mouse shape and position. class MouseCursorMonitor { public: + // Deprecated: CursorState will not be provided. enum CursorState { // Cursor on top of the window including window decorations. INSIDE, @@ -49,9 +52,19 @@ class MouseCursorMonitor { // Called in response to Capture(). |position| indicates cursor position // relative to the |window| specified in the constructor. + // Deprecated: use the following overload instead. virtual void OnMouseCursorPosition(CursorState state, const DesktopVector& position) = 0; + // Called in response to Capture(). |position| indicates cursor absolute + // position on the system in fullscreen coordinate, i.e. the top-left + // monitor always starts from (0, 0). + // TODO(zijiehe): Ensure all implementations return the absolute position. + // TODO(zijiehe): Make this function pure virtual after Chromium changes. + // TODO(zijiehe): Current this overload works correctly only when capturing + // mouse cursor against fullscreen. + virtual void OnMouseCursorPosition(const DesktopVector& position) {} + protected: virtual ~Callback() {} }; @@ -60,18 +73,26 @@ class MouseCursorMonitor { // Creates a capturer that notifies of mouse cursor events while the cursor is // over the specified window. + // + // Deprecated: use Create() function. static MouseCursorMonitor* CreateForWindow( const DesktopCaptureOptions& options, WindowId window); - // Creates a capturer that monitors the mouse cursor shape and position across - // the entire desktop. + // Creates a capturer that monitors the mouse cursor shape and position over + // the specified screen. // - // TODO(sergeyu): Provide a way to select a specific screen. + // Deprecated: use Create() function. static MouseCursorMonitor* CreateForScreen( const DesktopCaptureOptions& options, ScreenId screen); + // Creates a capturer that monitors the mouse cursor shape and position across + // the entire desktop. The capturer ensures that the top-left monitor starts + // from (0, 0). + static std::unique_ptr Create( + const DesktopCaptureOptions& options); + // Initializes the monitor with the |callback|, which must remain valid until // capturer is destroyed. virtual void Init(Callback* callback, Mode mode) = 0; diff --git a/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm b/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm index 7bf1a52392..7bb6b2ccf5 100644 --- a/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm +++ b/webrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm @@ -19,6 +19,7 @@ #include #include "webrtc/modules/desktop_capture/desktop_capture_options.h" +#include "webrtc/modules/desktop_capture/desktop_capture_types.h" #include "webrtc/modules/desktop_capture/desktop_frame.h" #include "webrtc/modules/desktop_capture/mac/desktop_configuration.h" #include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h" @@ -244,12 +245,11 @@ void MouseCursorMonitorMac::Capture() { position.subtract(configuration.bounds.top_left()); } } - if (state == INSIDE) { - // Convert Density Independent Pixel to physical pixel. - position = DesktopVector(round(position.x() * scale), - round(position.y() * scale)); - } + // Convert Density Independent Pixel to physical pixel. + position = DesktopVector(round(position.x() * scale), + round(position.y() * scale)); callback_->OnMouseCursorPosition(state, position); + callback_->OnMouseCursorPosition(position); } void MouseCursorMonitorMac::CaptureImage(float scale) { @@ -330,4 +330,10 @@ MouseCursorMonitor* MouseCursorMonitor::CreateForScreen( return new MouseCursorMonitorMac(options, kCGNullWindowID, screen); } +std::unique_ptr MouseCursorMonitor::Create( + const DesktopCaptureOptions& options) { + return std::unique_ptr( + CreateForScreen(options, kFullDesktopScreenId)); +} + } // namespace webrtc diff --git a/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc b/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc index 3a632cc0d9..6153fac1ac 100644 --- a/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc +++ b/webrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc @@ -12,6 +12,10 @@ #include +#include + +#include "webrtc/modules/desktop_capture/desktop_capture_types.h" + namespace webrtc { MouseCursorMonitor* MouseCursorMonitor::CreateForWindow( @@ -26,4 +30,10 @@ MouseCursorMonitor* MouseCursorMonitor::CreateForScreen( return NULL; } +std::unique_ptr MouseCursorMonitor::Create( + const DesktopCaptureOptions& options) { + return std::unique_ptr( + CreateForScreen(options, kFullDesktopScreenId)); +} + } // namespace webrtc diff --git a/webrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc b/webrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc index 83a581cdc2..ebf00ac6df 100644 --- a/webrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc +++ b/webrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc @@ -15,6 +15,7 @@ #include +#include "webrtc/modules/desktop_capture/desktop_capture_types.h" #include "webrtc/modules/desktop_capture/desktop_frame.h" #include "webrtc/modules/desktop_capture/desktop_geometry.h" #include "webrtc/modules/desktop_capture/mouse_cursor.h" @@ -162,6 +163,7 @@ void MouseCursorMonitorWin::Capture() { } callback_->OnMouseCursorPosition(inside ? INSIDE : OUTSIDE, position); + callback_->OnMouseCursorPosition(position); } DesktopRect MouseCursorMonitorWin::GetScreenRect() { @@ -204,4 +206,10 @@ MouseCursorMonitor* MouseCursorMonitor::CreateForScreen( return new MouseCursorMonitorWin(screen); } +std::unique_ptr MouseCursorMonitor::Create( + const DesktopCaptureOptions& options) { + return std::unique_ptr( + CreateForScreen(options, kFullDesktopScreenId)); +} + } // namespace webrtc diff --git a/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc b/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc index 795242e648..9b30c49831 100644 --- a/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc +++ b/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc @@ -17,6 +17,7 @@ #include #include "webrtc/modules/desktop_capture/desktop_capture_options.h" +#include "webrtc/modules/desktop_capture/desktop_capture_types.h" #include "webrtc/modules/desktop_capture/desktop_frame.h" #include "webrtc/modules/desktop_capture/mouse_cursor.h" #include "webrtc/modules/desktop_capture/x11/x_error_trap.h" @@ -200,8 +201,9 @@ void MouseCursorMonitorX11::Capture() { } } - callback_->OnMouseCursorPosition(state, - webrtc::DesktopVector(win_x, win_y)); + const DesktopVector position(win_x, win_y); + callback_->OnMouseCursorPosition(state, position); + callback_->OnMouseCursorPosition(position); } } @@ -268,4 +270,10 @@ MouseCursorMonitor* MouseCursorMonitor::CreateForScreen( options, DefaultRootWindow(options.x_display()->display())); } +std::unique_ptr MouseCursorMonitor::Create( + const DesktopCaptureOptions& options) { + return std::unique_ptr( + CreateForScreen(options, kFullDesktopScreenId)); +} + } // namespace webrtc