From a5d71009ac1dce7da23813dc9413c03073cfa8ca Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Thu, 7 Nov 2024 15:39:25 +0100 Subject: [PATCH] PipeWire camera: use better unique device name for camera devices Originally we used node id from PipeWire as an unique device name and while this works, it will change everytime PipeWire is restarted. This has an impact on default camera selection, where for example Firefox can automatically request a camera device that was used before, but this can break with the next PipeWire restart. Bug: webrtc:42225999 Change-Id: I9440ee065ffeaa1ffb911a4dc7c405d57c9416dc Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/367880 Commit-Queue: Jan Grulich Reviewed-by: Ilya Nikolaevskiy Cr-Commit-Position: refs/heads/main@{#43387} --- modules/video_capture/linux/pipewire_session.cc | 2 +- modules/video_capture/linux/video_capture_pipewire.cc | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/video_capture/linux/pipewire_session.cc b/modules/video_capture/linux/pipewire_session.cc index 85ccb289d8..98eb656096 100644 --- a/modules/video_capture/linux/pipewire_session.cc +++ b/modules/video_capture/linux/pipewire_session.cc @@ -75,7 +75,7 @@ PipeWireNode::PipeWireNode(PipeWireSession* session, : session_(session), id_(id), display_name_(spa_dict_lookup(props, PW_KEY_NODE_DESCRIPTION)), - unique_id_(rtc::ToString(id)) { + unique_id_(spa_dict_lookup(props, PW_KEY_NODE_NAME)) { RTC_LOG(LS_VERBOSE) << "Found Camera: " << display_name_; proxy_ = static_cast(pw_registry_bind( diff --git a/modules/video_capture/linux/video_capture_pipewire.cc b/modules/video_capture/linux/video_capture_pipewire.cc index e9d99133f5..f6cd57ac36 100644 --- a/modules/video_capture/linux/video_capture_pipewire.cc +++ b/modules/video_capture/linux/video_capture_pipewire.cc @@ -83,12 +83,15 @@ int32_t VideoCaptureModulePipeWire::Init(const char* deviceUniqueId) { RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); RTC_DCHECK_RUN_ON(&api_checker_); - std::optional id; - id = rtc::StringToNumber(deviceUniqueId); - if (id == std::nullopt) + auto node = + std::find_if(session_->nodes_.begin(), session_->nodes_.end(), + [deviceUniqueId](const PipeWireNode::PipeWireNodePtr& node) { + return node->unique_id() == deviceUniqueId; + }); + if (node == session_->nodes_.end()) return -1; - node_id_ = id.value(); + node_id_ = (*node)->id(); const int len = strlen(deviceUniqueId); _deviceUniqueId = new (std::nothrow) char[len + 1];