Upstream commit: https://webrtc.googlesource.com/src/+/7319cb19a40a685b97252e2525439f0841020b6e Return const references from member getters Return const references from member getters across network, crypto, video frame metadata, and experiment settings to avoid redundant string and vector copies. Bug: webrtc:374845009 Change-Id: I10db3e8c67fe12b302fd1bc405bab3981c654ddd Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/495800 Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Commit-Queue: Fredrik Solenberg <solenberg@webrtc.org> Cr-Commit-Position: refs/heads/main@{#48347}
193 lines
7.0 KiB
Diff
193 lines
7.0 KiB
Diff
From: Jan Grulich <jgrulich@redhat.com>
|
|
Date: Thu, 5 Sep 2024 16:04:00 +0000
|
|
Subject: Bug 1830275 - Add missing support for device change notifications
|
|
r=pehrsons,webrtc-reviewers
|
|
|
|
Registers each DeviceInfoPipeWire in PipeWireSession we use and calls
|
|
DeviceChange() for each once there is a new camera added or removed to
|
|
invoke OnDeviceChange() for every registered VideoInputFeedback.
|
|
|
|
Differential Revision: https://phabricator.services.mozilla.com/D219218
|
|
Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/60eb5ef11c8df7eb6e0d616cb76885d9109f114d
|
|
---
|
|
.../linux/device_info_pipewire.cc | 10 +++-
|
|
.../video_capture/linux/pipewire_session.cc | 49 ++++++++++++++++++-
|
|
.../video_capture/linux/pipewire_session.h | 26 +++++++++-
|
|
3 files changed, 81 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/modules/video_capture/linux/device_info_pipewire.cc b/modules/video_capture/linux/device_info_pipewire.cc
|
|
index 009e1408b9..a737f9bdb3 100644
|
|
--- a/modules/video_capture/linux/device_info_pipewire.cc
|
|
+++ b/modules/video_capture/linux/device_info_pipewire.cc
|
|
@@ -23,13 +23,19 @@
|
|
namespace webrtc {
|
|
namespace videocapturemodule {
|
|
DeviceInfoPipeWire::DeviceInfoPipeWire(VideoCaptureOptions* options)
|
|
- : DeviceInfoImpl(), pipewire_session_(options->pipewire_session()) {}
|
|
+ : DeviceInfoImpl(), pipewire_session_(options->pipewire_session()) {
|
|
+ const bool ret = pipewire_session_->RegisterDeviceInfo(this);
|
|
+ RTC_CHECK(ret);
|
|
+}
|
|
|
|
int32_t DeviceInfoPipeWire::Init() {
|
|
return 0;
|
|
}
|
|
|
|
-DeviceInfoPipeWire::~DeviceInfoPipeWire() = default;
|
|
+DeviceInfoPipeWire::~DeviceInfoPipeWire() {
|
|
+ const bool ret = pipewire_session_->DeRegisterDeviceInfo(this);
|
|
+ RTC_CHECK(ret);
|
|
+}
|
|
|
|
uint32_t DeviceInfoPipeWire::NumberOfDevices() {
|
|
RTC_CHECK(pipewire_session_);
|
|
diff --git a/modules/video_capture/linux/pipewire_session.cc b/modules/video_capture/linux/pipewire_session.cc
|
|
index e17bab807c..cd56026c7b 100644
|
|
--- a/modules/video_capture/linux/pipewire_session.cc
|
|
+++ b/modules/video_capture/linux/pipewire_session.cc
|
|
@@ -36,6 +36,7 @@
|
|
#include "modules/portal/pipewire_utils.h"
|
|
#include "modules/portal/portal_request_response.h"
|
|
#include "modules/video_capture/linux/camera_portal.h"
|
|
+#include "modules/video_capture/linux/device_info_pipewire.h"
|
|
#include "modules/video_capture/video_capture_defines.h"
|
|
#include "modules/video_capture/video_capture_options.h"
|
|
#include "rtc_base/logging.h"
|
|
@@ -343,6 +344,30 @@ void PipeWireSession::InitPipeWire(int fd) {
|
|
Finish(VideoCaptureOptions::Status::ERROR);
|
|
}
|
|
|
|
+bool PipeWireSession::RegisterDeviceInfo(DeviceInfoPipeWire* device_info) {
|
|
+ RTC_CHECK(device_info);
|
|
+ MutexLock lock(&device_info_lock_);
|
|
+ auto it = std::find(device_info_list_.begin(), device_info_list_.end(),
|
|
+ device_info);
|
|
+ if (it == device_info_list_.end()) {
|
|
+ device_info_list_.push_back(device_info);
|
|
+ return true;
|
|
+ }
|
|
+ return false;
|
|
+}
|
|
+
|
|
+bool PipeWireSession::DeRegisterDeviceInfo(DeviceInfoPipeWire* device_info) {
|
|
+ RTC_CHECK(device_info);
|
|
+ MutexLock lock(&device_info_lock_);
|
|
+ auto it = std::find(device_info_list_.begin(), device_info_list_.end(),
|
|
+ device_info);
|
|
+ if (it != device_info_list_.end()) {
|
|
+ device_info_list_.erase(it);
|
|
+ return true;
|
|
+ }
|
|
+ return false;
|
|
+}
|
|
+
|
|
RTC_NO_SANITIZE("cfi-icall")
|
|
bool PipeWireSession::StartPipeWire(int fd) {
|
|
pw_initializer_ = std::make_unique<PipeWireInitializer>();
|
|
@@ -415,6 +440,21 @@ void PipeWireSession::PipeWireSync() {
|
|
sync_seq_ = pw_core_sync(pw_core_, PW_ID_CORE, sync_seq_);
|
|
}
|
|
|
|
+void PipeWireSession::NotifyDeviceChange() {
|
|
+ RTC_LOG(LS_INFO) << "Notify about device list changes";
|
|
+ MutexLock lock(&device_info_lock_);
|
|
+
|
|
+ // It makes sense to notify about device changes only once we are
|
|
+ // properly initialized.
|
|
+ if (status_ != VideoCaptureOptions::Status::SUCCESS) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ for (auto* deviceInfo : device_info_list_) {
|
|
+ deviceInfo->DeviceChange();
|
|
+ }
|
|
+}
|
|
+
|
|
// static
|
|
void PipeWireSession::OnCoreError(void* data,
|
|
uint32_t id,
|
|
@@ -472,6 +512,8 @@ void PipeWireSession::OnRegistryGlobal(void* data,
|
|
|
|
that->nodes_.push_back(PipeWireNode::Create(that, id, props));
|
|
that->PipeWireSync();
|
|
+
|
|
+ that->NotifyDeviceChange();
|
|
}
|
|
|
|
// static
|
|
@@ -481,10 +523,15 @@ void PipeWireSession::OnRegistryGlobalRemove(void* data, uint32_t id) {
|
|
std::erase_if(that->nodes_, [id](const PipeWireNode::PipeWireNodePtr& node) {
|
|
return node->id() == id;
|
|
});
|
|
+
|
|
+ that->NotifyDeviceChange();
|
|
}
|
|
|
|
void PipeWireSession::Finish(VideoCaptureOptions::Status status) {
|
|
- status_ = status;
|
|
+ {
|
|
+ MutexLock lock(&device_info_lock_);
|
|
+ status_ = status;
|
|
+ }
|
|
|
|
webrtc::MutexLock lock(&callback_lock_);
|
|
|
|
diff --git a/modules/video_capture/linux/pipewire_session.h b/modules/video_capture/linux/pipewire_session.h
|
|
index 934933402f..4dc99a14fc 100644
|
|
--- a/modules/video_capture/linux/pipewire_session.h
|
|
+++ b/modules/video_capture/linux/pipewire_session.h
|
|
@@ -34,6 +34,7 @@
|
|
namespace webrtc {
|
|
namespace videocapturemodule {
|
|
|
|
+class DeviceInfoPipeWire;
|
|
class PipeWireSession;
|
|
class VideoCaptureModulePipeWire;
|
|
|
|
@@ -107,6 +108,21 @@ class PipeWireSession : public webrtc::RefCountedNonVirtual<PipeWireSession> {
|
|
|
|
void Init(VideoCaptureOptions::Callback* callback,
|
|
int fd = kInvalidPipeWireFd);
|
|
+
|
|
+ // [De]Register DeviceInfo for device change updates
|
|
+ // These methods will add or remove references to DeviceInfo
|
|
+ // objects that we want to notify about device changes.
|
|
+ // NOTE: We do not take ownership of these objects and
|
|
+ // they should never be released by us. All the instances
|
|
+ // of DeviceInfoPipeWire must outlive their registration.
|
|
+
|
|
+ // Returns true when DeviceInfo was successfuly registered
|
|
+ // or false otherwise, when it was already registered before.
|
|
+ bool RegisterDeviceInfo(DeviceInfoPipeWire* device_info);
|
|
+ // Returns true when DeviceInfo was successfuly unregistered
|
|
+ // or false otherwise, when it was not previously registered.
|
|
+ bool DeRegisterDeviceInfo(DeviceInfoPipeWire* device_info);
|
|
+
|
|
const std::deque<PipeWireNode::PipeWireNodePtr>& nodes() const {
|
|
return nodes_;
|
|
}
|
|
@@ -121,6 +137,8 @@ class PipeWireSession : public webrtc::RefCountedNonVirtual<PipeWireSession> {
|
|
void StopPipeWire();
|
|
void PipeWireSync();
|
|
|
|
+ void NotifyDeviceChange();
|
|
+
|
|
static void OnCoreError(void* data,
|
|
uint32_t id,
|
|
int seq,
|
|
@@ -143,7 +161,13 @@ class PipeWireSession : public webrtc::RefCountedNonVirtual<PipeWireSession> {
|
|
VideoCaptureOptions::Callback* callback_ RTC_GUARDED_BY(&callback_lock_) =
|
|
nullptr;
|
|
|
|
- VideoCaptureOptions::Status status_;
|
|
+ webrtc::Mutex device_info_lock_;
|
|
+ std::vector<DeviceInfoPipeWire*> device_info_list_
|
|
+ RTC_GUARDED_BY(device_info_lock_);
|
|
+ // Guard with device_info_lock, because currently it's the only place where
|
|
+ // we use this status information.
|
|
+ VideoCaptureOptions::Status status_
|
|
+ RTC_GUARDED_BY(device_info_lock_);
|
|
|
|
std::unique_ptr<PipeWireInitializer> pw_initializer_;
|
|
struct pw_thread_loop* pw_main_loop_ = nullptr;
|