From patchwork Wed Jul 29 11:50: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: 9072 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 885B6BD86F for ; Wed, 29 Jul 2020 11:51:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 652F561978; Wed, 29 Jul 2020 13:51:05 +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 39264616FF for ; Wed, 29 Jul 2020 13:51:03 +0200 (CEST) X-Halon-ID: c60f339f-d191-11ea-8fb8-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p4fca2eca.dip0.t-ipconnect.de [79.202.46.202]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id c60f339f-d191-11ea-8fb8-005056917f90; Wed, 29 Jul 2020 13:51:01 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 29 Jul 2020 13:50:51 +0200 Message-Id: <20200729115055.3840110-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200729115055.3840110-1-niklas.soderlund@ragnatech.se> References: <20200729115055.3840110-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 1/5] 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: Jacopo Mondi Reviewed-by: Kieran Bingham --- * Changes since v3 - s/the device path/the device path in sysfs/ --- include/libcamera/internal/v4l2_device.h | 1 + src/libcamera/v4l2_device.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 25 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..205797b568a869ae 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -350,6 +351,29 @@ int V4L2Device::setControls(ControlList *ctrls) return ret; } +/** + * \brief Retrieve the device path in sysfs + * + * The device path in sysfs describes the device backing the V4L2 device. + * + * \todo When switching to C++17 use std::filesystem:: in the implementation. + * \todo Query udev for this information as the path created for vdev here + * might not be correct. + * + * \return The device path in sysfs + */ +std::string V4L2Device::devicePath() const +{ + std::string vdev = basename(deviceNode_.c_str()); + std::string sysfs = "/sys/class/video4linux/" + vdev + "/device"; + + char path[PATH_MAX]; + if (!realpath(sysfs.c_str(), path)) + LOG(V4L2, Fatal) << "Can not resolve path for " << deviceNode_; + + return path; +} + /** * \brief Perform an IOCTL system call on the device node * \param[in] request The IOCTL request code From patchwork Wed Jul 29 11:50: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: 9073 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 930A9BD86F for ; Wed, 29 Jul 2020 11:51:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 84A6561981; Wed, 29 Jul 2020 13:51:05 +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 CDD226039D for ; Wed, 29 Jul 2020 13:51:03 +0200 (CEST) X-Halon-ID: c6f8c93d-d191-11ea-8fb8-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p4fca2eca.dip0.t-ipconnect.de [79.202.46.202]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id c6f8c93d-d191-11ea-8fb8-005056917f90; Wed, 29 Jul 2020 13:51:03 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 29 Jul 2020 13:50:52 +0200 Message-Id: <20200729115055.3840110-3-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200729115055.3840110-1-niklas.soderlund@ragnatech.se> References: <20200729115055.3840110-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 2/5] 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" Generate a constant and unique string ID for the sensor. The ID is generated from information from the firmware description of the camera image sensor. The ID is unique and persistent across reboots of the system. For OF based systems the ID is the full path of the sensors 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. A special case is needed to deal with the VIMC pipeline that implements a virtual pipeline that is not backed by any hardware device and is therefore not described in the device firmware. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- * 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 | 4 + src/libcamera/camera_sensor.cpp | 94 ++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h index 06c8292ca30129de..e0d2d9f63b47c2fe 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_; } @@ -67,11 +68,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..6dc616945dad5ef1 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -9,10 +9,12 @@ #include #include +#include #include #include #include #include +#include #include @@ -204,6 +206,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; @@ -283,6 +290,26 @@ int CameraSensor::init() * \return The sensor model name */ +/** + * \fn CameraSensor::id() + * \brief Retrieve the sensor ID + * + * The sensor ID is a free-formed string that uniquely identifies the sensor in + * the system. The ID is persistent between different instances of libcamera and + * between resets of the system. + * + * For OF based systems the ID is the full path of the sensors 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. + * + * A special case is needed to deal with the VIMC pipeline that implements a + * virtual pipeline that is not backed by any hardware device and is therefore + * not described in the device firmware. + * + * \return The sensor ID + */ + /** * \fn CameraSensor::entity() * \brief Retrieve the sensor media entity @@ -541,4 +568,71 @@ std::string CameraSensor::logPrefix() const return "'" + entity_->name() + "'"; } +int CameraSensor::generateID() +{ + std::string path, devPath = subdev_->devicePath(); + struct stat statbuf; + + /* Try to generate ID from OF device tree path. */ + path = devPath + "/of_node"; + if (stat(path.c_str(), &statbuf) == 0) { + char ofPath[PATH_MAX]; + + if (!realpath(path.c_str(), ofPath)) { + LOG(CameraSensor, Error) << "Failed to read sensor OF based ID"; + return -EINVAL; + } + + id_ = ofPath; + const std::string dropStr = "/sys/firmware/devicetree/"; + if (id_.find(dropStr) == 0) + id_.erase(0, dropStr.length()); + + return 0; + } + + /* Try to generate ID from ACPI path. */ + path = devPath + "/firmware_node/path"; + if (stat(path.c_str(), &statbuf) == 0) { + std::ifstream file(path.c_str()); + + if (!file.is_open()) { + LOG(CameraSensor, Error) << "Failed to read sensor ACPI based ID"; + return -EINVAL; + } + + std::getline(file, id_); + file.close(); + + return 0; + } + + /* + * VIMC is a virtual video pipeline not backed hardware and has no OF + * or ACPI firmware nodes. Handle this pipeline as a special case and + * generate IDs based on the sensor model. + */ + path = devPath + "/modalias"; + if (stat(path.c_str(), &statbuf) == 0) { + std::ifstream file(path.c_str()); + + if (!file.is_open()) { + LOG(CameraSensor, Error) << "Failed to read sensor ACPI based ID"; + return -EINVAL; + } + + std::string modalias; + std::getline(file, modalias); + file.close(); + + if (modalias == "platform:vimc") { + id_ = "VIMC " + model(); + return 0; + } + } + + LOG(CameraSensor, Error) << "Unknown sensor device type, can not generate ID"; + return -EINVAL; +} + } /* namespace libcamera */ From patchwork Wed Jul 29 11:50: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: 9074 X-Patchwork-Delegate: niklas.soderlund@ragnatech.se 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 13708BD86F for ; Wed, 29 Jul 2020 11:51:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A398061A0A; Wed, 29 Jul 2020 13:51:05 +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 933FB6039D for ; Wed, 29 Jul 2020 13:51:04 +0200 (CEST) X-Halon-ID: c7702ddd-d191-11ea-8fb8-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p4fca2eca.dip0.t-ipconnect.de [79.202.46.202]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id c7702ddd-d191-11ea-8fb8-005056917f90; Wed, 29 Jul 2020 13:51:03 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 29 Jul 2020 13:50:53 +0200 Message-Id: <20200729115055.3840110-4-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200729115055.3840110-1-niklas.soderlund@ragnatech.se> References: <20200729115055.3840110-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 3/5] libcamera: camera: Generate camera name from a CameraSensor 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 create() that generates a camera name from information in a CameraSensor. The intention is to help pipeline handlers that already uses CameraSensor to not have to worry about how to generate a unique and persistent name. All pipelines that use a CameraSensor (all but UVC) are updated to make use of this new function. All names of cameras created by these updated pipelines are modified. 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 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 Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- * Changes since v3 - Update commit message. - Do not include property_ids.h. --- include/libcamera/camera.h | 5 +++++ src/libcamera/camera.cpp | 18 ++++++++++++++++++ src/libcamera/pipeline/ipu3/ipu3.cpp | 12 +++++------- .../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 ++-- 7 files changed, 34 insertions(+), 12 deletions(-) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 4d1a4a9f52ec0fac..784510c9a79d44b9 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -19,6 +19,7 @@ namespace libcamera { +class CameraSensor; class FrameBuffer; class FrameBufferAllocator; class PipelineHandler; @@ -73,6 +74,10 @@ public: const std::string &name, const std::set &streams); + static std::shared_ptr create(PipelineHandler *pipe, + const CameraSensor *sensor, + const std::set &streams); + Camera(const Camera &) = delete; Camera &operator=(const Camera &) = delete; diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 69a1b4428e3f4eca..02e2369ef0089465 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -14,6 +14,7 @@ #include #include +#include "libcamera/internal/camera_sensor.h" #include "libcamera/internal/log.h" #include "libcamera/internal/pipeline_handler.h" #include "libcamera/internal/utils.h" @@ -473,6 +474,23 @@ std::shared_ptr Camera::create(PipelineHandler *pipe, return std::shared_ptr(camera, Deleter()); } +/** + * \brief Create a camera instance + * \param[in] pipe The pipeline handler responsible for the camera device + * \param[in] sensor The sensor of the camera device + * \param[in] streams Array of streams the camera provides + * + * Create a camera with name generated from \a sensor. + * + * \return A shared pointer to the newly created camera object + */ +std::shared_ptr Camera::create(PipelineHandler *pipe, + const CameraSensor *sensor, + const std::set &streams) +{ + return Camera::create(pipe, sensor->id(), streams); +} + /** * \brief Retrieve the name of the camera * \context This function is \threadsafe. diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index eb00eecfd10a89e4..72da6ed62a7f0de5 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -813,18 +813,16 @@ 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); - - registerCamera(std::move(camera), std::move(data)); + std::shared_ptr camera = + Camera::create(this, cio2->sensor(), streams); LOG(IPU3, Info) << "Registered Camera[" << numCameras << "] \"" - << cameraName << "\"" + << camera->name() << "\"" << " connected to CSI-2 receiver " << id; + registerCamera(std::move(camera), std::move(data)); + numCameras++; } diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 82a0a4dfd6824fce..a62dd24b1ab76b87 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_, 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..663e45b109aae9eb 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_, 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..1258f81284590060 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_.get(), 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..e1fc087f111b0bc4 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_, streams); registerCamera(std::move(camera), std::move(data)); return true; From patchwork Wed Jul 29 11:50: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: 9075 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 1D09BBD86F for ; Wed, 29 Jul 2020 11:51:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EADFA6185C; Wed, 29 Jul 2020 13:51:08 +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 1EF44616FF for ; Wed, 29 Jul 2020 13:51:05 +0200 (CEST) X-Halon-ID: c7e47ea1-d191-11ea-8fb8-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p4fca2eca.dip0.t-ipconnect.de [79.202.46.202]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id c7e47ea1-d191-11ea-8fb8-005056917f90; Wed, 29 Jul 2020 13:51:04 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 29 Jul 2020 13:50:54 +0200 Message-Id: <20200729115055.3840110-5-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200729115055.3840110-1-niklas.soderlund@ragnatech.se> References: <20200729115055.3840110-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 4/5] 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 vendor and product information that is stored on USB device itself and the USB bus and device numbers where the hardware is plugged in. Before this change example of camera names: Venus USB2.0 Camera: Venus USB2 Logitech Webcam C930e After this change the same cameras are: 0ac8:3420:3:10 046d:0843:3:4 Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- * Changes since v3 - Switch argument to generateName() to UVCCameraData pointer. --- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 35 +++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 93e3dc17e3a7105e..f51529ea519f5aee 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -81,6 +82,8 @@ public: bool match(DeviceEnumerator *enumerator) override; private: + std::string generateName(const UVCCameraData *data); + int processControl(ControlList *controls, unsigned int id, const ControlValue &value); int processControls(UVCCameraData *data, Request *request); @@ -379,6 +382,30 @@ int PipelineHandlerUVC::queueRequestDevice(Camera *camera, Request *request) return 0; } +std::string PipelineHandlerUVC::generateName(const UVCCameraData *data) +{ + + static const std::vector files + = { "idVendor", "idProduct", "busnum", "devnum" }; + std::string path = data->video_->devicePath(); + std::vector values; + std::string value; + + for (const std::string &name : files) { + std::ifstream file(path + "/../" + name); + + if (!file.is_open()) + return ""; + + std::getline(file, value); + file.close(); + + values.push_back(value); + } + + return utils::join(values, ":"); +} + bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) { MediaDevice *media; @@ -405,8 +432,14 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) return false; /* Create and register the camera. */ + std::string name = generateName(data.get()); + if (name.empty()) { + LOG(UVC, Error) << "Failed to generate camera name"; + return false; + } + std::set streams{ &data->stream_ }; - std::shared_ptr camera = Camera::create(this, media->model(), streams); + std::shared_ptr camera = Camera::create(this, name, streams); registerCamera(std::move(camera), std::move(data)); /* Enable hot-unplug notifications. */ From patchwork Wed Jul 29 11:50: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: 9076 X-Patchwork-Delegate: niklas.soderlund@ragnatech.se 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 47C50BD879 for ; Wed, 29 Jul 2020 11:51:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 20AB56196B; Wed, 29 Jul 2020 13:51:09 +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 A4B8461A0E for ; Wed, 29 Jul 2020 13:51:05 +0200 (CEST) X-Halon-ID: c835cdcc-d191-11ea-8fb8-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p4fca2eca.dip0.t-ipconnect.de [79.202.46.202]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id c835cdcc-d191-11ea-8fb8-005056917f90; Wed, 29 Jul 2020 13:51:05 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 29 Jul 2020 13:50:55 +0200 Message-Id: <20200729115055.3840110-6-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200729115055.3840110-1-niklas.soderlund@ragnatech.se> References: <20200729115055.3840110-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 5/5] libcamera: camera_manager: Enforce 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" The camera name have always been documented that it should be unique but it has never been enforced. Change this by refusing to add cameras to the CameraManager that would create two cameras with the exact same name. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- * 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 f60491d2c1a7500f..47e0f3129d346183 100644 --- a/src/libcamera/camera_manager.cpp +++ b/src/libcamera/camera_manager.cpp @@ -178,10 +178,10 @@ void CameraManager::Private::addCamera(std::shared_ptr camera, for (std::shared_ptr c : cameras_) { if (c->name() == camera->name()) { - LOG(Camera, Warning) - << "Registering camera with duplicate name '" + LOG(Camera, Error) + << "Skip registration of a camera with a duplicated name '" << camera->name() << "'"; - break; + return; } }