diff --git a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.h b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.h --- a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.h +++ b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.h @@ -41,22 +41,20 @@ static void OnStreamProcess(void* data); void OnFormatChanged(const struct spa_pod* format); void ProcessBuffers(); - rtc::RaceChecker pipewire_checker_; - const rtc::scoped_refptr session_ - RTC_GUARDED_BY(capture_checker_); + RTC_GUARDED_BY(api_checker_); + bool initialized_ RTC_GUARDED_BY(api_checker_); + bool started_ RTC_GUARDED_BY(api_lock_); int node_id_ RTC_GUARDED_BY(capture_checker_); VideoCaptureCapability configured_capability_ - RTC_GUARDED_BY(pipewire_checker_); - bool initialized_ RTC_GUARDED_BY(capture_checker_); - bool started_ RTC_GUARDED_BY(api_lock_); + RTC_GUARDED_BY(capture_checker_); - struct pw_stream* stream_ RTC_GUARDED_BY(pipewire_checker_) = nullptr; - struct spa_hook stream_listener_ RTC_GUARDED_BY(pipewire_checker_); + struct pw_stream* stream_ RTC_GUARDED_BY(capture_checker_) = nullptr; + struct spa_hook stream_listener_ RTC_GUARDED_BY(capture_checker_); }; } // namespace videocapturemodule } // namespace webrtc #endif // MODULES_VIDEO_CAPTURE_LINUX_VIDEO_CAPTURE_PIPEWIRE_H_ diff --git a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc --- a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc +++ b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc @@ -119,11 +119,10 @@ return static_cast(spa_pod_builder_pop(builder, &frames[0])); } int32_t VideoCaptureModulePipeWire::StartCapture( const VideoCaptureCapability& capability) { - RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); RTC_DCHECK_RUN_ON(&api_checker_); if (initialized_) { if (capability == _requestedCapability) { return 0; @@ -132,14 +131,21 @@ } } uint8_t buffer[1024] = {}; + // We don't want members above to be guarded by capture_checker_ as + // it's meant to be for members that are accessed on the API thread + // only when we are not capturing. The code above can be called many + // times while sharing instance of VideoCapturePipeWire between + // websites and therefore it would not follow the requirements of this + // checker. + RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); + PipeWireThreadLoopLock thread_loop_lock(session_->pw_main_loop_); + RTC_LOG(LS_VERBOSE) << "Creating new PipeWire stream for node " << node_id_; - PipeWireThreadLoopLock thread_loop_lock(session_->pw_main_loop_); - RTC_CHECK_RUNS_SERIALIZED(&pipewire_checker_); pw_properties* reuse_props = pw_properties_new_string("pipewire.client.reuse=1"); stream_ = pw_stream_new(session_->pw_core_, "camera-stream", reuse_props); if (!stream_) { @@ -186,15 +192,17 @@ return 0; } int32_t VideoCaptureModulePipeWire::StopCapture() { - RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); RTC_DCHECK_RUN_ON(&api_checker_); PipeWireThreadLoopLock thread_loop_lock(session_->pw_main_loop_); - RTC_CHECK_RUNS_SERIALIZED(&pipewire_checker_); + // PipeWireSession is guarded by API checker so just make sure we do + // race detection when the PipeWire loop is locked/stopped to not run + // any callback at this point. + RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); if (stream_) { pw_stream_destroy(stream_); stream_ = nullptr; } @@ -223,18 +231,18 @@ uint32_t id, const struct spa_pod* format) { VideoCaptureModulePipeWire* that = static_cast(data); RTC_DCHECK(that); - RTC_CHECK_RUNS_SERIALIZED(&that->pipewire_checker_); + RTC_CHECK_RUNS_SERIALIZED(&that->capture_checker_); if (format && id == SPA_PARAM_Format) that->OnFormatChanged(format); } void VideoCaptureModulePipeWire::OnFormatChanged(const struct spa_pod* format) { - RTC_CHECK_RUNS_SERIALIZED(&pipewire_checker_); + RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); uint32_t media_type, media_subtype; if (spa_format_parse(format, &media_type, &media_subtype) < 0) { RTC_LOG(LS_ERROR) << "Failed to parse video format."; @@ -329,11 +337,10 @@ pw_stream_state state, const char* error_message) { VideoCaptureModulePipeWire* that = static_cast(data); RTC_DCHECK(that); - RTC_CHECK_RUNS_SERIALIZED(&that->capture_checker_); MutexLock lock(&that->api_lock_); switch (state) { case PW_STREAM_STATE_STREAMING: that->started_ = true; @@ -372,11 +379,11 @@ return kVideoRotation_0; } } void VideoCaptureModulePipeWire::ProcessBuffers() { - RTC_CHECK_RUNS_SERIALIZED(&pipewire_checker_); + RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); while (pw_buffer* buffer = pw_stream_dequeue_buffer(stream_)) { struct spa_meta_header* h; h = static_cast( spa_buffer_find_meta_data(buffer->buffer, SPA_META_Header, sizeof(*h))); diff --git a/third_party/libwebrtc/moz-patch-stack/541f202354.no-op-cherry-pick-msg b/third_party/libwebrtc/moz-patch-stack/541f202354.no-op-cherry-pick-msg new file mode 100644 --- /dev/null +++ b/third_party/libwebrtc/moz-patch-stack/541f202354.no-op-cherry-pick-msg @@ -0,0 +1 @@ +We cherry-picked this in bug 1879752.