From patchwork Sat Jul 18 13:23:18 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: 8852 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 BFB75C2E67 for ; Sat, 18 Jul 2020 13:23:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CD7B160732; Sat, 18 Jul 2020 15:23:36 +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 B64B260589 for ; Sat, 18 Jul 2020 15:23:33 +0200 (CEST) X-Halon-ID: dfb350e3-c8f9-11ea-933e-005056917a89 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (p4fca2eca.dip0.t-ipconnect.de [79.202.46.202]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id dfb350e3-c8f9-11ea-933e-005056917a89; Sat, 18 Jul 2020 15:23:31 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Sat, 18 Jul 2020 15:23:18 +0200 Message-Id: <20200718132324.867815-4-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200718132324.867815-1-niklas.soderlund@ragnatech.se> References: <20200718132324.867815-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/9] libcamera: camera: Add camera 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 ID when creating a camera. The ID is a free form string that must be unique for the camera in the system. The ID shall also be persistent between reboots. All but the UVC pipeline is modified to use the ID of the sensor of each camera. The ID of the sensor guarantees the properties required of the camera ID. The UVC pipeline does not have a sensor so instead creates a unique and persistent ID from the video device path which includes the USB bus information and thus satisfy the camera ID requirements. Future changes will make use of and enforce the uniqueness of camera IDs. Signed-off-by: Niklas Söderlund --- include/libcamera/camera.h | 6 ++-- src/libcamera/camera.cpp | 34 +++++++++++++------ src/libcamera/pipeline/ipu3/ipu3.cpp | 1 + .../pipeline/raspberrypi/raspberrypi.cpp | 5 ++- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 3 +- src/libcamera/pipeline/simple/simple.cpp | 3 +- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 7 +++- src/libcamera/pipeline/vimc/vimc.cpp | 3 +- 8 files changed, 45 insertions(+), 17 deletions(-) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 4d1a4a9f52ec0fac..132225a37dcd1ef4 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -70,12 +70,14 @@ class Camera final : public std::enable_shared_from_this { public: static std::shared_ptr create(PipelineHandler *pipe, + const std::string &id, const std::string &name, const std::set &streams); Camera(const Camera &) = delete; Camera &operator=(const Camera &) = delete; + const std::string &id() const; const std::string &name() const; Signal bufferCompleted; @@ -99,8 +101,8 @@ public: int stop(); private: - Camera(PipelineHandler *pipe, const std::string &name, - const std::set &streams); + Camera(PipelineHandler *pipe, const std::string &id, + const std::string &name, const std::set &streams); ~Camera(); class Private; diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 69a1b4428e3f4eca..638d15e0da5e1ca9 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -265,8 +265,8 @@ public: CameraRunning, }; - Private(PipelineHandler *pipe, const std::string &name, - const std::set &streams); + Private(PipelineHandler *pipe, const std::string &id, + const std::string &name, const std::set &streams); ~Private(); int isAccessAllowed(State state, bool allowDisconnected = false) const; @@ -277,6 +277,7 @@ public: void setState(State state); std::shared_ptr pipe_; + std::string id_; std::string name_; std::set streams_; std::set activeStreams_; @@ -286,10 +287,11 @@ private: std::atomic state_; }; -Camera::Private::Private(PipelineHandler *pipe, const std::string &name, +Camera::Private::Private(PipelineHandler *pipe, const std::string &id, + const std::string &name, const std::set &streams) - : pipe_(pipe->shared_from_this()), name_(name), streams_(streams), - disconnected_(false), state_(CameraAvailable) + : pipe_(pipe->shared_from_this()), id_(id), name_(name), + streams_(streams), disconnected_(false), state_(CameraAvailable) { } @@ -450,14 +452,16 @@ void Camera::Private::setState(State state) /** * \brief Create a camera instance * \param[in] pipe The pipeline handler responsible for the camera device + * \param[in] id The ID of the camera device * \param[in] name The name 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 unicity of the camera ID. * * \return A shared pointer to the newly created camera object */ std::shared_ptr Camera::create(PipelineHandler *pipe, + const std::string &id, const std::string &name, const std::set &streams) { @@ -468,7 +472,7 @@ std::shared_ptr Camera::create(PipelineHandler *pipe, } }; - Camera *camera = new Camera(pipe, name, streams); + Camera *camera = new Camera(pipe, id, name, streams); return std::shared_ptr(camera, Deleter()); } @@ -483,6 +487,16 @@ const std::string &Camera::name() const return p_->name_; } +/** + * \brief Retrieve the camera ID + * \context This function is \threadsafe. + * \return Unique ID of the camera device + */ +const std::string &Camera::id() const +{ + return p_->id_; +} + /** * \var Camera::bufferCompleted * \brief Signal emitted when a buffer for a request queued to the camera has @@ -506,9 +520,9 @@ const std::string &Camera::name() const * application API calls by returning errors immediately. */ -Camera::Camera(PipelineHandler *pipe, const std::string &name, - const std::set &streams) - : p_(new Private(pipe, name, streams)) +Camera::Camera(PipelineHandler *pipe, const std::string &id, + const std::string &name, const std::set &streams) + : p_(new Private(pipe, id, name, streams)) { } diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index eb00eecfd10a89e4..09bab78b999b8b52 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -815,6 +815,7 @@ int PipelineHandlerIPU3::registerCameras() /* Create and register the Camera instance. */ std::string cameraName = cio2->sensor()->entity()->name(); std::shared_ptr camera = Camera::create(this, + cio2->sensor()->id(), cameraName, streams); diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index bf1c77144f855df9..487dc819daa1d0ec 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -973,7 +973,10 @@ 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(), + data->sensor_->model(), + 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..6f3699fe1a53eeaf 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -971,7 +971,8 @@ 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(), sensor->name(), + 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 28d367883323d855..3c27cc28f672e020 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -800,7 +800,8 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) continue; std::shared_ptr camera = - Camera::create(this, data->sensor_->entity()->name(), + Camera::create(this, data->sensor_->id(), + data->sensor_->entity()->name(), data->streams()); registerCamera(std::move(camera), std::move(data)); } diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 47f383d1551d5193..4484b70c6ec5f0ca 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -406,8 +406,13 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) return false; /* Create and register the camera. */ + std::string id = data->video_->devicePath(); + const std::string dropStr = "/sys/devices/"; + if (id.find(dropStr) == 0) + id.erase(0, dropStr.length()); + std::set streams{ &data->stream_ }; - std::shared_ptr camera = Camera::create(this, media->model(), streams); + std::shared_ptr camera = Camera::create(this, id, media->model(), streams); registerCamera(std::move(camera), std::move(data)); /* Enable hot-unplug notifications. */ diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 4f461b928514022d..38656d28b357dd1b 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -434,7 +434,8 @@ bool PipelineHandlerVimc::match(DeviceEnumerator *enumerator) /* 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(), + name, streams); registerCamera(std::move(camera), std::move(data)); return true;