From patchwork Wed Aug 5 10:48: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: 9208 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 BDBC2BD86F for ; Wed, 5 Aug 2020 10:49:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 809F460595; Wed, 5 Aug 2020 12:49:13 +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 D4BF660492 for ; Wed, 5 Aug 2020 12:49:11 +0200 (CEST) X-Halon-ID: 4b0c393e-d709-11ea-a39b-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 4b0c393e-d709-11ea-a39b-005056917f90; Wed, 05 Aug 2020 12:49:10 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 5 Aug 2020 12:48:52 +0200 Message-Id: <20200805104900.2172763-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> References: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 1/9] libcamera: sysfs: Add helper to lookup sysfs path of a character device 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 helper function to lookup the sysfs path of a character device. Store the function in a new libcamera::sysfs namespace as there is not class to host it. Suggested-by: Laurent Pinchart Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- * Changes since v7 - Rename parameter to deviceNode - Include sstream - Rename LOG category to SysFs - Update documentation - Print errno on failure ` --- include/libcamera/internal/meson.build | 1 + include/libcamera/internal/sysfs.h | 22 +++++++++++ src/libcamera/meson.build | 1 + src/libcamera/sysfs.cpp | 52 ++++++++++++++++++++++++++ 4 files changed, 76 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..247a376ab7e0e8ee --- /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 &deviceNode); + +} /* 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..398df2c2be114908 --- /dev/null +++ b/src/libcamera/sysfs.cpp @@ -0,0 +1,52 @@ +/* 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 + +#include "libcamera/internal/log.h" + +/** + * \file sysfs.h + * \brief Miscellaneous utility functions to access sysfs + */ + +namespace libcamera { + +LOG_DEFINE_CATEGORY(SysFs); + +namespace sysfs { + +/** + * \brief Retrieve the sysfs path for a character device + * \param[in] deviceNode Path to character device node + * \return The sysfs path on success or an empty string on failure + */ +std::string charDevPath(const std::string &deviceNode) +{ + struct stat st; + int ret = stat(deviceNode.c_str(), &st); + if (ret < 0) { + ret = -errno; + LOG(SysFs, Error) + << "Unable to stat '" << deviceNode << "': " + << strerror(-ret); + 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 Wed Aug 5 10:48: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: 9209 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 D0861BD86F for ; Wed, 5 Aug 2020 10:49:16 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A9B3A6055E; Wed, 5 Aug 2020 12:49:16 +0200 (CEST) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8D94F60555 for ; Wed, 5 Aug 2020 12:49:12 +0200 (CEST) X-Halon-ID: 4bd20296-d709-11ea-a39b-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 4bd20296-d709-11ea-a39b-005056917f90; Wed, 05 Aug 2020 12:49:11 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 5 Aug 2020 12:48:53 +0200 Message-Id: <20200805104900.2172763-3-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> References: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 2/9] libcamera: sysfs: Add helper to lookup device firmware node 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" A system's firmware description is recorded differently in sysfs depending if the system uses DT or ACPI. Add a helper to abstract this, allowing users not to care which of the two are used. For DT-based systems, the path is the full name of the DT node that represents the device. For ACPI-based systems, the path is the absolute namespace path to the ACPI object that represents the device. In both cases, the path is guaranteed to be unique and persistent as long as the system firmware is not modified. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- * Changes since v7 - Rename function to firmwareNodePath() - Rename argument to device - Return firmware path instead of passing storage as argument - Update documentation - Keep leading slash for DT-based paths - Use File::exists() --- 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 247a376ab7e0e8ee..bc6c1620b55d43a2 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 &deviceNode); +std::string firmwareNodePath(const std::string &device); + } /* namespace sysfs */ } /* namespace libcamera */ diff --git a/src/libcamera/sysfs.cpp b/src/libcamera/sysfs.cpp index 398df2c2be114908..39fe0c468f5e703a 100644 --- a/src/libcamera/sysfs.cpp +++ b/src/libcamera/sysfs.cpp @@ -7,10 +7,12 @@ #include "libcamera/internal/sysfs.h" +#include #include #include #include +#include "libcamera/internal/file.h" #include "libcamera/internal/log.h" /** @@ -47,6 +49,61 @@ std::string charDevPath(const std::string &deviceNode) return dev.str(); } +/** + * \brief Retrieve the path of the firmware node for a device + * \param[in] device Path in sysfs to search + * + * Physical devices in a system are described by the system firmware. Depending + * on the type of platform, devices are identified using different naming + * schemes. The Linux kernel abstract those differences with "firmware nodes". + * This function retrieves the firmware node path corresponding to the + * \a device. + * + * For DT-based systems, the path is the full name of the DT node that + * represents the device. For ACPI-based systems, the path is the absolute + * namespace path to the ACPI object that represents the device. In both cases, + * the path is guaranteed to be unique and persistent as long as the system + * firmware is not modified. + * + * \return The firmware node path on success or an empty string on failure + */ +std::string firmwareNodePath(const std::string &device) +{ + std::string fwPath, node; + + /* Lookup for DT-based systems */ + node = device + "/of_node"; + if (File::exists(node)) { + char *ofPath = realpath(node.c_str(), nullptr); + if (!ofPath) + return {}; + + fwPath = ofPath; + free(ofPath); + + static const std::string dropStr = "/sys/firmware/devicetree"; + if (fwPath.find(dropStr) == 0) + fwPath.erase(0, dropStr.length()); + + return fwPath; + } + + /* Lookup for ACPI-based systems */ + node = device + "/firmware_node/path"; + if (File::exists(node)) { + std::ifstream file(node); + if (!file.is_open()) + return {}; + + std::getline(file, fwPath); + file.close(); + + return fwPath; + } + + return {}; +} + } /* namespace sysfs */ } /* namespace libcamera */ From patchwork Wed Aug 5 10:48: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: 9210 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 228A1BD87B for ; Wed, 5 Aug 2020 10:49:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CFDE4605A8; Wed, 5 Aug 2020 12:49:16 +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 555A560555 for ; Wed, 5 Aug 2020 12:49:13 +0200 (CEST) X-Halon-ID: 4c3c6404-d709-11ea-a39b-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 4c3c6404-d709-11ea-a39b-005056917f90; Wed, 05 Aug 2020 12:49:12 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 5 Aug 2020 12:48:54 +0200 Message-Id: <20200805104900.2172763-4-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> References: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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 v7 - Expand comment - Update error message * 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 | 31 ++++++++++++++++++++++++ 2 files changed, 32 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..65830d41f3cb6e9d 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,34 @@ 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. + * + * It includes the sysfs mount point prefix + * + * \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 device 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 Wed Aug 5 10:48: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: 9211 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 A73D7BD86F for ; Wed, 5 Aug 2020 10:49:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EED45605AB; Wed, 5 Aug 2020 12:49:16 +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 22E9C60555 for ; Wed, 5 Aug 2020 12:49:14 +0200 (CEST) X-Halon-ID: 4cbdb497-d709-11ea-a39b-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 4cbdb497-d709-11ea-a39b-005056917f90; Wed, 05 Aug 2020 12:49:13 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 5 Aug 2020 12:48:55 +0200 Message-Id: <20200805104900.2172763-5-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> References: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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: Jacopo Mondi Reviewed-by: Laurent Pinchart --- * Changes sinve v7 - Use device path stripped of /sys/devices/ prefix instead of modalias for virtual sensors. * 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 | 37 ++++++++++++++++++++++ 2 files changed, 40 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..695c4ad0028d5c4c 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,33 @@ std::string CameraSensor::logPrefix() const return "'" + entity_->name() + "'"; } +int CameraSensor::generateId() +{ + const std::string devPath = subdev_->devicePath(); + + /* Try to get ID from firmware description. */ + id_ = sysfs::firmwareNodePath(devPath); + if (!id_.empty()) + return 0; + + /* + * Virtual sensors not described in firmware + * + * Verify it's a platform device and construct ID from the deive path + * and model of sensor. + */ + if (devPath.rfind("/sys/devices/platform/", 0) == 0) { + id_ = devPath + " " + model(); + + static const std::string dropStr = "/sys/devices/"; + if (id_.find(dropStr) == 0) + id_.erase(0, dropStr.length()); + + return 0; + } + + LOG(CameraSensor, Error) << "Can't generate sensor ID"; + return -EINVAL; +} + } /* namespace libcamera */ From patchwork Wed Aug 5 10:48: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: 9212 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 025B8BD87B for ; Wed, 5 Aug 2020 10:49:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2158E605AE; Wed, 5 Aug 2020 12:49:17 +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 EC39C6055E for ; Wed, 5 Aug 2020 12:49:15 +0200 (CEST) X-Halon-ID: 4d3302b5-d709-11ea-a39b-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 4d3302b5-d709-11ea-a39b-005056917f90; Wed, 05 Aug 2020 12:49:15 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 5 Aug 2020 12:48:56 +0200 Message-Id: <20200805104900.2172763-6-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> References: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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 695c4ad0028d5c4c..2c2db051f8e264c7 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 Wed Aug 5 10:48: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: 9213 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 8941FBD86F for ; Wed, 5 Aug 2020 10:49:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 663E260492; Wed, 5 Aug 2020 12:49:19 +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 201AD6059F for ; Wed, 5 Aug 2020 12:49:17 +0200 (CEST) X-Halon-ID: 4e4eaa6c-d709-11ea-a39b-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 4e4eaa6c-d709-11ea-a39b-005056917f90; Wed, 05 Aug 2020 12:49:16 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 5 Aug 2020 12:48:57 +0200 Message-Id: <20200805104900.2172763-7-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> References: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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@36 * ACPI based systems \_SB_.PCI0.I2C2.CAM0 \_SB_.PCI0.I2C4.CAM1 * VIMC platform/vimc.0 Sensor B Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 9 ++++----- 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, 18 insertions(+), 18 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index c1f9fdf1013c7ec0..cfee178aa1bf57c2 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -805,16 +805,15 @@ 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 cameraId = cio2->sensor()->id(); + std::shared_ptr camera = + Camera::create(this, cameraId, streams); registerCamera(std::move(camera), std::move(data)); LOG(IPU3, Info) << "Registered Camera[" << numCameras << "] \"" - << cameraName << "\"" + << cameraId << "\"" << " connected to CSI-2 receiver " << id; numCameras++; 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..46e03746213912aa 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.0 Sensor B") { } diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp index f6b2f348bda52752..ea84daeef196e349 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.0 Sensor B") { } diff --git a/test/camera/configuration_default.cpp b/test/camera/configuration_default.cpp index 31c908d2449eafe7..cdd6cb97e5ae0732 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.0 Sensor B") { } diff --git a/test/camera/configuration_set.cpp b/test/camera/configuration_set.cpp index b4b5968115e81f59..30f19ba908d6a12e 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.0 Sensor B") { } diff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp index 325b4674bcc958d8..0bda6fe4b0b232fc 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.0 Sensor B") { } diff --git a/test/controls/control_info_map.cpp b/test/controls/control_info_map.cpp index e4305f132db7952f..db95945a15809107 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.0 Sensor B") { } diff --git a/test/controls/control_list.cpp b/test/controls/control_list.cpp index 5c8485b5dcc31499..b5a49dc1700021f8 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.0 Sensor B") { } diff --git a/test/serialization/serialization_test.h b/test/serialization/serialization_test.h index fe77221ef5d07478..f51ae546d890ff27 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.0 Sensor B") { } From patchwork Wed Aug 5 10:48: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: 9214 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 C0874BD87B for ; Wed, 5 Aug 2020 10:49:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 847C16059B; Wed, 5 Aug 2020 12:49:19 +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 DF4D160564 for ; Wed, 5 Aug 2020 12:49:17 +0200 (CEST) X-Halon-ID: 4efe6d72-d709-11ea-a39b-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 4efe6d72-d709-11ea-a39b-005056917f90; Wed, 05 Aug 2020 12:49:17 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 5 Aug 2020 12:48:58 +0200 Message-Id: <20200805104900.2172763-8-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> References: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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.2:1.0-0ac8:3420 Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- * Changes since v7 - Rename function to generateId() - Improve logic to generate deviceId - Update format description of USB ID - Fetch controllerId without using realpath() - Order the generation of the different parts of the ID to match the order in the ID string :-) * Changes since v5 - New algorithm to generate IDs. * Changes since v3 - Switch argument to generateName() to UVCCameraData pointer. --- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 75 +++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 93e3dc17e3a7105e..9f66844e40cb3cd3 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,69 @@ int PipelineHandlerUVC::queueRequestDevice(Camera *camera, Request *request) return 0; } +std::string PipelineHandlerUVC::generateId(const UVCCameraData *data) +{ + const std::string path = data->video_->devicePath(); + + /* Create a controller ID from first device described in firmware. */ + std::string controllerId; + std::string searchPath = path; + while (true) { + std::string::size_type pos = searchPath.rfind('/'); + if (pos <= 1) { + LOG(UVC, Error) << "Can not find controller ID"; + return {}; + } + + searchPath = searchPath.substr(0, pos); + + controllerId = sysfs::firmwareNodePath(searchPath); + if (!controllerId.empty()) + break; + } + + /* + * Create a USB ID from the device path which has the known format: + * + * path = 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); + + /* 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(); + + if (!deviceId.empty()) + deviceId += ":"; + + deviceId += value; + } + + return controllerId + "-" + usbId + "-" + deviceId; +} + bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) { MediaDevice *media; @@ -405,8 +472,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 Wed Aug 5 10:48:59 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: 9215 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 C83FEBD86F for ; Wed, 5 Aug 2020 10:49:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A1B9D605A8; Wed, 5 Aug 2020 12:49:21 +0200 (CEST) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C3B3D6039D for ; Wed, 5 Aug 2020 12:49:19 +0200 (CEST) X-Halon-ID: 4f74efda-d709-11ea-a39b-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 4f74efda-d709-11ea-a39b-005056917f90; Wed, 05 Aug 2020 12:49:17 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 5 Aug 2020 12:48:59 +0200 Message-Id: <20200805104900.2172763-9-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> References: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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 --- * Changes since v7 - Update two missed name -> id conversions - Expand documentation for ID, thanks Laurent! - Add todo in DNG writer to not forget to use real model information when it becomes available. --- include/libcamera/camera.h | 6 +-- src/android/camera_device.cpp | 4 +- src/cam/main.cpp | 10 ++-- src/gstreamer/gstlibcameraprovider.cpp | 4 +- src/gstreamer/gstlibcamerasrc.cpp | 6 +-- src/libcamera/camera.cpp | 51 +++++++++++++------ 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 | 5 +- src/qcam/main_window.cpp | 26 +++++----- 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, 91 insertions(+), 70 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..dfd0e68aa631b5c9 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) @@ -173,7 +173,7 @@ int CamApp::parseOptions(int argc, char *argv[]) OptionsParser parser; parser.addOption(OptCamera, OptionString, - "Specify which camera to operate on, by name or by index", "camera", + "Specify which camera to operate on, by id or by index", "camera", ArgumentRequired, "camera"); parser.addOption(OptCapture, OptionInteger, "Capture until interrupted by user or until frames captured", @@ -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..1e9ca1ebdfcbca7c 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,21 @@ 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 + * matching the constraints described by Camera::id(). Parameters that are + * allocated dynamically at system startup, such as bus numbers that may be + * enumerated differently, aretherefore not suitable to use in the ID. + * + * Pipeline handlers that use a CameraSensor may use the CameraSensor::id() to + * generate an ID that 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 +474,34 @@ 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 + * + * The camera ID is a free-form string that identifies a camera in the system. + * IDs are guaranteed to be unique and stable: the same camera, when connected + * to the system in the same way (e.g. in the same USB port), will have the same + * ID across both unplug/replug and system reboots. + * + * Applications may store the camera ID and use it later to acquire the same + * camera. They shall treat the ID as an opaque identifier, without interpreting + * its value. + * + * Camera IDs may change when the system hardware or firmware is modified, for + * instance when replacing a PCI USB controller or moving it to another PCI + * slot, or updating the ACPI tables or Device Tree. + * * \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 +527,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 +551,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 cfee178aa1bf57c2..d931ed333b4a1df6 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..b5b81f0637b545af 100644 --- a/src/qcam/dng_writer.cpp +++ b/src/qcam/dng_writer.cpp @@ -386,8 +386,9 @@ 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()); + /* \todo Report a real model string instead of id. */ + 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..750353726cb16bc2 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,19 +266,19 @@ 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, - false, &result); + QString id = QInputDialog::getItem(this, "Select Camera", + "Camera:", cameras, 0, + false, &result); if (!result) return std::string(); - return name.toStdString(); + return id.toStdString(); } int MainWindow::openCamera() @@ -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 Wed Aug 5 10:49:00 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: 9216 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 2A7EABD87B for ; Wed, 5 Aug 2020 10:49:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 06E7A605B6; Wed, 5 Aug 2020 12:49:22 +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 B11396039D for ; Wed, 5 Aug 2020 12:49:20 +0200 (CEST) X-Halon-ID: 5095d8f5-d709-11ea-a39b-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id 5095d8f5-d709-11ea-a39b-005056917f90; Wed, 05 Aug 2020 12:49:20 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 5 Aug 2020 12:49:00 +0200 Message-Id: <20200805104900.2172763-10-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> References: <20200805104900.2172763-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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; } }