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)
|
||||
static bool IsRunningUnderWayland();
|
||||
|
||||
virtual void UpdateResolution(uint32_t width, uint32_t height){};
|
||||
#endif // defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11)
|
||||
|
||||
#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) {
|
||||
RTC_DCHECK(!callback_);
|
||||
RTC_DCHECK(callback);
|
||||
|
@ -45,6 +45,7 @@ class BaseCapturerPipeWire : public DesktopCapturer,
|
||||
uint32_t stream_node_id,
|
||||
int fd) override;
|
||||
void OnScreenCastSessionClosed() override;
|
||||
void UpdateResolution(uint32_t width, uint32_t height) override;
|
||||
|
||||
xdg_portal::SessionDetails GetSessionDetails();
|
||||
|
||||
|
@ -89,6 +89,7 @@ class SharedScreenCastStreamPrivate {
|
||||
int fd,
|
||||
uint32_t width = 0,
|
||||
uint32_t height = 0);
|
||||
void UpdateScreenCastStreamResolution(uint32_t width, uint32_t height);
|
||||
void StopScreenCastStream();
|
||||
std::unique_ptr<DesktopFrame> CaptureFrame();
|
||||
std::unique_ptr<MouseCursor> CaptureCursor();
|
||||
@ -130,6 +131,13 @@ class SharedScreenCastStreamPrivate {
|
||||
// Version of the library used to run our code
|
||||
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
|
||||
pw_core_events pw_core_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)};
|
||||
|
||||
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,
|
||||
SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx}) {
|
||||
if (!that->modifiers_.empty()) {
|
||||
params.push_back(BuildFormat(&builder, format, that->modifiers_,
|
||||
/*resolution=*/nullptr));
|
||||
params.push_back(BuildFormat(
|
||||
&builder, format, that->modifiers_,
|
||||
that->pending_resolution_change_ ? &resolution : nullptr));
|
||||
}
|
||||
params.push_back(BuildFormat(&builder, format, /*modifiers=*/{},
|
||||
/*resolution=*/nullptr));
|
||||
params.push_back(BuildFormat(
|
||||
&builder, format, /*modifiers=*/{},
|
||||
that->pending_resolution_change_ ? &resolution : nullptr));
|
||||
}
|
||||
|
||||
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,
|
||||
uint32_t width,
|
||||
uint32_t height) {
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
#if defined(WEBRTC_DLOPEN_PIPEWIRE)
|
||||
StubPathMap paths;
|
||||
|
||||
@ -502,6 +518,35 @@ bool SharedScreenCastStreamPrivate::StartScreenCastStream(
|
||||
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() {
|
||||
if (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);
|
||||
}
|
||||
|
||||
void SharedScreenCastStream::UpdateScreenCastStreamResolution(uint32_t width,
|
||||
uint32_t height) {
|
||||
private_->UpdateScreenCastStreamResolution(width, height);
|
||||
}
|
||||
|
||||
void SharedScreenCastStream::StopScreenCastStream() {
|
||||
private_->StopScreenCastStream();
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ class RTC_EXPORT SharedScreenCastStream
|
||||
int fd,
|
||||
uint32_t width = 0,
|
||||
uint32_t height = 0);
|
||||
void UpdateScreenCastStreamResolution(uint32_t width, uint32_t height);
|
||||
void StopScreenCastStream();
|
||||
|
||||
// Below functions return the most recent information we get from a
|
||||
|
Reference in New Issue
Block a user