Wayland screencast: use damage regions metadata from PW buffers
We already communicated SPA_META_VideoDamage before, but we never used these metadata. This change checks whether SPA_META_VideoDamage metadata are available and construct a damage rect combined from all sent damage regions. Bug: webrtc:13429 Change-Id: I326109b4bacf51855904e53345c671640d670323 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/278820 Reviewed-by: Alexander Cooper <alcooper@chromium.org> Commit-Queue: Jan Grulich <grulja@gmail.com> Cr-Commit-Position: refs/heads/main@{#38449}
This commit is contained in:
committed by
WebRTC LUCI CQ
parent
640e92684a
commit
f5db32f02a
@ -194,6 +194,13 @@ class RTC_EXPORT DesktopCaptureOptions {
|
||||
|
||||
void set_height(uint32_t height) { height_ = height; }
|
||||
uint32_t get_height() const { return height_; }
|
||||
|
||||
void set_pipewire_use_damage_region(bool use_damage_regions) {
|
||||
pipewire_use_damage_region_ = use_damage_regions;
|
||||
}
|
||||
bool pipewire_use_damage_region() const {
|
||||
return pipewire_use_damage_region_;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
@ -232,6 +239,7 @@ class RTC_EXPORT DesktopCaptureOptions {
|
||||
bool detect_updated_region_ = false;
|
||||
#if defined(WEBRTC_USE_PIPEWIRE)
|
||||
bool allow_pipewire_ = false;
|
||||
bool pipewire_use_damage_region_ = true;
|
||||
uint32_t width_ = 0;
|
||||
uint32_t height_ = 0;
|
||||
#endif
|
||||
|
||||
@ -42,6 +42,8 @@ BaseCapturerPipeWire::BaseCapturerPipeWire(
|
||||
is_screencast_portal_(false),
|
||||
portal_(std::move(portal)) {
|
||||
source_id_ = RestoreTokenManager::GetInstance().GetUnusedId();
|
||||
options_.screencast_stream()->SetUseDamageRegion(
|
||||
options_.pipewire_use_damage_region());
|
||||
}
|
||||
|
||||
BaseCapturerPipeWire::~BaseCapturerPipeWire() {
|
||||
|
||||
@ -36,6 +36,7 @@ using modules_desktop_capture_linux_wayland::StubPathMap;
|
||||
namespace webrtc {
|
||||
|
||||
const int kBytesPerPixel = 4;
|
||||
const int kVideoDamageRegionCount = 16;
|
||||
|
||||
#if defined(WEBRTC_DLOPEN_PIPEWIRE)
|
||||
const char kPipeWireLib[] = "libpipewire-0.3.so.0";
|
||||
@ -88,6 +89,9 @@ class SharedScreenCastStreamPrivate {
|
||||
uint32_t width = 0,
|
||||
uint32_t height = 0);
|
||||
void UpdateScreenCastStreamResolution(uint32_t width, uint32_t height);
|
||||
void SetUseDamageRegion(bool use_damage_region) {
|
||||
use_damage_region_ = use_damage_region;
|
||||
}
|
||||
void SetObserver(SharedScreenCastStream::Observer* observer) {
|
||||
observer_ = observer;
|
||||
}
|
||||
@ -101,6 +105,11 @@ class SharedScreenCastStreamPrivate {
|
||||
void StopAndCleanupStream();
|
||||
|
||||
SharedScreenCastStream::Observer* observer_ = nullptr;
|
||||
|
||||
// Track damage region updates that were reported since the last time
|
||||
// frame was captured
|
||||
DesktopRegion damage_region_;
|
||||
|
||||
uint32_t pw_stream_node_id_ = 0;
|
||||
|
||||
DesktopSize stream_size_ = {};
|
||||
@ -142,6 +151,8 @@ class SharedScreenCastStreamPrivate {
|
||||
// Resolution changes are processed during buffer processing.
|
||||
bool pending_resolution_change_ RTC_GUARDED_BY(&resolution_lock_) = false;
|
||||
|
||||
bool use_damage_region_ = true;
|
||||
|
||||
// event handlers
|
||||
pw_core_events pw_core_events_ = {};
|
||||
pw_stream_events pw_stream_events_ = {};
|
||||
@ -294,9 +305,10 @@ void SharedScreenCastStreamPrivate::OnStreamParamChanged(
|
||||
params.push_back(reinterpret_cast<spa_pod*>(spa_pod_builder_add_object(
|
||||
&builder, SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, SPA_PARAM_META_type,
|
||||
SPA_POD_Id(SPA_META_VideoDamage), SPA_PARAM_META_size,
|
||||
SPA_POD_CHOICE_RANGE_Int(sizeof(struct spa_meta_region) * 16,
|
||||
sizeof(struct spa_meta_region) * 1,
|
||||
sizeof(struct spa_meta_region) * 16))));
|
||||
SPA_POD_CHOICE_RANGE_Int(
|
||||
sizeof(struct spa_meta_region) * kVideoDamageRegionCount,
|
||||
sizeof(struct spa_meta_region) * 1,
|
||||
sizeof(struct spa_meta_region) * kVideoDamageRegionCount))));
|
||||
|
||||
pw_stream_update_params(that->pw_stream_, params.data(), params.size());
|
||||
}
|
||||
@ -585,7 +597,13 @@ SharedScreenCastStreamPrivate::CaptureFrame() {
|
||||
return std::unique_ptr<SharedDesktopFrame>{};
|
||||
}
|
||||
|
||||
return queue_.current_frame()->Share();
|
||||
std::unique_ptr<SharedDesktopFrame> frame = queue_.current_frame()->Share();
|
||||
if (use_damage_region_) {
|
||||
frame->mutable_updated_region()->Swap(&damage_region_);
|
||||
damage_region_.Clear();
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
std::unique_ptr<MouseCursor> SharedScreenCastStreamPrivate::CaptureCursor() {
|
||||
@ -844,13 +862,38 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
queue_.current_frame()->mutable_updated_region()->SetRect(
|
||||
DesktopRect::MakeSize(queue_.current_frame()->size()));
|
||||
|
||||
// For testing purpose
|
||||
if (observer_) {
|
||||
observer_->OnDesktopFrameChanged();
|
||||
}
|
||||
|
||||
if (use_damage_region_) {
|
||||
const struct spa_meta* video_damage = static_cast<struct spa_meta*>(
|
||||
spa_buffer_find_meta(spa_buffer, SPA_META_VideoDamage));
|
||||
if (video_damage) {
|
||||
spa_meta_region* meta_region;
|
||||
|
||||
queue_.current_frame()->mutable_updated_region()->Clear();
|
||||
|
||||
spa_meta_for_each(meta_region, video_damage) {
|
||||
// Skip empty regions
|
||||
if (meta_region->region.size.width == 0 ||
|
||||
meta_region->region.size.height == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
damage_region_.AddRect(DesktopRect::MakeXYWH(
|
||||
meta_region->region.position.x, meta_region->region.position.y,
|
||||
meta_region->region.size.width, meta_region->region.size.height));
|
||||
}
|
||||
} else {
|
||||
damage_region_.SetRect(
|
||||
DesktopRect::MakeSize(queue_.current_frame()->size()));
|
||||
}
|
||||
} else {
|
||||
queue_.current_frame()->mutable_updated_region()->SetRect(
|
||||
DesktopRect::MakeSize(queue_.current_frame()->size()));
|
||||
}
|
||||
}
|
||||
|
||||
void SharedScreenCastStreamPrivate::ConvertRGBxToBGRx(uint8_t* frame,
|
||||
@ -891,6 +934,10 @@ void SharedScreenCastStream::UpdateScreenCastStreamResolution(uint32_t width,
|
||||
private_->UpdateScreenCastStreamResolution(width, height);
|
||||
}
|
||||
|
||||
void SharedScreenCastStream::SetUseDamageRegion(bool use_damage_region) {
|
||||
private_->SetUseDamageRegion(use_damage_region);
|
||||
}
|
||||
|
||||
void SharedScreenCastStream::SetObserver(
|
||||
SharedScreenCastStream::Observer* observer) {
|
||||
private_->SetObserver(observer);
|
||||
|
||||
@ -48,6 +48,7 @@ class RTC_EXPORT SharedScreenCastStream
|
||||
uint32_t width = 0,
|
||||
uint32_t height = 0);
|
||||
void UpdateScreenCastStreamResolution(uint32_t width, uint32_t height);
|
||||
void SetUseDamageRegion(bool use_damage_region);
|
||||
void SetObserver(SharedScreenCastStream::Observer* observer);
|
||||
void StopScreenCastStream();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user