From patchwork Tue Jan 22 23:29:53 2019 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: 331 Return-Path: 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 1886B60C7D for ; Wed, 23 Jan 2019 00:30:44 +0100 (CET) X-Halon-ID: ba9f5212-1e9d-11e9-874f-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id ba9f5212-1e9d-11e9-874f-005056917f90; Wed, 23 Jan 2019 00:30:40 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 23 Jan 2019 00:29:53 +0100 Message-Id: <20190122232955.31783-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190122232955.31783-1-niklas.soderlund@ragnatech.se> References: <20190122232955.31783-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/3] libcamera: camera: create a association with the responsible pipeline handler X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 22 Jan 2019 23:30:44 -0000 The PipelineHandler which creates a Camera is responsible for serving any operation requested by the user. In order to do so the Camera needs to store a reference to its creator. Signed-off-by: Niklas Söderlund --- include/libcamera/camera.h | 8 ++++++-- src/libcamera/camera.cpp | 15 +++++++++------ src/libcamera/pipeline/ipu3/ipu3.cpp | 3 ++- src/libcamera/pipeline/uvcvideo.cpp | 2 +- src/libcamera/pipeline/vimc.cpp | 10 ++-------- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 2ea1a6883311cf9f..d3bae4cbee1e0cea 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -12,10 +12,13 @@ namespace libcamera { +class PipelineHandler; + class Camera final { public: - static std::shared_ptr create(const std::string &name); + static std::shared_ptr create(const std::string &name, + class PipelineHandler *pipe); Camera(const Camera &) = delete; void operator=(const Camera &) = delete; @@ -23,10 +26,11 @@ public: const std::string &name() const; private: - explicit Camera(const std::string &name); + explicit Camera(const std::string &name, class PipelineHandler *pipe); ~Camera(); std::string name_; + class PipelineHandler *pipe_; }; } /* namespace libcamera */ diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index acf912bee95cbec4..f198eb4978b12239 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -52,17 +52,20 @@ namespace libcamera { /** * \brief Create a camera instance * \param[in] name The name of the camera device + * \param[in] pipe The pipeline handler responsible for the camera device * * The caller is responsible for guaranteeing unicity of the camera name. * * \return A shared pointer to the newly created camera object */ -std::shared_ptr Camera::create(const std::string &name) +std::shared_ptr Camera::create(const std::string &name, + class PipelineHandler *pipe) { struct Allocator : std::allocator { - void construct(void *p, const std::string &name) + void construct(void *p, const std::string &name, + class PipelineHandler *pipe) { - ::new(p) Camera(name); + ::new(p) Camera(name, pipe); } void destroy(Camera *p) { @@ -70,7 +73,7 @@ std::shared_ptr Camera::create(const std::string &name) } }; - return std::allocate_shared(Allocator(), name); + return std::allocate_shared(Allocator(), name, pipe); } /** @@ -83,8 +86,8 @@ const std::string &Camera::name() const return name_; } -Camera::Camera(const std::string &name) - : name_(name) +Camera::Camera(const std::string &name, class PipelineHandler *pipe) + : name_(name), pipe_(pipe) { } diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 8cbc10acfbb571fd..48d028f7e6cd9b4d 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -171,7 +171,8 @@ void PipelineHandlerIPU3::registerCameras(CameraManager *manager) continue; std::string cameraName = sensor->name() + " " + std::to_string(id); - std::shared_ptr camera = Camera::create(cameraName); + std::shared_ptr camera = Camera::create(cameraName, + this); manager->addCamera(std::move(camera)); LOG(IPU3, Info) diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 3ba69da8b77586e3..3651250b683e7810 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -48,7 +48,7 @@ bool PipelineHandlerUVC::match(CameraManager *manager, DeviceEnumerator *enumera dev_->acquire(); - std::shared_ptr camera = Camera::create(dev_->model()); + std::shared_ptr camera = Camera::create(dev_->model(), this); manager->addCamera(std::move(camera)); return true; diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 82b9237a3d7d93e5..81d8319eb88e06d2 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -57,14 +57,8 @@ bool PipeHandlerVimc::match(CameraManager *manager, DeviceEnumerator *enumerator dev_->acquire(); - /* - * NOTE: A more complete Camera implementation could - * be passed the MediaDevice(s) it controls here or - * a reference to the PipelineHandler. Which method - * will be chosen depends on how the Camera - * object is modeled. - */ - std::shared_ptr camera = Camera::create("Dummy VIMC Camera"); + std::shared_ptr camera = Camera::create("Dummy VIMC Camera", + this); manager->addCamera(std::move(camera)); return true; From patchwork Tue Jan 22 23:29:54 2019 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: 332 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2F9C460C81 for ; Wed, 23 Jan 2019 00:30:44 +0100 (CET) X-Halon-ID: bb2411cb-1e9d-11e9-874f-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id bb2411cb-1e9d-11e9-874f-005056917f90; Wed, 23 Jan 2019 00:30:41 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 23 Jan 2019 00:29:54 +0100 Message-Id: <20190122232955.31783-3-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190122232955.31783-1-niklas.soderlund@ragnatech.se> References: <20190122232955.31783-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/3] libcamera: pipelines: keep reference to cameras created X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 22 Jan 2019 23:30:44 -0000 The pipeline handlers needs to keep a reference to the cameras it creates in order to notify it when it's being disconnected. When hot-unplug support is added the pipeline handler would be deleted when the hardware is removed from under it. After the deletion of pipeline handler all the Camera objects created by the pipeline handler might still be around as they might be in use by a application. At this point the pipeline handler should inform the camera that it's disconnected. Signed-off-by: Niklas Söderlund --- src/libcamera/pipeline/ipu3/ipu3.cpp | 7 ++++++- src/libcamera/pipeline/uvcvideo.cpp | 10 +++++++--- src/libcamera/pipeline/vimc.cpp | 11 +++++++---- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 48d028f7e6cd9b4d..19f73011f8b75438 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -32,6 +32,8 @@ private: MediaDevice *cio2_; MediaDevice *imgu_; + std::vector> cameras_; + void registerCameras(CameraManager *manager); }; @@ -42,6 +44,8 @@ PipelineHandlerIPU3::PipelineHandlerIPU3() PipelineHandlerIPU3::~PipelineHandlerIPU3() { + cameras_.clear(); + if (cio2_) cio2_->release(); @@ -173,7 +177,8 @@ void PipelineHandlerIPU3::registerCameras(CameraManager *manager) std::string cameraName = sensor->name() + " " + std::to_string(id); std::shared_ptr camera = Camera::create(cameraName, this); - manager->addCamera(std::move(camera)); + cameras_.push_back(camera); + manager->addCamera(camera); LOG(IPU3, Info) << "Registered Camera[" << numCameras << "] \"" diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 3651250b683e7810..2162824eb571fba7 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -24,15 +24,19 @@ public: private: MediaDevice *dev_; + std::shared_ptr camera_; }; PipelineHandlerUVC::PipelineHandlerUVC() - : dev_(nullptr) + : dev_(nullptr), camera_(nullptr) { } PipelineHandlerUVC::~PipelineHandlerUVC() { + if (camera_) + camera_ = nullptr; + if (dev_) dev_->release(); } @@ -48,8 +52,8 @@ bool PipelineHandlerUVC::match(CameraManager *manager, DeviceEnumerator *enumera dev_->acquire(); - std::shared_ptr camera = Camera::create(dev_->model(), this); - manager->addCamera(std::move(camera)); + camera_ = Camera::create(dev_->model(), this); + manager->addCamera(camera_); return true; } diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 81d8319eb88e06d2..373fc0ee5339f9ae 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -24,15 +24,19 @@ public: private: MediaDevice *dev_; + std::shared_ptr camera_; }; PipeHandlerVimc::PipeHandlerVimc() - : dev_(nullptr) + : dev_(nullptr), camera_(nullptr) { } PipeHandlerVimc::~PipeHandlerVimc() { + if (camera_) + camera_ = nullptr; + if (dev_) dev_->release(); } @@ -57,9 +61,8 @@ bool PipeHandlerVimc::match(CameraManager *manager, DeviceEnumerator *enumerator dev_->acquire(); - std::shared_ptr camera = Camera::create("Dummy VIMC Camera", - this); - manager->addCamera(std::move(camera)); + camera_ = Camera::create("Dummy VIMC Camera", this); + manager->addCamera(camera_); return true; } From patchwork Tue Jan 22 23:29:55 2019 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: 333 Return-Path: Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A625D60C82 for ; Wed, 23 Jan 2019 00:30:45 +0100 (CET) X-Halon-ID: bb9fda7e-1e9d-11e9-874f-005056917f90 Authorized-sender: niklas@soderlund.pp.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id bb9fda7e-1e9d-11e9-874f-005056917f90; Wed, 23 Jan 2019 00:30:41 +0100 (CET) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Wed, 23 Jan 2019 00:29:55 +0100 Message-Id: <20190122232955.31783-4-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190122232955.31783-1-niklas.soderlund@ragnatech.se> References: <20190122232955.31783-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/3] libcamera: camera: add method to disconnect camera X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 22 Jan 2019 23:30:45 -0000 As camera object have the potential to outlive the hardware they represent there is a need to inform the camera it's disconnected from the hardware. At this point it is enough to sever the reference to the pipeline handler which created the camera as that is the only resource the Camera object holds which represents hardware. As we move forward maybe a more elaborate flag is needed to flag that hardware is being removed. Signed-off-by: Niklas Söderlund --- include/libcamera/camera.h | 2 ++ src/libcamera/camera.cpp | 16 ++++++++++++++++ src/libcamera/pipeline/ipu3/ipu3.cpp | 3 +++ src/libcamera/pipeline/uvcvideo.cpp | 4 +++- src/libcamera/pipeline/vimc.cpp | 4 +++- 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index d3bae4cbee1e0cea..b5d4dfe4b1f6a586 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -25,6 +25,8 @@ public: const std::string &name() const; + void disconnect(); + private: explicit Camera(const std::string &name, class PipelineHandler *pipe); ~Camera(); diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index f198eb4978b12239..496fb1021c4fccf0 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -33,6 +33,8 @@ namespace libcamera { +LOG_DECLARE_CATEGORY(Camera) + /** * \class Camera * \brief Camera device @@ -86,6 +88,20 @@ const std::string &Camera::name() const return name_; } +/** + * \brief Disconnect the camera from the hardware + * + * When the underlying PipelineHandler is deleted as a result of the hardware + * being removed or un-pluged the Camera needs to be disconnected. The pipeline + * handler should when it detects that it's being removed notify all cameras it + * have created that they are now longer backed by any hardware. + */ +void Camera::disconnect() +{ + LOG(Camera, Debug) << "Disconnecting camera" << name_; + pipe_ = nullptr; +} + Camera::Camera(const std::string &name, class PipelineHandler *pipe) : name_(name), pipe_(pipe) { diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 19f73011f8b75438..c6106c538f071058 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -44,6 +44,9 @@ PipelineHandlerIPU3::PipelineHandlerIPU3() PipelineHandlerIPU3::~PipelineHandlerIPU3() { + for (const std::shared_ptr &camera : cameras_) + camera->disconnect(); + cameras_.clear(); if (cio2_) diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 2162824eb571fba7..a02f3671d22c5f79 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -34,8 +34,10 @@ PipelineHandlerUVC::PipelineHandlerUVC() PipelineHandlerUVC::~PipelineHandlerUVC() { - if (camera_) + if (camera_) { + camera_->disconnect(); camera_ = nullptr; + } if (dev_) dev_->release(); diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 373fc0ee5339f9ae..d732ac21cae1a84b 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -34,8 +34,10 @@ PipeHandlerVimc::PipeHandlerVimc() PipeHandlerVimc::~PipeHandlerVimc() { - if (camera_) + if (camera_) { + camera_->disconnect(); camera_ = nullptr; + } if (dev_) dev_->release();