From patchwork Tue Aug 4 16:13:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9184 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id C9F28BD87A for ; Tue, 4 Aug 2020 16:14:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9CD9F6055A; Tue, 4 Aug 2020 18:14:21 +0200 (CEST) Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9AC8E60547 for ; Tue, 4 Aug 2020 18:14:20 +0200 (CEST) X-Halon-ID: 8c9998c5-d66d-11ea-b48b-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id 8c9998c5-d66d-11ea-b48b-0050569116f7; Tue, 04 Aug 2020 18:14:19 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 4 Aug 2020 18:13:50 +0200 Message-Id: <20200804161358.1628962-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> References: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 1/9] libcamera: sysfs: Add new namespace to interact with sysfs X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" To support stable and unique camera IDs access to information in sysfs is needed. Add a new libcamera::sysfs namespace to contain such sysfs helpers. As a first helper add a method to lookup a character device sysfs path. Suggested-by: Laurent Pinchart Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- include/libcamera/internal/meson.build | 1 + include/libcamera/internal/sysfs.h | 22 ++++++++++++ src/libcamera/meson.build | 1 + src/libcamera/sysfs.cpp | 48 ++++++++++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 include/libcamera/internal/sysfs.h create mode 100644 src/libcamera/sysfs.cpp diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index d868eff47f920da0..150103388fdb219d 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -25,6 +25,7 @@ libcamera_internal_headers = files([ 'process.h', 'pub_key.h', 'semaphore.h', + 'sysfs.h', 'thread.h', 'utils.h', 'v4l2_controls.h', diff --git a/include/libcamera/internal/sysfs.h b/include/libcamera/internal/sysfs.h new file mode 100644 index 0000000000000000..72f436205d8d30e8 --- /dev/null +++ b/include/libcamera/internal/sysfs.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * sysfs.h - Miscellaneous utility functions to access sysfs + */ +#ifndef __LIBCAMERA_INTERNAL_SYSFS_H__ +#define __LIBCAMERA_INTERNAL_SYSFS_H__ + +#include + +namespace libcamera { + +namespace sysfs { + +std::string charDevPath(const std::string &devicePath); + +} /* namespace sysfs */ + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_INTERNAL_SYSFS_H__ */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 3aad4386ffc296db..bada45bcb11e9e88 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -41,6 +41,7 @@ libcamera_sources = files([ 'semaphore.cpp', 'signal.cpp', 'stream.cpp', + 'sysfs.cpp', 'thread.cpp', 'timer.cpp', 'utils.cpp', diff --git a/src/libcamera/sysfs.cpp b/src/libcamera/sysfs.cpp new file mode 100644 index 0000000000000000..3b2920663e9c3bcc --- /dev/null +++ b/src/libcamera/sysfs.cpp @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * sysfs.cpp - Miscellaneous utility functions to access sysfs + */ + +#include "libcamera/internal/sysfs.h" + +#include +#include + +#include "libcamera/internal/log.h" + +/** + * \file sysfs.h + * \brief Miscellaneous utility functions to access sysfs + */ + +namespace libcamera { + +LOG_DEFINE_CATEGORY(SYSFS); + +namespace sysfs { + +/** + * \brief Retrive the sysfs path for a characther device + * \param[in] devicePath Path to charachter device + * \return The sysfs path on success or empty string on failure + */ +std::string charDevPath(const std::string &devicePath) +{ + struct stat st; + int ret = stat(devicePath.c_str(), &st); + if (ret < 0) { + LOG(SYSFS, Error) + << "Unable to stat '" << devicePath << "'"; + return {}; + } + + std::ostringstream dev("/sys/dev/char/", std::ios_base::ate); + dev << major(st.st_rdev) << ":" << minor(st.st_rdev); + return dev.str(); +} + +} /* namespace sysfs */ + +} /* namespace libcamera */ From patchwork Tue Aug 4 16:13:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9185 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 417EEBD87A for ; Tue, 4 Aug 2020 16:14:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id ECCF160555; Tue, 4 Aug 2020 18:14:24 +0200 (CEST) Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5C29660547 for ; Tue, 4 Aug 2020 18:14:21 +0200 (CEST) X-Halon-ID: 8d526a04-d66d-11ea-b48b-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id 8d526a04-d66d-11ea-b48b-0050569116f7; Tue, 04 Aug 2020 18:14:20 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 4 Aug 2020 18:13:51 +0200 Message-Id: <20200804161358.1628962-3-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> References: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 2/9] libcamera: sysfs: Add method to lookup firmware ID X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" A systems firmware description is recorded differently in sysfs depending if the system uses OF or ACPI. Add a helper to abstract this, allowing users not to care which of the two are used. For OF-based systems the ID is the full path of the device in the device tree description. For ACPI-based systems the ID is the ACPI firmware nodes path. Both ID sources are guaranteed to be unique and persistent as long as the firmware of the system is not changed. Signed-off-by: Niklas Söderlund --- include/libcamera/internal/sysfs.h | 2 ++ src/libcamera/sysfs.cpp | 57 ++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/include/libcamera/internal/sysfs.h b/include/libcamera/internal/sysfs.h index 72f436205d8d30e8..ef8ec55909d85bf9 100644 --- a/include/libcamera/internal/sysfs.h +++ b/include/libcamera/internal/sysfs.h @@ -15,6 +15,8 @@ namespace sysfs { std::string charDevPath(const std::string &devicePath); +int firmwareId(const std::string &path, std::string *id); + } /* namespace sysfs */ } /* namespace libcamera */ diff --git a/src/libcamera/sysfs.cpp b/src/libcamera/sysfs.cpp index 3b2920663e9c3bcc..98be4df9d38e6fa8 100644 --- a/src/libcamera/sysfs.cpp +++ b/src/libcamera/sysfs.cpp @@ -7,9 +7,11 @@ #include "libcamera/internal/sysfs.h" +#include #include #include +#include "libcamera/internal/file.h" #include "libcamera/internal/log.h" /** @@ -43,6 +45,61 @@ std::string charDevPath(const std::string &devicePath) return dev.str(); } +/** + * \brief Try to read a device firmware ID from sysfs + * \param[in] path Path in sysfs to search + * \param[out] id Location to store ID if found + * + * A systems firmware description is recorded differently in sysfs depending if + * the system uses OF or ACPI. Add a helper to abstract this, allowing users not + * to care which of the two are used. + * + * For OF-based systems the ID is the full path of the device in the device tree + * description. For ACPI-based systems the ID is the ACPI firmware nodes path. + * Both ID sources are guaranteed to be unique and persistent as long as the + * firmware of the system is not changed. + * + * \return 0 on success or a negative error code otherwise + * \retval -EINVAL Error when looking up firmware ID + * \retval -ENODEV No firmware ID available for \a path + */ +int firmwareId(const std::string &path, std::string *id) +{ + ASSERT(id); + + /* ID lookup for OF-based systems */ + File ofFile(path + "/of_node"); + if (ofFile.exists()) { + char *ofPath = realpath(ofFile.fileName().c_str(), nullptr); + if (!ofPath) + return -EINVAL; + + *id = ofPath; + free(ofPath); + + static const std::string dropStr = "/sys/firmware/devicetree/"; + if (id->find(dropStr) == 0) + id->erase(0, dropStr.length()); + + return 0; + } + + /* ID lookup for ACPI-based systems */ + File acpiFile(path + "/firmware_node/path"); + if (acpiFile.exists()) { + std::ifstream file(acpiFile.fileName()); + if (!file.is_open()) + return -EINVAL; + + std::getline(file, *id); + file.close(); + + return 0; + } + + return -ENODEV; +} + } /* namespace sysfs */ } /* namespace libcamera */ From patchwork Tue Aug 4 16:13:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9186 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id C2E1BBD87A for ; Tue, 4 Aug 2020 16:14:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7F33260564; Tue, 4 Aug 2020 18:14:25 +0200 (CEST) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 200B560555 for ; Tue, 4 Aug 2020 18:14:22 +0200 (CEST) X-Halon-ID: 8db6e245-d66d-11ea-b48b-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id 8db6e245-d66d-11ea-b48b-0050569116f7; Tue, 04 Aug 2020 18:14:20 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 4 Aug 2020 18:13:52 +0200 Message-Id: <20200804161358.1628962-4-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> References: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 3/9] libcamera: v4l2_device: Add method to lookup device path X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add a method to lookup a V4L2 devices path in sysfs. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- * Changes since v6 - Use sysfs:: helper. - Do not try to return std::string { nullptr } on error. * Changes since v5 - Expand documentation - Use DeviceEnumerator interface to lookup device path - Include stdlib.h - Use realpath(..., nullptr); ...; free(); * Changes since v3 - s/the device path/the device path in sysfs/ --- include/libcamera/internal/v4l2_device.h | 1 + src/libcamera/v4l2_device.cpp | 28 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h index bf643f2ec966bb33..3b605aab343b3b94 100644 --- a/include/libcamera/internal/v4l2_device.h +++ b/include/libcamera/internal/v4l2_device.h @@ -30,6 +30,7 @@ public: int setControls(ControlList *ctrls); const std::string &deviceNode() const { return deviceNode_; } + std::string devicePath() const; protected: V4L2Device(const std::string &deviceNode); diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 56ea1ddda2c1425f..e55deabed46e30d4 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -9,12 +9,15 @@ #include #include +#include +#include #include #include #include #include #include "libcamera/internal/log.h" +#include "libcamera/internal/sysfs.h" #include "libcamera/internal/utils.h" #include "libcamera/internal/v4l2_controls.h" @@ -350,6 +353,31 @@ int V4L2Device::setControls(ControlList *ctrls) return ret; } +/** + * \brief Retrieve the device path in sysfs + * + * This function returns the sysfs path to the physical device backing the V4L2 + * device. The path is guaranteed to be an absolute path, without any symbolic + * link. + * + * \return The device path in sysfs + */ +std::string V4L2Device::devicePath() const +{ + std::string devicePath = sysfs::charDevPath(deviceNode_) + "/device"; + + char *realPath = realpath(devicePath.c_str(), nullptr); + if (!realPath) { + LOG(V4L2, Fatal) << "Can not resolve path for " << devicePath; + return {}; + } + + std::string path{ realPath }; + free(realPath); + + return path; +} + /** * \brief Perform an IOCTL system call on the device node * \param[in] request The IOCTL request code From patchwork Tue Aug 4 16:13:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9187 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 526AFBD87A for ; Tue, 4 Aug 2020 16:14:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AFE7B6055A; Tue, 4 Aug 2020 18:14:25 +0200 (CEST) Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9328B60548 for ; Tue, 4 Aug 2020 18:14:22 +0200 (CEST) X-Halon-ID: 8e18ce9c-d66d-11ea-b48b-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id 8e18ce9c-d66d-11ea-b48b-0050569116f7; Tue, 04 Aug 2020 18:14:21 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 4 Aug 2020 18:13:53 +0200 Message-Id: <20200804161358.1628962-5-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> References: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 4/9] libcamera: camera_sensor: Generate a sensor ID X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The ID is generated from information in the firmware description of the sensor if available or from module and model information if the sensor is virtual (for example VIMC). Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- * Changes sinve v6 - Do not allow for subclassing - Add support for virtual sensors - Use new sysfs:: helper. * Changes since v5 - Use new utils:: helper. - Allow for subclassing * Changes since v4 - Fix spelling. * Changes since v3 - Update commit message. - Add description of how ID are generated to comment. --- include/libcamera/internal/camera_sensor.h | 3 ++ src/libcamera/camera_sensor.cpp | 38 ++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h index 06c8292ca30129de..0f65fca46877e89a 100644 --- a/include/libcamera/internal/camera_sensor.h +++ b/include/libcamera/internal/camera_sensor.h @@ -67,11 +67,14 @@ protected: std::string logPrefix() const override; private: + int generateId(); + const MediaEntity *entity_; std::unique_ptr subdev_; unsigned int pad_; std::string model_; + std::string id_; V4L2Subdevice::Formats formats_; Size resolution_; diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index 350f49accad99c7b..3952d16b053ae20e 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -16,7 +17,9 @@ #include +#include "libcamera/internal/file.h" #include "libcamera/internal/formats.h" +#include "libcamera/internal/sysfs.h" #include "libcamera/internal/utils.h" /** @@ -204,6 +207,11 @@ int CameraSensor::init() if (ret < 0) return ret; + /* Generate a unique ID for the sensor. */ + ret = generateId(); + if (ret) + return ret; + /* Retrieve and store the camera sensor properties. */ const ControlInfoMap &controls = subdev_->controls(); int32_t propertyValue; @@ -541,4 +549,34 @@ std::string CameraSensor::logPrefix() const return "'" + entity_->name() + "'"; } +int CameraSensor::generateId() +{ + const std::string devPath = subdev_->devicePath(); + + /* Try to get ID from firmware description. */ + if (!sysfs::firmwareId(devPath, &id_)) + return 0; + + /* Virtual sensors not described in firmware, use modalias and model. */ + std::string path = devPath + "/modalias"; + if (File::exists(path)) { + std::ifstream file(path.c_str()); + + if (!file.is_open()) { + LOG(CameraSensor, Error) << "Failed to read modalias"; + return -EINVAL; + } + + std::string modalias; + std::getline(file, modalias); + file.close(); + + id_ = modalias + " " + model(); + return 0; + } + + LOG(CameraSensor, Error) << "Can't generate sensor ID"; + return -EINVAL; +} + } /* namespace libcamera */ From patchwork Tue Aug 4 16:13:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9188 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 7A82DBD87B for ; Tue, 4 Aug 2020 16:14:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CCE8F6059D; Tue, 4 Aug 2020 18:14:25 +0200 (CEST) Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2DAF160545 for ; Tue, 4 Aug 2020 18:14:23 +0200 (CEST) X-Halon-ID: 8e7c609a-d66d-11ea-b48b-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id 8e7c609a-d66d-11ea-b48b-0050569116f7; Tue, 04 Aug 2020 18:14:22 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 4 Aug 2020 18:13:54 +0200 Message-Id: <20200804161358.1628962-6-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> References: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 5/9] libcamera: camera_sensor: Add accessors for sensor ID X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add an accessors so that the sensor ID can be used outside CameraSensor. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- include/libcamera/internal/camera_sensor.h | 1 + src/libcamera/camera_sensor.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h index 0f65fca46877e89a..b9eba89f00fba882 100644 --- a/include/libcamera/internal/camera_sensor.h +++ b/include/libcamera/internal/camera_sensor.h @@ -47,6 +47,7 @@ public: int init(); const std::string &model() const { return model_; } + const std::string &id() const { return id_; } const MediaEntity *entity() const { return entity_; } const std::vector &mbusCodes() const { return mbusCodes_; } const std::vector &sizes() const { return sizes_; } diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index 3952d16b053ae20e..157e1d34a03a4a8e 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -291,6 +291,16 @@ int CameraSensor::init() * \return The sensor model name */ +/** + * \fn CameraSensor::id() + * \brief Retrieve the sensor ID + * + * The sensor ID is a free-form string that uniquely identifies the sensor in + * the system. The ID satisfy the requirements to be used as a camera ID. + * + * \return The sensor ID + */ + /** * \fn CameraSensor::entity() * \brief Retrieve the sensor media entity From patchwork Tue Aug 4 16:13:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9189 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 98B12BD87C for ; Tue, 4 Aug 2020 16:14:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E86FB605A8; Tue, 4 Aug 2020 18:14:25 +0200 (CEST) Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 16B0260545 for ; Tue, 4 Aug 2020 18:14:24 +0200 (CEST) X-Halon-ID: 8ed4db1f-d66d-11ea-b48b-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id 8ed4db1f-d66d-11ea-b48b-0050569116f7; Tue, 04 Aug 2020 18:14:22 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 4 Aug 2020 18:13:55 +0200 Message-Id: <20200804161358.1628962-7-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> References: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 6/9] libcamera: pipelines: Use sensor ID as camera name X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Use the CameraSensor ID as the camera name in pipelines that uses a CameraSensors, this is done in preparation of turning the camera name into an ID. The CameraSensor ID meets the requirements that will be put on camera ID. Before this change example of camera names: * OF based systems ov5695 7-0036 ov2685 7-003c * ACPI based systems ov13858 8-0010 ov5670 10-0036 * VIMC VIMC Sensor B After this change the same cameras are: * OF based systems base/i2c@ff160000/camera@36 base/i2c@ff160000/camera@3c * ACPI based systems \_SB_.PCI0.I2C2.CAM0 \_SB_.PCI0.I2C4.CAM1 * VIMC platform:vimc Sensor B Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 7 +++---- src/libcamera/pipeline/raspberrypi/raspberrypi.cpp | 3 ++- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 2 +- src/libcamera/pipeline/simple/simple.cpp | 2 +- src/libcamera/pipeline/vimc/vimc.cpp | 4 ++-- test/camera/buffer_import.cpp | 2 +- test/camera/capture.cpp | 2 +- test/camera/configuration_default.cpp | 2 +- test/camera/configuration_set.cpp | 2 +- test/camera/statemachine.cpp | 2 +- test/controls/control_info_map.cpp | 2 +- test/controls/control_list.cpp | 2 +- test/serialization/serialization_test.h | 2 +- 13 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index c1f9fdf1013c7ec0..c300f570d727e03e 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -805,10 +805,9 @@ int PipelineHandlerIPU3::registerCameras() &IPU3CameraData::imguOutputBufferReady); /* Create and register the Camera instance. */ - std::string cameraName = cio2->sensor()->entity()->name(); - std::shared_ptr camera = Camera::create(this, - cameraName, - streams); + std::string cameraName = cio2->sensor()->id(); + std::shared_ptr camera = + Camera::create(this, cameraName, streams); registerCamera(std::move(camera), std::move(data)); diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 82a0a4dfd6824fce..c55d7325cd44d6cb 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -972,7 +972,8 @@ bool PipelineHandlerRPi::match(DeviceEnumerator *enumerator) streams.insert(&data->isp_[Isp::Stats]); /* Create and register the camera. */ - std::shared_ptr camera = Camera::create(this, data->sensor_->model(), streams); + std::shared_ptr camera = + Camera::create(this, data->sensor_->id(), streams); registerCamera(std::move(camera), std::move(data)); return true; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 52a0d862417cc4ec..94561062c2b9d4fc 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -971,7 +971,7 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) std::set streams{ &data->stream_ }; std::shared_ptr camera = - Camera::create(this, sensor->name(), streams); + Camera::create(this, data->sensor_->id(), streams); registerCamera(std::move(camera), std::move(data)); return 0; diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 0bab5af86f05d63c..eb72e3b8a2996342 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -815,7 +815,7 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) continue; std::shared_ptr camera = - Camera::create(this, data->sensor_->entity()->name(), + Camera::create(this, data->sensor_->id(), data->streams()); registerCamera(std::move(camera), std::move(data)); } diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 4f461b928514022d..cf244f11f2423dea 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -432,9 +432,9 @@ bool PipelineHandlerVimc::match(DeviceEnumerator *enumerator) return false; /* Create and register the camera. */ - std::string name{ "VIMC " + data->sensor_->model() }; std::set streams{ &data->stream_ }; - std::shared_ptr camera = Camera::create(this, name, streams); + std::shared_ptr camera = + Camera::create(this, data->sensor_->id(), streams); registerCamera(std::move(camera), std::move(data)); return true; diff --git a/test/camera/buffer_import.cpp b/test/camera/buffer_import.cpp index ad680a83f9187213..e8a7d1df52d3782c 100644 --- a/test/camera/buffer_import.cpp +++ b/test/camera/buffer_import.cpp @@ -28,7 +28,7 @@ class BufferImportTest : public CameraTest, public Test { public: BufferImportTest() - : CameraTest("VIMC Sensor B") + : CameraTest("platform:vimc Sensor B") { } diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp index f6b2f348bda52752..d5ed6e72626cf87d 100644 --- a/test/camera/capture.cpp +++ b/test/camera/capture.cpp @@ -18,7 +18,7 @@ class Capture : public CameraTest, public Test { public: Capture() - : CameraTest("VIMC Sensor B") + : CameraTest("platform:vimc Sensor B") { } diff --git a/test/camera/configuration_default.cpp b/test/camera/configuration_default.cpp index 31c908d2449eafe7..ea97493d915fd107 100644 --- a/test/camera/configuration_default.cpp +++ b/test/camera/configuration_default.cpp @@ -18,7 +18,7 @@ class ConfigurationDefault : public CameraTest, public Test { public: ConfigurationDefault() - : CameraTest("VIMC Sensor B") + : CameraTest("platform:vimc Sensor B") { } diff --git a/test/camera/configuration_set.cpp b/test/camera/configuration_set.cpp index b4b5968115e81f59..b1fa8fea2edd7683 100644 --- a/test/camera/configuration_set.cpp +++ b/test/camera/configuration_set.cpp @@ -18,7 +18,7 @@ class ConfigurationSet : public CameraTest, public Test { public: ConfigurationSet() - : CameraTest("VIMC Sensor B") + : CameraTest("platform:vimc Sensor B") { } diff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp index 325b4674bcc958d8..0e7c43dd84399a5a 100644 --- a/test/camera/statemachine.cpp +++ b/test/camera/statemachine.cpp @@ -18,7 +18,7 @@ class Statemachine : public CameraTest, public Test { public: Statemachine() - : CameraTest("VIMC Sensor B") + : CameraTest("platform:vimc Sensor B") { } diff --git a/test/controls/control_info_map.cpp b/test/controls/control_info_map.cpp index e4305f132db7952f..72987646a63dab6b 100644 --- a/test/controls/control_info_map.cpp +++ b/test/controls/control_info_map.cpp @@ -24,7 +24,7 @@ class ControlInfoMapTest : public CameraTest, public Test { public: ControlInfoMapTest() - : CameraTest("VIMC Sensor B") + : CameraTest("platform:vimc Sensor B") { } diff --git a/test/controls/control_list.cpp b/test/controls/control_list.cpp index 5c8485b5dcc31499..9a0fe53c022246f1 100644 --- a/test/controls/control_list.cpp +++ b/test/controls/control_list.cpp @@ -24,7 +24,7 @@ class ControlListTest : public CameraTest, public Test { public: ControlListTest() - : CameraTest("VIMC Sensor B") + : CameraTest("platform:vimc Sensor B") { } diff --git a/test/serialization/serialization_test.h b/test/serialization/serialization_test.h index fe77221ef5d07478..5d4a6cd80a6e2208 100644 --- a/test/serialization/serialization_test.h +++ b/test/serialization/serialization_test.h @@ -20,7 +20,7 @@ class SerializationTest : public CameraTest, public Test { public: SerializationTest() - : CameraTest("VIMC Sensor B") + : CameraTest("platform:vimc Sensor B") { } From patchwork Tue Aug 4 16:13:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9190 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id B3A40BD87D for ; Tue, 4 Aug 2020 16:14:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1318E605AB; Tue, 4 Aug 2020 18:14:26 +0200 (CEST) Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C481660545 for ; Tue, 4 Aug 2020 18:14:24 +0200 (CEST) X-Halon-ID: 8f5e5ffc-d66d-11ea-b48b-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id 8f5e5ffc-d66d-11ea-b48b-0050569116f7; Tue, 04 Aug 2020 18:14:23 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 4 Aug 2020 18:13:56 +0200 Message-Id: <20200804161358.1628962-8-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> References: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 7/9] libcamera: pipeline: uvcvideo: Generate unique camera names X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Generate camera names that are unique and persistent between system resets. The name is constructed from the USB device information as well as the USB controller on the host. Before this change example of camera names: Venus USB2.0 Camera: Venus USB2 Logitech Webcam C930e After this change the same cameras are: \_SB_.PCI0.RP05.PXSX-2.1.1:1.0-0ac8:3420 \_SB_.PCI0.RP05.PXSX-2.4:1.0-046d:0843 On OF-based system: base/soc/usb@7e980000/usb-port@1-1.3:1.0-0ac8:3420 Signed-off-by: Niklas Söderlund --- * Changes since v5 - New algorithm to generate IDs. * Changes since v3 - Switch argument to generateName() to UVCCameraData pointer. --- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 77 +++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 93e3dc17e3a7105e..70c057b543f85c7b 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -20,6 +21,7 @@ #include "libcamera/internal/log.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/pipeline_handler.h" +#include "libcamera/internal/sysfs.h" #include "libcamera/internal/utils.h" #include "libcamera/internal/v4l2_controls.h" #include "libcamera/internal/v4l2_videodevice.h" @@ -81,6 +83,8 @@ public: bool match(DeviceEnumerator *enumerator) override; private: + std::string generateID(const UVCCameraData *data); + int processControl(ControlList *controls, unsigned int id, const ControlValue &value); int processControls(UVCCameraData *data, Request *request); @@ -379,6 +383,71 @@ int PipelineHandlerUVC::queueRequestDevice(Camera *camera, Request *request) return 0; } +std::string PipelineHandlerUVC::generateID(const UVCCameraData *data) +{ + const std::string path = data->video_->devicePath(); + + /* Creata a device ID from the USB devices vendor and product ID. */ + std::string deviceId; + for (const std::string &name : { "idVendor", "idProduct" }) { + std::ifstream file(path + "/../" + name); + + if (!file.is_open()) + return {}; + + std::string value; + std::getline(file, value); + file.close(); + + deviceId += value + (deviceId.empty() ? ":" : ""); + } + + /* + * Create a USB ID from the device path which has the known format: + * + * bus , "-", ports, ":", config, ".", interface ; + * bus = number ; + * ports = port, [ ".", ports ] ; + * port = number ; + * config = number ; + * interface = number ; + * + * Example: 3-2.4:1.0 + * + * The bus is not guaranteed to be stable and needs to be stripped from + * the USB ID. The final USB ID is built up of the ports, config and + * interface properties. + * + * Example 2.4:1.0. + */ + std::string usbId = basename(path.c_str()); + usbId = usbId.substr(usbId.find('-') + 1, std::string::npos); + + /* Create a controller ID from first device described in firmware. */ + std::string controllerId; + std::string searchPath = path; + while (true) { + searchPath += "/.."; + char *realPath = realpath(searchPath.c_str(), nullptr); + if (!realPath) { + LOG(UVC, Error) << "Failed to lookup " << searchPath; + return {}; + } + searchPath = realPath; + free(realPath); + + if (searchPath.empty() || searchPath == "/") { + LOG(UVC, Error) << "Can not find controller ID"; + return {}; + } + + if (!sysfs::firmwareId(searchPath, &controllerId)) + break; + } + + return controllerId + "-" + usbId + "-" + deviceId; +} + bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) { MediaDevice *media; @@ -405,8 +474,14 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) return false; /* Create and register the camera. */ + std::string id = generateID(data.get()); + if (id.empty()) { + LOG(UVC, Error) << "Failed to generate camera ID"; + return false; + } + std::set streams{ &data->stream_ }; - std::shared_ptr camera = Camera::create(this, media->model(), streams); + std::shared_ptr camera = Camera::create(this, id, streams); registerCamera(std::move(camera), std::move(data)); /* Enable hot-unplug notifications. */ From patchwork Tue Aug 4 16:13:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9191 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 854EDBD87A for ; Tue, 4 Aug 2020 16:14:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 610AA60564; Tue, 4 Aug 2020 18:14:28 +0200 (CEST) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 65F6E60552 for ; Tue, 4 Aug 2020 18:14:26 +0200 (CEST) X-Halon-ID: 8fcc3463-d66d-11ea-b48b-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id 8fcc3463-d66d-11ea-b48b-0050569116f7; Tue, 04 Aug 2020 18:14:24 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 4 Aug 2020 18:13:57 +0200 Message-Id: <20200804161358.1628962-9-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> References: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 8/9] libcamera: camera: Rename name() to id() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Rename Camera::name() to camera::id() to better describe what it represents, a unique and stable ID for the camera. While at it improve the documentation for the camera ID to describe it needs to be stable for a camera between resets of the system. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- include/libcamera/camera.h | 6 +-- src/android/camera_device.cpp | 4 +- src/cam/main.cpp | 8 ++-- src/gstreamer/gstlibcameraprovider.cpp | 4 +- src/gstreamer/gstlibcamerasrc.cpp | 6 +-- src/libcamera/camera.cpp | 40 ++++++++++++------- src/libcamera/camera_controls.cpp | 2 +- src/libcamera/camera_manager.cpp | 16 ++++---- src/libcamera/framebuffer_allocator.cpp | 2 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 5 +-- .../pipeline/raspberrypi/raspberrypi.cpp | 4 +- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 14 +++---- src/qcam/dng_writer.cpp | 4 +- src/qcam/main_window.cpp | 18 ++++----- src/v4l2/v4l2_camera_proxy.cpp | 2 +- test/pipeline/ipu3/ipu3_pipeline_test.cpp | 2 +- test/pipeline/rkisp1/rkisp1_pipeline_test.cpp | 2 +- 17 files changed, 74 insertions(+), 65 deletions(-) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 7dd23d75864ef2db..48d88d64a0a94050 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -71,13 +71,13 @@ class Camera final : public Object, public std::enable_shared_from_this { public: static std::shared_ptr create(PipelineHandler *pipe, - const std::string &name, + const std::string &id, const std::set &streams); Camera(const Camera &) = delete; Camera &operator=(const Camera &) = delete; - const std::string &name() const; + const std::string &id() const; Signal bufferCompleted; Signal requestCompleted; @@ -100,7 +100,7 @@ public: int stop(); private: - Camera(PipelineHandler *pipe, const std::string &name, + Camera(PipelineHandler *pipe, const std::string &id, const std::set &streams); ~Camera(); diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index b5206fd623c62b23..c74e8a6e84251838 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -1072,7 +1072,7 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list) int ret = camera_->configure(config_.get()); if (ret) { LOG(HAL, Error) << "Failed to configure camera '" - << camera_->name() << "'"; + << camera_->id() << "'"; return ret; } @@ -1240,7 +1240,7 @@ void CameraDevice::requestComplete(Request *request) std::string CameraDevice::logPrefix() const { - return "'" + camera_->name() + "'"; + return "'" + camera_->id() + "'"; } void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp) diff --git a/src/cam/main.cpp b/src/cam/main.cpp index ec59e9eaf1176a94..6791e57bfdea05b2 100644 --- a/src/cam/main.cpp +++ b/src/cam/main.cpp @@ -118,7 +118,7 @@ int CamApp::init(int argc, char **argv) return -EINVAL; } - std::cout << "Using camera " << camera_->name() << std::endl; + std::cout << "Using camera " << camera_->id() << std::endl; ret = prepareConfig(); if (ret) @@ -322,12 +322,12 @@ int CamApp::infoConfiguration() void CamApp::cameraAdded(std::shared_ptr cam) { - std::cout << "Camera Added: " << cam->name() << std::endl; + std::cout << "Camera Added: " << cam->id() << std::endl; } void CamApp::cameraRemoved(std::shared_ptr cam) { - std::cout << "Camera Removed: " << cam->name() << std::endl; + std::cout << "Camera Removed: " << cam->id() << std::endl; } int CamApp::run() @@ -339,7 +339,7 @@ int CamApp::run() unsigned int index = 1; for (const std::shared_ptr &cam : cm_->cameras()) { - std::cout << index << ": " << cam->name() << std::endl; + std::cout << index << ": " << cam->id() << std::endl; index++; } } diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp index 914ed4fb1612b8c9..840e87a3d8daeae4 100644 --- a/src/gstreamer/gstlibcameraprovider.cpp +++ b/src/gstreamer/gstlibcameraprovider.cpp @@ -127,7 +127,7 @@ static GstDevice * gst_libcamera_device_new(const std::shared_ptr &camera) { g_autoptr(GstCaps) caps = gst_caps_new_empty(); - const gchar *name = camera->name().c_str(); + const gchar *name = camera->id().c_str(); StreamRoles roles; roles.push_back(StreamRole::VideoRecording); @@ -189,7 +189,7 @@ gst_libcamera_provider_probe(GstDeviceProvider *provider) } for (const std::shared_ptr &camera : cm->cameras()) { - GST_INFO_OBJECT(self, "Found camera '%s'", camera->name().c_str()); + GST_INFO_OBJECT(self, "Found camera '%s'", camera->id().c_str()); devices = g_list_append(devices, g_object_ref_sink(gst_libcamera_device_new(camera))); } diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index 9755922ad59b22f6..0c28ae3f28529df2 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -241,12 +241,12 @@ gst_libcamera_src_open(GstLibcameraSrc *self) cam = cm->cameras()[0]; } - GST_INFO_OBJECT(self, "Using camera named '%s'", cam->name().c_str()); + GST_INFO_OBJECT(self, "Using camera '%s'", cam->id().c_str()); ret = cam->acquire(); if (ret) { GST_ELEMENT_ERROR(self, RESOURCE, BUSY, - ("Camera name '%s' is already in use.", cam->name().c_str()), + ("Camera '%s' is already in use.", cam->id().c_str()), ("libcamera::Camera::acquire() failed: %s", g_strerror(ret))); return false; } @@ -495,7 +495,7 @@ gst_libcamera_src_close(GstLibcameraSrc *self) ret = state->cam_->release(); if (ret) { GST_ELEMENT_WARNING(self, RESOURCE, BUSY, - ("Camera name '%s' is still in use.", state->cam_->name().c_str()), + ("Camera '%s' is still in use.", state->cam_->id().c_str()), ("libcamera::Camera.release() failed: %s", g_strerror(-ret))); } diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 99cb5048ee06e3d3..a547542d1b67cc2b 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -265,7 +265,7 @@ public: CameraRunning, }; - Private(PipelineHandler *pipe, const std::string &name, + Private(PipelineHandler *pipe, const std::string &id, const std::set &streams); ~Private(); @@ -277,7 +277,7 @@ public: void setState(State state); std::shared_ptr pipe_; - std::string name_; + std::string id_; std::set streams_; std::set activeStreams_; @@ -286,9 +286,9 @@ private: std::atomic state_; }; -Camera::Private::Private(PipelineHandler *pipe, const std::string &name, +Camera::Private::Private(PipelineHandler *pipe, const std::string &id, const std::set &streams) - : pipe_(pipe->shared_from_this()), name_(name), streams_(streams), + : pipe_(pipe->shared_from_this()), id_(id), streams_(streams), disconnected_(false), state_(CameraAvailable) { } @@ -450,15 +450,25 @@ void Camera::Private::setState(State state) /** * \brief Create a camera instance * \param[in] pipe The pipeline handler responsible for the camera device - * \param[in] name The name of the camera device + * \param[in] id The ID of the camera device * \param[in] streams Array of streams the camera provides * - * The caller is responsible for guaranteeing unicity of the camera name. + * The caller is responsible for guaranteeing a stable and unique camera ID. For + * an ID to be stable it must be the same each time the pipeline handler creates + * it, even between system resets. Parameters that are enumerated at system + * startup such as bus parameters which might be enumerated differently are + * therefor not possible to use in the ID. For an ID to be unique no pipeline + * should generate an ID that could conflict, either with IDs from the same + * pipeline handle or any other. + * + * Pipeline handlers that use a CameraSensor may use the CameraSensor::id() to + * generate and ID which satisfies the criteria of a stable and unique camera + * ID. * * \return A shared pointer to the newly created camera object */ std::shared_ptr Camera::create(PipelineHandler *pipe, - const std::string &name, + const std::string &id, const std::set &streams) { struct Deleter : std::default_delete { @@ -468,19 +478,19 @@ std::shared_ptr Camera::create(PipelineHandler *pipe, } }; - Camera *camera = new Camera(pipe, name, streams); + Camera *camera = new Camera(pipe, id, streams); return std::shared_ptr(camera, Deleter()); } /** - * \brief Retrieve the name of the camera + * \brief Retrieve the ID of the camera * \context This function is \threadsafe. - * \return Name of the camera device + * \return ID of the camera device */ -const std::string &Camera::name() const +const std::string &Camera::id() const { - return p_->name_; + return p_->id_; } /** @@ -506,9 +516,9 @@ const std::string &Camera::name() const * application API calls by returning errors immediately. */ -Camera::Camera(PipelineHandler *pipe, const std::string &name, +Camera::Camera(PipelineHandler *pipe, const std::string &id, const std::set &streams) - : p_(new Private(pipe, name, streams)) + : p_(new Private(pipe, id, streams)) { } @@ -530,7 +540,7 @@ Camera::~Camera() */ void Camera::disconnect() { - LOG(Camera, Debug) << "Disconnecting camera " << name(); + LOG(Camera, Debug) << "Disconnecting camera " << id(); p_->disconnect(); disconnected.emit(this); diff --git a/src/libcamera/camera_controls.cpp b/src/libcamera/camera_controls.cpp index 371f6d079e2d877c..cabdcf75c223fc3e 100644 --- a/src/libcamera/camera_controls.cpp +++ b/src/libcamera/camera_controls.cpp @@ -36,7 +36,7 @@ CameraControlValidator::CameraControlValidator(Camera *camera) const std::string &CameraControlValidator::name() const { - return camera_->name(); + return camera_->id(); } /** diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp index c45bf33fdc1ef01b..76543b6aac8df9c4 100644 --- a/src/libcamera/camera_manager.cpp +++ b/src/libcamera/camera_manager.cpp @@ -181,10 +181,10 @@ void CameraManager::Private::addCamera(std::shared_ptr camera, MutexLocker locker(mutex_); for (std::shared_ptr c : cameras_) { - if (c->name() == camera->name()) { + if (c->id() == camera->id()) { LOG(Camera, Warning) - << "Registering camera with duplicate name '" - << camera->name() << "'"; + << "Registering camera with duplicate ID '" + << camera->id() << "'"; break; } } @@ -208,7 +208,7 @@ void CameraManager::Private::removeCamera(Camera *camera) return; LOG(Camera, Debug) - << "Unregistering camera '" << camera->name() << "'"; + << "Unregistering camera '" << camera->id() << "'"; auto iter_d = std::find_if(camerasByDevnum_.begin(), camerasByDevnum_.end(), [camera](const std::pair> &p) { @@ -329,8 +329,8 @@ std::vector> CameraManager::cameras() const } /** - * \brief Get a camera based on name - * \param[in] name Name of camera to get + * \brief Get a camera based on ID + * \param[in] id ID of camera to get * * Before calling this function the caller is responsible for ensuring that * the camera manager is running. @@ -339,12 +339,12 @@ std::vector> CameraManager::cameras() const * * \return Shared pointer to Camera object or nullptr if camera not found */ -std::shared_ptr CameraManager::get(const std::string &name) +std::shared_ptr CameraManager::get(const std::string &id) { MutexLocker locker(p_->mutex_); for (std::shared_ptr camera : p_->cameras_) { - if (camera->name() == name) + if (camera->id() == id) return camera; } diff --git a/src/libcamera/framebuffer_allocator.cpp b/src/libcamera/framebuffer_allocator.cpp index 252191ba234c5450..2fbba37a1b0b7254 100644 --- a/src/libcamera/framebuffer_allocator.cpp +++ b/src/libcamera/framebuffer_allocator.cpp @@ -95,7 +95,7 @@ int FrameBufferAllocator::allocate(Stream *stream) int ret = camera_->exportFrameBuffers(stream, &buffers_[stream]); if (ret == -EINVAL) LOG(Allocator, Error) - << "Stream is not part of " << camera_->name() + << "Stream is not part of " << camera_->id() << " active configuration"; return ret; } diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index c300f570d727e03e..25f890947b660ecc 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -629,7 +629,7 @@ int PipelineHandlerIPU3::start(Camera *camera) error: freeBuffers(camera); - LOG(IPU3, Error) << "Failed to start camera " << camera->name(); + LOG(IPU3, Error) << "Failed to start camera " << camera->id(); return ret; } @@ -642,8 +642,7 @@ void PipelineHandlerIPU3::stop(Camera *camera) ret |= data->imgu_->stop(); ret |= data->cio2_.stop(); if (ret) - LOG(IPU3, Warning) << "Failed to stop camera " - << camera->name(); + LOG(IPU3, Warning) << "Failed to stop camera " << camera->id(); freeBuffers(camera); } diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index c55d7325cd44d6cb..eeaf335cbcd2f93f 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -643,7 +643,7 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) if (ret) return ret; - LOG(RPI, Info) << "Sensor: " << camera->name() + LOG(RPI, Info) << "Sensor: " << camera->id() << " - Selected mode: " << sensorFormat.toString(); /* @@ -793,7 +793,7 @@ int PipelineHandlerRPi::start(Camera *camera) ret = data->ipa_->start(); if (ret) { LOG(RPI, Error) - << "Failed to start IPA for " << camera->name(); + << "Failed to start IPA for " << camera->id(); stop(camera); return ret; } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 94561062c2b9d4fc..b7609cbc8f363135 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -798,7 +798,7 @@ int PipelineHandlerRkISP1::start(Camera *camera) if (ret) { freeBuffers(camera); LOG(RkISP1, Error) - << "Failed to start IPA " << camera->name(); + << "Failed to start IPA " << camera->id(); return ret; } @@ -809,7 +809,7 @@ int PipelineHandlerRkISP1::start(Camera *camera) data->ipa_->stop(); freeBuffers(camera); LOG(RkISP1, Error) - << "Failed to start parameters " << camera->name(); + << "Failed to start parameters " << camera->id(); return ret; } @@ -819,7 +819,7 @@ int PipelineHandlerRkISP1::start(Camera *camera) data->ipa_->stop(); freeBuffers(camera); LOG(RkISP1, Error) - << "Failed to start statistics " << camera->name(); + << "Failed to start statistics " << camera->id(); return ret; } @@ -831,7 +831,7 @@ int PipelineHandlerRkISP1::start(Camera *camera) freeBuffers(camera); LOG(RkISP1, Error) - << "Failed to start camera " << camera->name(); + << "Failed to start camera " << camera->id(); } activeCamera_ = camera; @@ -870,17 +870,17 @@ void PipelineHandlerRkISP1::stop(Camera *camera) ret = video_->streamOff(); if (ret) LOG(RkISP1, Warning) - << "Failed to stop camera " << camera->name(); + << "Failed to stop camera " << camera->id(); ret = stat_->streamOff(); if (ret) LOG(RkISP1, Warning) - << "Failed to stop statistics " << camera->name(); + << "Failed to stop statistics " << camera->id(); ret = param_->streamOff(); if (ret) LOG(RkISP1, Warning) - << "Failed to stop parameters " << camera->name(); + << "Failed to stop parameters " << camera->id(); data->ipa_->stop(); diff --git a/src/qcam/dng_writer.cpp b/src/qcam/dng_writer.cpp index 8fb9681c2b4fb5e8..65fbd409cfe72bf4 100644 --- a/src/qcam/dng_writer.cpp +++ b/src/qcam/dng_writer.cpp @@ -386,8 +386,8 @@ int DNGWriter::write(const char *filename, const Camera *camera, TIFFSetField(tif, TIFFTAG_DNGBACKWARDVERSION, version); TIFFSetField(tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); TIFFSetField(tif, TIFFTAG_MAKE, "libcamera"); - TIFFSetField(tif, TIFFTAG_MODEL, camera->name().c_str()); - TIFFSetField(tif, TIFFTAG_UNIQUECAMERAMODEL, camera->name().c_str()); + TIFFSetField(tif, TIFFTAG_MODEL, camera->id().c_str()); + TIFFSetField(tif, TIFFTAG_UNIQUECAMERAMODEL, camera->id().c_str()); TIFFSetField(tif, TIFFTAG_SOFTWARE, "qcam"); TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 13a4fefe89ae7525..526e50f48fd36577 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -169,7 +169,7 @@ int MainWindow::createToolbars() this, &MainWindow::switchCamera); for (const std::shared_ptr &cam : cm_->cameras()) - cameraCombo_->addItem(QString::fromStdString(cam->name())); + cameraCombo_->addItem(QString::fromStdString(cam->id())); toolbar_->addWidget(cameraCombo_); @@ -241,11 +241,11 @@ void MainWindow::switchCamera(int index) const std::shared_ptr &cam = cameras[index]; if (cam->acquire()) { - qInfo() << "Failed to acquire camera" << cam->name().c_str(); + qInfo() << "Failed to acquire camera" << cam->id().c_str(); return; } - qInfo() << "Switching to camera" << cam->name().c_str(); + qInfo() << "Switching to camera" << cam->id().c_str(); /* * Stop the capture session, release the current camera, replace it with @@ -266,11 +266,11 @@ std::string MainWindow::chooseCamera() /* If only one camera is available, use it automatically. */ if (cm_->cameras().size() == 1) - return cm_->cameras()[0]->name(); + return cm_->cameras()[0]->id(); /* Present a dialog box to pick a camera. */ for (const std::shared_ptr &cam : cm_->cameras()) - cameras.append(QString::fromStdString(cam->name())); + cameras.append(QString::fromStdString(cam->id())); QString name = QInputDialog::getItem(this, "Select Camera", "Camera:", cameras, 0, @@ -582,7 +582,7 @@ void MainWindow::processHotplug(HotplugEvent *e) HotplugEvent::PlugEvent event = e->hotplugEvent(); if (event == HotplugEvent::HotPlug) { - cameraCombo_->addItem(QString::fromStdString(camera->name())); + cameraCombo_->addItem(QString::fromStdString(camera->id())); } else if (event == HotplugEvent::HotUnplug) { /* Check if the currently-streaming camera is removed. */ if (camera == camera_.get()) { @@ -592,14 +592,14 @@ void MainWindow::processHotplug(HotplugEvent *e) cameraCombo_->setCurrentIndex(0); } - int camIndex = cameraCombo_->findText(QString::fromStdString(camera->name())); + int camIndex = cameraCombo_->findText(QString::fromStdString(camera->id())); cameraCombo_->removeItem(camIndex); } } void MainWindow::addCamera(std::shared_ptr camera) { - qInfo() << "Adding new camera:" << camera->name().c_str(); + qInfo() << "Adding new camera:" << camera->id().c_str(); QCoreApplication::postEvent(this, new HotplugEvent(std::move(camera), HotplugEvent::HotPlug)); @@ -607,7 +607,7 @@ void MainWindow::addCamera(std::shared_ptr camera) void MainWindow::removeCamera(std::shared_ptr camera) { - qInfo() << "Removing camera:" << camera->name().c_str(); + qInfo() << "Removing camera:" << camera->id().c_str(); QCoreApplication::postEvent(this, new HotplugEvent(std::move(camera), HotplugEvent::HotUnplug)); diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp index 50ab7e66cdc02fb1..63affaeec1b3af11 100644 --- a/src/v4l2/v4l2_camera_proxy.cpp +++ b/src/v4l2/v4l2_camera_proxy.cpp @@ -189,7 +189,7 @@ void V4L2CameraProxy::querycap(std::shared_ptr camera) utils::strlcpy(reinterpret_cast(capabilities_.driver), driver.c_str(), sizeof(capabilities_.driver)); - utils::strlcpy(reinterpret_cast(capabilities_.card), camera->name().c_str(), + utils::strlcpy(reinterpret_cast(capabilities_.card), camera->id().c_str(), sizeof(capabilities_.card)); utils::strlcpy(reinterpret_cast(capabilities_.bus_info), bus_info.c_str(), sizeof(capabilities_.bus_info)); diff --git a/test/pipeline/ipu3/ipu3_pipeline_test.cpp b/test/pipeline/ipu3/ipu3_pipeline_test.cpp index 34998f8f6d04473f..9e647af5fdf8ee7f 100644 --- a/test/pipeline/ipu3/ipu3_pipeline_test.cpp +++ b/test/pipeline/ipu3/ipu3_pipeline_test.cpp @@ -106,7 +106,7 @@ int IPU3PipelineTest::run() { auto cameras = cameraManager_->cameras(); for (const std::shared_ptr &cam : cameras) - cout << "Found camera '" << cam->name() << "'" << endl; + cout << "Found camera '" << cam->id() << "'" << endl; if (cameras.size() != sensors_) { cerr << cameras.size() << " cameras registered, but " << sensors_ diff --git a/test/pipeline/rkisp1/rkisp1_pipeline_test.cpp b/test/pipeline/rkisp1/rkisp1_pipeline_test.cpp index b6678ce76e9af193..acaf3c33b529d31d 100644 --- a/test/pipeline/rkisp1/rkisp1_pipeline_test.cpp +++ b/test/pipeline/rkisp1/rkisp1_pipeline_test.cpp @@ -95,7 +95,7 @@ int RKISP1PipelineTest::run() { auto cameras = cameraManager_->cameras(); for (const std::shared_ptr &cam : cameras) - cout << "Found camera '" << cam->name() << "'" << endl; + cout << "Found camera '" << cam->id() << "'" << endl; if (cameras.size() != sensors_) { cerr << cameras.size() << " cameras registered, but " << sensors_ From patchwork Tue Aug 4 16:13:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9192 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id A62F6BD87A for ; Tue, 4 Aug 2020 16:14:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8502860579; Tue, 4 Aug 2020 18:14:30 +0200 (CEST) Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6D78960579 for ; Tue, 4 Aug 2020 18:14:28 +0200 (CEST) X-Halon-ID: 90c2cf49-d66d-11ea-b48b-0050569116f7 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA id 90c2cf49-d66d-11ea-b48b-0050569116f7; Tue, 04 Aug 2020 18:14:27 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Tue, 4 Aug 2020 18:13:58 +0200 Message-Id: <20200804161358.1628962-10-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> References: <20200804161358.1628962-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 9/9] libcamera: camera_manager: Enforce unique camera IDs X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The camera ID is documented that it should be unique but it's not enforced. Change this by refusing to add cameras to the CameraManager that would create two cameras with the exact same ID. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- * Changes since v5 - Rename 'name' to 'id'. - Make error Fatal. * Changes since v4 - Update string in error message. * Changes since v3 - Update commit message. --- src/libcamera/camera_manager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp index 76543b6aac8df9c4..47d56256abd6d490 100644 --- a/src/libcamera/camera_manager.cpp +++ b/src/libcamera/camera_manager.cpp @@ -182,10 +182,10 @@ void CameraManager::Private::addCamera(std::shared_ptr camera, for (std::shared_ptr c : cameras_) { if (c->id() == camera->id()) { - LOG(Camera, Warning) - << "Registering camera with duplicate ID '" + LOG(Camera, Fatal) + << "Trying to register a camera with a duplicated ID '" << camera->id() << "'"; - break; + return; } }