Video capture PipeWire: always capture latest processed buffer
Both CaptureFrame() and ProcessBuffer() hold a lock over the frame queue and it happens that one waits for the other, causing unnecessary delays since we already work with a queue having two frames, but this way we don't really need a queue. Instead, keep reference to the last processed buffer, which we will always use in CaptureFrame() and update it every time at the end of ProcessBuffer(). This avoid unnecessary waiting for the lock over the queue to be released. Bug: chromium:333945842 Change-Id: I4afeb1daacd342e92578a50ac6e1c89a691bb8f8 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/350042 Commit-Queue: Jan Grulich <grulja@gmail.com> Reviewed-by: Alexander Cooper <alcooper@chromium.org> Reviewed-by: Mark Foltz <mfoltz@chromium.org> Cr-Commit-Position: refs/heads/main@{#42394}
This commit is contained in:
parent
ac4e0b6f46
commit
848980198e
@ -83,6 +83,9 @@ class SharedScreenCastStreamPrivate {
|
||||
webrtc::Mutex queue_lock_;
|
||||
ScreenCaptureFrameQueue<SharedDesktopFrame> queue_
|
||||
RTC_GUARDED_BY(&queue_lock_);
|
||||
webrtc::Mutex latest_frame_lock_;
|
||||
SharedDesktopFrame* latest_available_frame_
|
||||
RTC_GUARDED_BY(&latest_frame_lock_) = nullptr;
|
||||
std::unique_ptr<MouseCursor> mouse_cursor_;
|
||||
DesktopVector mouse_cursor_position_ = DesktopVector(-1, -1);
|
||||
|
||||
@ -603,13 +606,13 @@ void SharedScreenCastStreamPrivate::StopAndCleanupStream() {
|
||||
|
||||
std::unique_ptr<SharedDesktopFrame>
|
||||
SharedScreenCastStreamPrivate::CaptureFrame() {
|
||||
webrtc::MutexLock lock(&queue_lock_);
|
||||
webrtc::MutexLock latest_frame_lock(&latest_frame_lock_);
|
||||
|
||||
if (!pw_stream_ || !queue_.current_frame()) {
|
||||
if (!pw_stream_ || !latest_available_frame_) {
|
||||
return std::unique_ptr<SharedDesktopFrame>{};
|
||||
}
|
||||
|
||||
std::unique_ptr<SharedDesktopFrame> frame = queue_.current_frame()->Share();
|
||||
std::unique_ptr<SharedDesktopFrame> frame = latest_available_frame_->Share();
|
||||
if (use_damage_region_) {
|
||||
frame->mutable_updated_region()->Swap(&damage_region_);
|
||||
damage_region_.Clear();
|
||||
@ -842,6 +845,8 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
|
||||
if (observer_) {
|
||||
observer_->OnFailedToProcessBuffer();
|
||||
}
|
||||
webrtc::MutexLock latest_frame_lock(&latest_frame_lock_);
|
||||
latest_available_frame_ = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -860,9 +865,16 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
|
||||
observer_->OnDesktopFrameChanged();
|
||||
}
|
||||
|
||||
// We have to hold the lock over the latest_frame here already, since
|
||||
// we are going to update damage region, which corresponds to the latest
|
||||
// frame and is accessed in CaptureFrame()
|
||||
webrtc::MutexLock latest_frame_lock(&latest_frame_lock_);
|
||||
|
||||
UpdateFrameUpdatedRegions(spa_buffer, *queue_.current_frame());
|
||||
queue_.current_frame()->set_may_contain_cursor(is_cursor_embedded_);
|
||||
|
||||
latest_available_frame_ = queue_.current_frame();
|
||||
|
||||
if (callback_) {
|
||||
std::unique_ptr<SharedDesktopFrame> frame = queue_.current_frame()->Share();
|
||||
frame->set_capturer_id(DesktopCapturerId::kWaylandCapturerLinux);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user