wayland: Support dynamic resolution changes of pw stream
This change adds support for dynamic resolution adjustment of pipewire stream. Bug: chromium:1291247 Change-Id: I87e02484920f795a053a814eb872834ab22c1bd3 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/263680 Commit-Queue: Salman Malik <salmanmalik@google.com> Reviewed-by: Alexander Cooper <alcooper@chromium.org> Cr-Commit-Position: refs/heads/main@{#37010}
This commit is contained in:

committed by
WebRTC LUCI CQ

parent
2d4207e85a
commit
45a22ffbb7
@ -144,6 +144,8 @@ class RTC_EXPORT DesktopCapturer {
|
|||||||
|
|
||||||
#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11)
|
#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11)
|
||||||
static bool IsRunningUnderWayland();
|
static bool IsRunningUnderWayland();
|
||||||
|
|
||||||
|
virtual void UpdateResolution(uint32_t width, uint32_t height){};
|
||||||
#endif // defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11)
|
#endif // defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11)
|
||||||
|
|
||||||
#if defined(WEBRTC_USE_GIO)
|
#if defined(WEBRTC_USE_GIO)
|
||||||
|
@ -58,6 +58,13 @@ void BaseCapturerPipeWire::OnScreenCastSessionClosed() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseCapturerPipeWire::UpdateResolution(uint32_t width, uint32_t height) {
|
||||||
|
if (!capturer_failed_) {
|
||||||
|
options_.screencast_stream()->UpdateScreenCastStreamResolution(width,
|
||||||
|
height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BaseCapturerPipeWire::Start(Callback* callback) {
|
void BaseCapturerPipeWire::Start(Callback* callback) {
|
||||||
RTC_DCHECK(!callback_);
|
RTC_DCHECK(!callback_);
|
||||||
RTC_DCHECK(callback);
|
RTC_DCHECK(callback);
|
||||||
|
@ -45,6 +45,7 @@ class BaseCapturerPipeWire : public DesktopCapturer,
|
|||||||
uint32_t stream_node_id,
|
uint32_t stream_node_id,
|
||||||
int fd) override;
|
int fd) override;
|
||||||
void OnScreenCastSessionClosed() override;
|
void OnScreenCastSessionClosed() override;
|
||||||
|
void UpdateResolution(uint32_t width, uint32_t height) override;
|
||||||
|
|
||||||
xdg_portal::SessionDetails GetSessionDetails();
|
xdg_portal::SessionDetails GetSessionDetails();
|
||||||
|
|
||||||
|
@ -89,6 +89,7 @@ class SharedScreenCastStreamPrivate {
|
|||||||
int fd,
|
int fd,
|
||||||
uint32_t width = 0,
|
uint32_t width = 0,
|
||||||
uint32_t height = 0);
|
uint32_t height = 0);
|
||||||
|
void UpdateScreenCastStreamResolution(uint32_t width, uint32_t height);
|
||||||
void StopScreenCastStream();
|
void StopScreenCastStream();
|
||||||
std::unique_ptr<DesktopFrame> CaptureFrame();
|
std::unique_ptr<DesktopFrame> CaptureFrame();
|
||||||
std::unique_ptr<MouseCursor> CaptureCursor();
|
std::unique_ptr<MouseCursor> CaptureCursor();
|
||||||
@ -130,6 +131,13 @@ class SharedScreenCastStreamPrivate {
|
|||||||
// Version of the library used to run our code
|
// Version of the library used to run our code
|
||||||
PipeWireVersion pw_client_version_;
|
PipeWireVersion pw_client_version_;
|
||||||
|
|
||||||
|
// Resolution parameters.
|
||||||
|
uint32_t width_ = 0;
|
||||||
|
uint32_t height_ = 0;
|
||||||
|
webrtc::Mutex resolution_lock_;
|
||||||
|
// Resolution changes are processed during buffer processing.
|
||||||
|
bool pending_resolution_change_ RTC_GUARDED_BY(&resolution_lock_) = false;
|
||||||
|
|
||||||
// event handlers
|
// event handlers
|
||||||
pw_core_events pw_core_events_ = {};
|
pw_core_events pw_core_events_ = {};
|
||||||
pw_stream_events pw_stream_events_ = {};
|
pw_stream_events pw_stream_events_ = {};
|
||||||
@ -329,18 +337,24 @@ void SharedScreenCastStreamPrivate::OnRenegotiateFormat(void* data, uint64_t) {
|
|||||||
spa_pod_builder builder = spa_pod_builder{buffer, sizeof(buffer)};
|
spa_pod_builder builder = spa_pod_builder{buffer, sizeof(buffer)};
|
||||||
|
|
||||||
std::vector<const spa_pod*> params;
|
std::vector<const spa_pod*> params;
|
||||||
|
struct spa_rectangle resolution =
|
||||||
|
SPA_RECTANGLE(that->width_, that->height_);
|
||||||
|
|
||||||
|
webrtc::MutexLock lock(&that->resolution_lock_);
|
||||||
for (uint32_t format : {SPA_VIDEO_FORMAT_BGRA, SPA_VIDEO_FORMAT_RGBA,
|
for (uint32_t format : {SPA_VIDEO_FORMAT_BGRA, SPA_VIDEO_FORMAT_RGBA,
|
||||||
SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx}) {
|
SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx}) {
|
||||||
if (!that->modifiers_.empty()) {
|
if (!that->modifiers_.empty()) {
|
||||||
params.push_back(BuildFormat(&builder, format, that->modifiers_,
|
params.push_back(BuildFormat(
|
||||||
/*resolution=*/nullptr));
|
&builder, format, that->modifiers_,
|
||||||
|
that->pending_resolution_change_ ? &resolution : nullptr));
|
||||||
}
|
}
|
||||||
params.push_back(BuildFormat(&builder, format, /*modifiers=*/{},
|
params.push_back(BuildFormat(
|
||||||
/*resolution=*/nullptr));
|
&builder, format, /*modifiers=*/{},
|
||||||
|
that->pending_resolution_change_ ? &resolution : nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
pw_stream_update_params(that->pw_stream_, params.data(), params.size());
|
pw_stream_update_params(that->pw_stream_, params.data(), params.size());
|
||||||
|
that->pending_resolution_change_ = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,6 +388,8 @@ bool SharedScreenCastStreamPrivate::StartScreenCastStream(
|
|||||||
int fd,
|
int fd,
|
||||||
uint32_t width,
|
uint32_t width,
|
||||||
uint32_t height) {
|
uint32_t height) {
|
||||||
|
width_ = width;
|
||||||
|
height_ = height;
|
||||||
#if defined(WEBRTC_DLOPEN_PIPEWIRE)
|
#if defined(WEBRTC_DLOPEN_PIPEWIRE)
|
||||||
StubPathMap paths;
|
StubPathMap paths;
|
||||||
|
|
||||||
@ -502,6 +518,35 @@ bool SharedScreenCastStreamPrivate::StartScreenCastStream(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RTC_NO_SANITIZE("cfi-icall")
|
||||||
|
void SharedScreenCastStreamPrivate::UpdateScreenCastStreamResolution(
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height) {
|
||||||
|
if (!width || !height) {
|
||||||
|
RTC_LOG(LS_WARNING) << "Bad resolution specified: " << width << "x"
|
||||||
|
<< height;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!pw_main_loop_) {
|
||||||
|
RTC_LOG(LS_WARNING) << "No main pipewire loop, ignoring resolution change";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!renegotiate_) {
|
||||||
|
RTC_LOG(LS_WARNING) << "Can not renegotiate stream params, ignoring "
|
||||||
|
<< "resolution change";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (width_ != width || height_ != height) {
|
||||||
|
width_ = width;
|
||||||
|
height_ = height;
|
||||||
|
{
|
||||||
|
webrtc::MutexLock lock(&resolution_lock_);
|
||||||
|
pending_resolution_change_ = true;
|
||||||
|
}
|
||||||
|
pw_loop_signal_event(pw_thread_loop_get_loop(pw_main_loop_), renegotiate_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SharedScreenCastStreamPrivate::StopScreenCastStream() {
|
void SharedScreenCastStreamPrivate::StopScreenCastStream() {
|
||||||
if (pw_stream_) {
|
if (pw_stream_) {
|
||||||
pw_stream_disconnect(pw_stream_);
|
pw_stream_disconnect(pw_stream_);
|
||||||
@ -751,6 +796,11 @@ bool SharedScreenCastStream::StartScreenCastStream(uint32_t stream_node_id,
|
|||||||
return private_->StartScreenCastStream(stream_node_id, fd, width, height);
|
return private_->StartScreenCastStream(stream_node_id, fd, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SharedScreenCastStream::UpdateScreenCastStreamResolution(uint32_t width,
|
||||||
|
uint32_t height) {
|
||||||
|
private_->UpdateScreenCastStreamResolution(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
void SharedScreenCastStream::StopScreenCastStream() {
|
void SharedScreenCastStream::StopScreenCastStream() {
|
||||||
private_->StopScreenCastStream();
|
private_->StopScreenCastStream();
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ class RTC_EXPORT SharedScreenCastStream
|
|||||||
int fd,
|
int fd,
|
||||||
uint32_t width = 0,
|
uint32_t width = 0,
|
||||||
uint32_t height = 0);
|
uint32_t height = 0);
|
||||||
|
void UpdateScreenCastStreamResolution(uint32_t width, uint32_t height);
|
||||||
void StopScreenCastStream();
|
void StopScreenCastStream();
|
||||||
|
|
||||||
// Below functions return the most recent information we get from a
|
// Below functions return the most recent information we get from a
|
||||||
|
Reference in New Issue
Block a user