screencast_portal: Add option to choose cursor capture mode

Change adds a flag that can be used with desktop capture options
to specify how the cursor capture should be handled.

Bug: chromium:1291247
Change-Id: If8150f8412ade2b6216a65dd026ca528654f52bf
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/284780
Commit-Queue: Salman Malik <salmanmalik@chromium.org>
Reviewed-by: Alexander Cooper <alcooper@chromium.org>
Cr-Commit-Position: refs/heads/main@{#38721}
This commit is contained in:
Salman
2022-11-23 21:14:55 +00:00
committed by WebRTC LUCI CQ
parent fc5d709e41
commit 7216b27406
6 changed files with 39 additions and 9 deletions

View File

@ -105,6 +105,17 @@ class RTC_EXPORT DesktopCaptureOptions {
detect_updated_region_ = detect_updated_region;
}
// Indicates that the capturer should try to include the cursor in the frame.
// If it is able to do so it will set `DesktopFrame::may_contain_cursor()`.
// Not all capturers will support including the cursor. If this value is false
// or the cursor otherwise cannot be included in the frame, then cursor
// metadata will be sent, though the capturer may choose to always send cursor
// metadata.
bool prefer_cursor_embedded() const { return prefer_cursor_embedded_; }
void set_prefer_cursor_embedded(bool prefer_cursor_embedded) {
prefer_cursor_embedded_ = prefer_cursor_embedded;
}
#if defined(WEBRTC_WIN)
// Enumerating windows owned by the current process on Windows has some
// complications due to |GetWindowText*()| APIs potentially causing a
@ -237,6 +248,7 @@ class RTC_EXPORT DesktopCaptureOptions {
#endif
bool disable_effects_ = true;
bool detect_updated_region_ = false;
bool prefer_cursor_embedded_ = false;
#if defined(WEBRTC_USE_PIPEWIRE)
bool allow_pipewire_ = false;
bool pipewire_use_damage_region_ = true;

View File

@ -72,7 +72,8 @@ void BaseCapturerPipeWire::OnScreenCastRequestResult(RequestResponse result,
capturer_failed_ = false;
if (result != RequestResponse::kSuccess ||
!options_.screencast_stream()->StartScreenCastStream(
stream_node_id, fd, options_.get_width(), options_.get_height())) {
stream_node_id, fd, options_.get_width(), options_.get_height(),
options_.prefer_cursor_embedded())) {
capturer_failed_ = true;
RTC_LOG(LS_ERROR) << "ScreenCastPortal failed: "
<< static_cast<uint>(result);

View File

@ -56,9 +56,12 @@ ScreenCastPortal::ScreenCastPortal(
PortalNotifier* notifier,
ProxyRequestResponseHandler proxy_request_response_handler,
SourcesRequestResponseSignalHandler sources_request_response_signal_handler,
gpointer user_data)
gpointer user_data,
bool prefer_cursor_embedded)
: notifier_(notifier),
capture_source_type_(ToCaptureSourceType(type)),
cursor_mode_(prefer_cursor_embedded ? CursorMode::kEmbedded
: CursorMode::kMetadata),
proxy_request_response_handler_(proxy_request_response_handler),
sources_request_response_signal_handler_(
sources_request_response_signal_handler),

View File

@ -84,7 +84,10 @@ class ScreenCastPortal : public xdg_portal::ScreenCapturePortalInterface {
ProxyRequestResponseHandler proxy_request_response_handler,
SourcesRequestResponseSignalHandler
sources_request_response_signal_handler,
gpointer user_data);
gpointer user_data,
// TODO(chromium:1291247): Remove the default option once
// downstream has been adjusted.
bool prefer_cursor_embedded = false);
~ScreenCastPortal();
@ -140,7 +143,7 @@ class ScreenCastPortal : public xdg_portal::ScreenCapturePortalInterface {
CaptureSourceType capture_source_type_ =
ScreenCastPortal::CaptureSourceType::kScreen;
CursorMode cursor_mode_ = ScreenCastPortal::CursorMode::kMetadata;
CursorMode cursor_mode_ = CursorMode::kMetadata;
PersistMode persist_mode_ = ScreenCastPortal::PersistMode::kDoNotPersist;

View File

@ -77,7 +77,8 @@ class SharedScreenCastStreamPrivate {
bool StartScreenCastStream(uint32_t stream_node_id,
int fd,
uint32_t width = 0,
uint32_t height = 0);
uint32_t height = 0,
bool is_cursor_embedded = false);
void UpdateScreenCastStreamResolution(uint32_t width, uint32_t height);
void SetUseDamageRegion(bool use_damage_region) {
use_damage_region_ = use_damage_region;
@ -143,6 +144,10 @@ class SharedScreenCastStreamPrivate {
bool use_damage_region_ = true;
// Specifies whether the pipewire stream has been initialized with a request
// to embed cursor into the captured frames.
bool is_cursor_embedded_ = false;
// event handlers
pw_core_events pw_core_events_ = {};
pw_stream_events pw_stream_events_ = {};
@ -380,9 +385,11 @@ bool SharedScreenCastStreamPrivate::StartScreenCastStream(
uint32_t stream_node_id,
int fd,
uint32_t width,
uint32_t height) {
uint32_t height,
bool is_cursor_embedded) {
width_ = width;
height_ = height;
is_cursor_embedded_ = is_cursor_embedded;
if (!InitializePipeWire()) {
RTC_LOG(LS_ERROR) << "Unable to open PipeWire library";
return false;
@ -875,6 +882,7 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
queue_.current_frame()->mutable_updated_region()->SetRect(
DesktopRect::MakeSize(queue_.current_frame()->size()));
}
queue_.current_frame()->set_may_contain_cursor(is_cursor_embedded_);
}
void SharedScreenCastStreamPrivate::ConvertRGBxToBGRx(uint8_t* frame,
@ -906,8 +914,10 @@ bool SharedScreenCastStream::StartScreenCastStream(uint32_t stream_node_id) {
bool SharedScreenCastStream::StartScreenCastStream(uint32_t stream_node_id,
int fd,
uint32_t width,
uint32_t height) {
return private_->StartScreenCastStream(stream_node_id, fd, width, height);
uint32_t height,
bool is_cursor_embedded) {
return private_->StartScreenCastStream(stream_node_id, fd, width, height,
is_cursor_embedded);
}
void SharedScreenCastStream::UpdateScreenCastStreamResolution(uint32_t width,

View File

@ -47,7 +47,8 @@ class RTC_EXPORT SharedScreenCastStream
bool StartScreenCastStream(uint32_t stream_node_id,
int fd,
uint32_t width = 0,
uint32_t height = 0);
uint32_t height = 0,
bool is_cursor_embedded = false);
void UpdateScreenCastStreamResolution(uint32_t width, uint32_t height);
void SetUseDamageRegion(bool use_damage_region);
void SetObserver(SharedScreenCastStream::Observer* observer);