From f71315c480f9450ad2bb14a068b38fd47b23c8d8 Mon Sep 17 00:00:00 2001 From: Salman Malik Date: Mon, 23 May 2022 20:17:54 +0000 Subject: [PATCH] Wayland: Allow setting custom resolution This CL allows the users to propose custom resolution to server for the captured pipewire streams. Bug: chromium:1291247 Change-Id: Iaae2c73df1a5f5ebac651ce7d087af4c273113c4 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/263360 Reviewed-by: Alexander Cooper Commit-Queue: Salman Malik Cr-Commit-Position: refs/heads/main@{#36979} --- .../desktop_capture/desktop_capture_options.h | 8 ++++++ .../linux/wayland/base_capturer_pipewire.cc | 4 +-- .../linux/wayland/shared_screencast_stream.cc | 25 ++++++++++++++----- .../linux/wayland/shared_screencast_stream.h | 5 +++- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/modules/desktop_capture/desktop_capture_options.h b/modules/desktop_capture/desktop_capture_options.h index dd3cde0145..4ee5259bb4 100644 --- a/modules/desktop_capture/desktop_capture_options.h +++ b/modules/desktop_capture/desktop_capture_options.h @@ -188,6 +188,12 @@ class RTC_EXPORT DesktopCaptureOptions { rtc::scoped_refptr stream) { screencast_stream_ = stream; } + + void set_width(uint32_t width) { width_ = width; } + uint32_t get_width() const { return width_; } + + void set_height(uint32_t height) { height_ = height; } + uint32_t get_height() const { return height_; } #endif private: @@ -226,6 +232,8 @@ class RTC_EXPORT DesktopCaptureOptions { bool detect_updated_region_ = false; #if defined(WEBRTC_USE_PIPEWIRE) bool allow_pipewire_ = false; + uint32_t width_ = 0; + uint32_t height_ = 0; #endif }; diff --git a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc index 0fc90e0e8d..678f350f89 100644 --- a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc +++ b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc @@ -44,8 +44,8 @@ void BaseCapturerPipeWire::OnScreenCastRequestResult(RequestResponse result, uint32_t stream_node_id, int fd) { if (result != RequestResponse::kSuccess || - !options_.screencast_stream()->StartScreenCastStream(stream_node_id, - fd)) { + !options_.screencast_stream()->StartScreenCastStream( + stream_node_id, fd, options_.get_width(), options_.get_height())) { capturer_failed_ = true; RTC_LOG(LS_ERROR) << "ScreenCastPortal failed: " << static_cast(result); diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc index 644569fd76..deb85a8580 100644 --- a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc +++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc @@ -85,7 +85,10 @@ class SharedScreenCastStreamPrivate { SharedScreenCastStreamPrivate(); ~SharedScreenCastStreamPrivate(); - bool StartScreenCastStream(uint32_t stream_node_id, int fd); + bool StartScreenCastStream(uint32_t stream_node_id, + int fd, + uint32_t width = 0, + uint32_t height = 0); void StopScreenCastStream(); std::unique_ptr CaptureFrame(); std::unique_ptr CaptureCursor(); @@ -368,7 +371,9 @@ SharedScreenCastStreamPrivate::~SharedScreenCastStreamPrivate() { RTC_NO_SANITIZE("cfi-icall") bool SharedScreenCastStreamPrivate::StartScreenCastStream( uint32_t stream_node_id, - int fd) { + int fd, + uint32_t width, + uint32_t height) { #if defined(WEBRTC_DLOPEN_PIPEWIRE) StubPathMap paths; @@ -463,6 +468,12 @@ bool SharedScreenCastStreamPrivate::StartScreenCastStream( pw_client_version_ >= kDmaBufModifierMinVersion; const bool has_required_pw_server_version = pw_server_version_ >= kDmaBufModifierMinVersion; + struct spa_rectangle resolution; + bool set_resolution = false; + if (width && height) { + resolution = SPA_RECTANGLE(width, height); + set_resolution = true; + } for (uint32_t format : {SPA_VIDEO_FORMAT_BGRA, SPA_VIDEO_FORMAT_RGBA, SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx}) { // Modifiers can be used with PipeWire >= 0.3.33 @@ -471,12 +482,12 @@ bool SharedScreenCastStreamPrivate::StartScreenCastStream( if (!modifiers_.empty()) { params.push_back(BuildFormat(&builder, format, modifiers_, - /*resolution=*/nullptr)); + set_resolution ? &resolution : nullptr)); } } params.push_back(BuildFormat(&builder, format, /*modifiers=*/{}, - /*resolution=*/nullptr)); + set_resolution ? &resolution : nullptr)); } if (pw_stream_connect(pw_stream_, PW_DIRECTION_INPUT, pw_stream_node_id_, @@ -734,8 +745,10 @@ bool SharedScreenCastStream::StartScreenCastStream(uint32_t stream_node_id) { } bool SharedScreenCastStream::StartScreenCastStream(uint32_t stream_node_id, - int fd) { - return private_->StartScreenCastStream(stream_node_id, fd); + int fd, + uint32_t width, + uint32_t height) { + return private_->StartScreenCastStream(stream_node_id, fd, width, height); } void SharedScreenCastStream::StopScreenCastStream() { diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream.h b/modules/desktop_capture/linux/wayland/shared_screencast_stream.h index 1e9fbe5f70..e8b79cb4ec 100644 --- a/modules/desktop_capture/linux/wayland/shared_screencast_stream.h +++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream.h @@ -30,7 +30,10 @@ class RTC_EXPORT SharedScreenCastStream static rtc::scoped_refptr CreateDefault(); bool StartScreenCastStream(uint32_t stream_node_id); - bool StartScreenCastStream(uint32_t stream_node_id, int fd); + bool StartScreenCastStream(uint32_t stream_node_id, + int fd, + uint32_t width = 0, + uint32_t height = 0); void StopScreenCastStream(); // Below functions return the most recent information we get from a