File: 0112.patch

package info (click to toggle)
thunderbird 1%3A143.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 4,703,968 kB
  • sloc: cpp: 7,770,492; javascript: 5,943,842; ansic: 3,918,754; python: 1,418,263; xml: 653,354; asm: 474,045; java: 183,079; sh: 111,238; makefile: 20,410; perl: 14,359; objc: 13,059; yacc: 4,583; pascal: 3,405; lex: 1,720; ruby: 999; exp: 762; sql: 715; awk: 580; php: 436; lisp: 430; sed: 69; csh: 10
file content (190 lines) | stat: -rw-r--r-- 6,968 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
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   | 47 ++++++++++++++++++-
 .../video_capture/linux/pipewire_session.h    | 26 +++++++++-
 3 files changed, 79 insertions(+), 4 deletions(-)

diff --git a/modules/video_capture/linux/device_info_pipewire.cc b/modules/video_capture/linux/device_info_pipewire.cc
index db2a3c7099..a0607b4aba 100644
--- a/modules/video_capture/linux/device_info_pipewire.cc
+++ b/modules/video_capture/linux/device_info_pipewire.cc
@@ -29,13 +29,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 990bfde912..25c4dfae4e 100644
--- a/modules/video_capture/linux/pipewire_session.cc
+++ b/modules/video_capture/linux/pipewire_session.cc
@@ -9,6 +9,7 @@
  */
 
 #include "modules/video_capture/linux/pipewire_session.h"
+#include "modules/video_capture/linux/device_info_pipewire.h"
 
 #include <spa/monitor/device.h>
 #include <spa/param/format-utils.h>
@@ -286,6 +287,28 @@ 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_init(/*argc=*/nullptr, /*argv=*/nullptr);
@@ -358,6 +381,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,
@@ -416,6 +454,8 @@ void PipeWireSession::OnRegistryGlobal(void* data,
 
   that->nodes_.push_back(PipeWireNode::Create(that, id, props));
   that->PipeWireSync();
+
+  that->NotifyDeviceChange();
 }
 
 // static
@@ -427,10 +467,15 @@ void PipeWireSession::OnRegistryGlobalRemove(void* data, uint32_t id) {
                              return node->id() == id;
                            });
   that->nodes_.erase(it, that->nodes_.end());
+
+  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 aec268e008..7dbba23691 100644
--- a/modules/video_capture/linux/pipewire_session.h
+++ b/modules/video_capture/linux/pipewire_session.h
@@ -28,6 +28,7 @@
 namespace webrtc {
 namespace videocapturemodule {
 
+class DeviceInfoPipeWire;
 class PipeWireSession;
 class VideoCaptureModulePipeWire;
 
@@ -96,6 +97,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_;
   }
@@ -110,6 +126,8 @@ class PipeWireSession : public webrtc::RefCountedNonVirtual<PipeWireSession> {
   void StopPipeWire();
   void PipeWireSync();
 
+  void NotifyDeviceChange();
+
   static void OnCoreError(void* data,
                           uint32_t id,
                           int seq,
@@ -132,7 +150,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_);
 
   struct pw_thread_loop* pw_main_loop_ = nullptr;
   struct pw_context* pw_context_ = nullptr;