Video capture PipeWire: guard callback to avoid concurrent access

Make sure the callback is reset when tearing down the PipeWireSession
and that there is no concurrent access to it, which can potentially lead
to a crash.

Bug: webrtc:15386
Change-Id: I0b09002fe0479dc1cd946c80684bcc5d8754d54a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/311546
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Jan Grulich <grulja@gmail.com>
Cr-Commit-Position: refs/heads/main@{#40464}
diff --git a/modules/video_capture/linux/pipewire_session.cc b/modules/video_capture/linux/pipewire_session.cc
index 2adb1cd..3f52b3d 100644
--- a/modules/video_capture/linux/pipewire_session.cc
+++ b/modules/video_capture/linux/pipewire_session.cc
@@ -232,7 +232,10 @@
 }
 
 void PipeWireSession::Init(VideoCaptureOptions::Callback* callback, int fd) {
-  callback_ = callback;
+  {
+    webrtc::MutexLock lock(&callback_lock_);
+    callback_ = callback;
+  }
 
   if (fd != kInvalidPipeWireFd) {
     InitPipeWire(fd);
@@ -374,6 +377,8 @@
 }
 
 void PipeWireSession::Finish(VideoCaptureOptions::Status status) {
+  webrtc::MutexLock lock(&callback_lock_);
+
   if (callback_) {
     callback_->OnInitialized(status);
     callback_ = nullptr;
@@ -381,6 +386,9 @@
 }
 
 void PipeWireSession::Cleanup() {
+  webrtc::MutexLock lock(&callback_lock_);
+  callback_ = nullptr;
+
   StopPipeWire();
 }
 
diff --git a/modules/video_capture/linux/pipewire_session.h b/modules/video_capture/linux/pipewire_session.h
index 982b468..fdc06a6 100644
--- a/modules/video_capture/linux/pipewire_session.h
+++ b/modules/video_capture/linux/pipewire_session.h
@@ -24,6 +24,7 @@
 #include "modules/video_capture/linux/camera_portal.h"
 #include "modules/video_capture/video_capture.h"
 #include "modules/video_capture/video_capture_options.h"
+#include "rtc_base/synchronization/mutex.h"
 
 namespace webrtc {
 namespace videocapturemodule {
@@ -117,7 +118,9 @@
   void Finish(VideoCaptureOptions::Status status);
   void Cleanup();
 
-  VideoCaptureOptions::Callback* callback_ = nullptr;
+  webrtc::Mutex callback_lock_;
+  VideoCaptureOptions::Callback* callback_ RTC_GUARDED_BY(&callback_lock_) =
+      nullptr;
 
   VideoCaptureOptions::Status status_;