From patchwork Thu May 11 22:48:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 18614 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 7D0B4BD16B for ; Thu, 11 May 2023 22:48:40 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 00060633BA; Fri, 12 May 2023 00:48:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1683845318; bh=PO+khrgkmgH0MRjDkkq/NgIqzlUH7vj7fUnEUdV3wik=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=SdVM3q2hLOSA7EP7JLYFYFjJYtaPWIgU/ywKHt2Az2LKchPwCRvugfiNCH1dewc2l 49Nme9oDTOAmV9FUJCqequaKvbQQN78LMHuUgJIKQKfKp6jizdfeRM+Cds+7NLMRAa PRf9u+8JfTbzyoZtlFTuzI65cXTp4yZeOmi6xB3dxiclRaLx058MbLznplytsrvHfd uQCNmP2JBYmjP7FQce6AOCuMZyCf5X/519/thH532acFcExLxn3dDoLB3fSMND+oF9 npIlsMQ/fX5lmu11v0C8P3TYIRQ7vS4ggid8ikSQoADStBwQTSCpqgIM2y9Qwv9xmh BG24ilOlD1VhA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5AA466039E for ; Fri, 12 May 2023 00:48:35 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="W5muiTFY"; dkim-atps=neutral Received: from Monstersaurus.local (aztw-30-b2-v4wan-166917-cust845.vm26.cable.virginm.net [82.37.23.78]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B17DC132F; Fri, 12 May 2023 00:48:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1683845307; bh=PO+khrgkmgH0MRjDkkq/NgIqzlUH7vj7fUnEUdV3wik=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=W5muiTFYBtu4/EjyrEz8OQVd5ZlpHK1xGg8MJty4cZoHRWcddJXbUwnnSBcDKk7Qk Yy6nQGvmVwl9EJXi6O0dgf0EIFp7U6kIeSPOgB2Q3h7T+leOs0ULr7VDbvLRgz7N3m qzatWmy3OVo0gT5hMrqatflqkD6XqyS9lYCb7fK0= To: libcamera devel Date: Thu, 11 May 2023 23:48:24 +0100 Message-Id: <20230511224830.356416-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230511224830.356416-1-kieran.bingham@ideasonboard.com> References: <20230511224830.356416-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 1/4] libcamera: camera_manager: Move private implementation to internal 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: , X-Patchwork-Original-From: Kieran Bingham via libcamera-devel From: Kieran Bingham Reply-To: Kieran Bingham Cc: George Kiagiadakis , Robert Mader , Wim Taymans Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The CameraManager makes use of the Extensible pattern to provide an internal private implementation that is not exposed in the public API. Move the Private declaration to an internal header to make it available from other internal components in preperation for reducing the surface area of the public interface of the Camera Manager. Signed-off-by: Kieran Bingham --- include/libcamera/internal/camera_manager.h | 66 +++++++++++++++++++++ include/libcamera/internal/meson.build | 1 + src/libcamera/camera_manager.cpp | 49 ++------------- 3 files changed, 71 insertions(+), 45 deletions(-) create mode 100644 include/libcamera/internal/camera_manager.h diff --git a/include/libcamera/internal/camera_manager.h b/include/libcamera/internal/camera_manager.h new file mode 100644 index 000000000000..4bba3ac2eb29 --- /dev/null +++ b/include/libcamera/internal/camera_manager.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Ideas on Board Oy. + * + * camera_manager.h - Camera manager private data + */ +#ifndef __LIBCAMERA_INTERNAL_CAMERA_MANAGER_H__ +#define __LIBCAMERA_INTERNAL_CAMERA_MANAGER_H__ + +#include + +#include +#include + +#include + +#include "libcamera/internal/ipa_manager.h" +#include "libcamera/internal/process.h" + +namespace libcamera { + +class DeviceEnumerator; + +class CameraManager::Private : public Extensible::Private, public Thread +{ + LIBCAMERA_DECLARE_PUBLIC(CameraManager) + +public: + Private(); + + int start(); + void addCamera(std::shared_ptr camera, + const std::vector &devnums) LIBCAMERA_TSA_EXCLUDES(mutex_); + void removeCamera(Camera *camera) LIBCAMERA_TSA_EXCLUDES(mutex_); + + /* + * This mutex protects + * + * - initialized_ and status_ during initialization + * - cameras_ and camerasByDevnum_ after initialization + */ + mutable Mutex mutex_; + std::vector> cameras_ LIBCAMERA_TSA_GUARDED_BY(mutex_); + std::map> camerasByDevnum_ LIBCAMERA_TSA_GUARDED_BY(mutex_); + +protected: + void run() override; + +private: + int init(); + void createPipelineHandlers(); + void cleanup() LIBCAMERA_TSA_EXCLUDES(mutex_); + + ConditionVariable cv_; + bool initialized_ LIBCAMERA_TSA_GUARDED_BY(mutex_); + int status_ LIBCAMERA_TSA_GUARDED_BY(mutex_); + + std::unique_ptr enumerator_; + + IPAManager ipaManager_; + ProcessManager processManager_; +}; + +} /* namespace libcamera */ + +#endif // __LIBCAMERA_INTERNAL_CAMERA_MANAGER_H__ diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index d75088059996..0028ed0dc27f 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -13,6 +13,7 @@ libcamera_internal_headers = files([ 'bayer_format.h', 'byte_stream_buffer.h', 'camera.h', + 'camera_manager.h', 'camera_controls.h', 'camera_lens.h', 'camera_sensor.h', diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp index c1edefdad160..b95284ba5a80 100644 --- a/src/libcamera/camera_manager.cpp +++ b/src/libcamera/camera_manager.cpp @@ -9,20 +9,19 @@ #include -#include - #include #include #include #include +#include + +#include "libcamera/internal/camera_manager.h" #include "libcamera/internal/device_enumerator.h" -#include "libcamera/internal/ipa_manager.h" #include "libcamera/internal/pipeline_handler.h" -#include "libcamera/internal/process.h" /** - * \file camera_manager.h + * \file libcamera/camera_manager.h * \brief The camera manager */ @@ -33,46 +32,6 @@ namespace libcamera { LOG_DEFINE_CATEGORY(Camera) -class CameraManager::Private : public Extensible::Private, public Thread -{ - LIBCAMERA_DECLARE_PUBLIC(CameraManager) - -public: - Private(); - - int start(); - void addCamera(std::shared_ptr camera, - const std::vector &devnums) LIBCAMERA_TSA_EXCLUDES(mutex_); - void removeCamera(Camera *camera) LIBCAMERA_TSA_EXCLUDES(mutex_); - - /* - * This mutex protects - * - * - initialized_ and status_ during initialization - * - cameras_ and camerasByDevnum_ after initialization - */ - mutable Mutex mutex_; - std::vector> cameras_ LIBCAMERA_TSA_GUARDED_BY(mutex_); - std::map> camerasByDevnum_ LIBCAMERA_TSA_GUARDED_BY(mutex_); - -protected: - void run() override; - -private: - int init(); - void createPipelineHandlers(); - void cleanup() LIBCAMERA_TSA_EXCLUDES(mutex_); - - ConditionVariable cv_; - bool initialized_ LIBCAMERA_TSA_GUARDED_BY(mutex_); - int status_ LIBCAMERA_TSA_GUARDED_BY(mutex_); - - std::unique_ptr enumerator_; - - IPAManager ipaManager_; - ProcessManager processManager_; -}; - CameraManager::Private::Private() : initialized_(false) { From patchwork Thu May 11 22:48:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 18616 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 947CBC3285 for ; Thu, 11 May 2023 22:48:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D5F3B633C4; Fri, 12 May 2023 00:48:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1683845319; bh=3ExVC91FmGtc9FklNc+yXz0Wp0KSHyqL3SC0ExEt0S0=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=buc7xw388OLDxCBygl+jIOeQDc0dmrmsnFe1g8gmc2/MLtu5/D4EFu1UeRkL1cMnH pRO/BEvA4SQot85UpACeiaSGps40Nn7J+fIKtKbBIv/BMqOuE0tbQH2XZD95KEl+j7 6BQjOTmg66d8wnCmeOC/QS5ue0nTeC3mX92LTJH81rd+COoQ0tc1qVhNWSbGuov4L/ s0hhwkBePcqU5Y9jXc73FQgByNuerKTvuilwZdCQ72RN3uJhw6fzYHWCwOUnNVNC0N 3iDUxJSf9XGX6IgnkDNNs0FzWxXisriy+DBY1NaNvpXhKxx8PjGfsNY7r+ixHOM+vP RbaHzRafrV39g== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1BACC633A8 for ; Fri, 12 May 2023 00:48:36 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="vwcpvaMU"; dkim-atps=neutral Received: from Monstersaurus.local (aztw-30-b2-v4wan-166917-cust845.vm26.cable.virginm.net [82.37.23.78]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A022114DC; Fri, 12 May 2023 00:48:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1683845307; bh=3ExVC91FmGtc9FklNc+yXz0Wp0KSHyqL3SC0ExEt0S0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vwcpvaMUfQR84rfOK+yUYc+mWotOt0XeNW5zoRY4H9T9u6Q79wZvBE45YEzofJ1yS IgTSeHgZtLAOEaM30DY6oJyK5inY0fXeJLfLfG0C+IB9rCDnJjlGfcUCcPAC+wckJG 7Twd4Q5H0GMh8MkoW+HzwmOLF7zSE+4EGX16zdGM= To: libcamera devel Date: Thu, 11 May 2023 23:48:26 +0100 Message-Id: <20230511224830.356416-4-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230511224830.356416-1-kieran.bingham@ideasonboard.com> References: <20230511224830.356416-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/4] libcamera: camera_manager: Move {add, remove}Camera to internal 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: , X-Patchwork-Original-From: Kieran Bingham via libcamera-devel From: Kieran Bingham Reply-To: Kieran Bingham Cc: George Kiagiadakis , Robert Mader , Wim Taymans Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The CameraManager exposes addCamera and removeCamera as public API calls, while they should never be called from an application. These calls are only expected to be used by PipelineHandlers to update the CameraManager that a new Camera has been created and allow the Camera Manager to expose it to applications. Remove the public calls and update the private implementations such that they can be used directly by the PipelineHandler through the internal CameraManager::Private provided by the Extensible class. Signed-off-by: Kieran Bingham --- include/libcamera/camera_manager.h | 4 - include/libcamera/internal/camera_manager.h | 2 +- src/libcamera/camera_manager.cpp | 87 +++++++++------------ src/libcamera/pipeline_handler.cpp | 6 +- 4 files changed, 43 insertions(+), 56 deletions(-) diff --git a/include/libcamera/camera_manager.h b/include/libcamera/camera_manager.h index 4b1fb7568e83..9767acc42c89 100644 --- a/include/libcamera/camera_manager.h +++ b/include/libcamera/camera_manager.h @@ -34,10 +34,6 @@ public: std::shared_ptr get(const std::string &id); std::shared_ptr get(dev_t devnum); - void addCamera(std::shared_ptr camera, - const std::vector &devnums); - void removeCamera(std::shared_ptr camera); - static const std::string &version() { return version_; } Signal> cameraAdded; diff --git a/include/libcamera/internal/camera_manager.h b/include/libcamera/internal/camera_manager.h index 4bba3ac2eb29..8386e90e0f60 100644 --- a/include/libcamera/internal/camera_manager.h +++ b/include/libcamera/internal/camera_manager.h @@ -31,7 +31,7 @@ public: int start(); void addCamera(std::shared_ptr camera, const std::vector &devnums) LIBCAMERA_TSA_EXCLUDES(mutex_); - void removeCamera(Camera *camera) LIBCAMERA_TSA_EXCLUDES(mutex_); + void removeCamera(std::shared_ptr camera) LIBCAMERA_TSA_EXCLUDES(mutex_); /* * This mutex protects diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp index b95284ba5a80..34f09a4d181b 100644 --- a/src/libcamera/camera_manager.cpp +++ b/src/libcamera/camera_manager.cpp @@ -148,9 +148,25 @@ void CameraManager::Private::cleanup() enumerator_.reset(nullptr); } +/** + * \brief Add a camera to the camera manager + * \param[in] camera The camera to be added + * \param[in] devnums The device numbers to associate with \a camera + * + * This function is called by pipeline handlers to register the cameras they + * handle with the camera manager. Registered cameras are immediately made + * available to the system. + * + * \a devnums are used by the V4L2 compatibility layer to map V4L2 device nodes + * to Camera instances. + * + * \context This function shall be called from the CameraManager thread. + */ void CameraManager::Private::addCamera(std::shared_ptr camera, const std::vector &devnums) { + ASSERT(Thread::current() == this); + MutexLocker locker(mutex_); for (const std::shared_ptr &c : cameras_) { @@ -167,15 +183,31 @@ void CameraManager::Private::addCamera(std::shared_ptr camera, unsigned int index = cameras_.size() - 1; for (dev_t devnum : devnums) camerasByDevnum_[devnum] = cameras_[index]; + + /* Report the addition to the public signal */ + CameraManager *const o = LIBCAMERA_O_PTR(); + o->cameraAdded.emit(cameras_[index]); } -void CameraManager::Private::removeCamera(Camera *camera) +/** + * \brief Remove a camera from the camera manager + * \param[in] camera The camera to be removed + * + * This function is called by pipeline handlers to unregister cameras from the + * camera manager. Unregistered cameras won't be reported anymore by the + * cameras() and get() calls, but references may still exist in applications. + * + * \context This function shall be called from the CameraManager thread. + */ +void CameraManager::Private::removeCamera(std::shared_ptr camera) { + ASSERT(Thread::current() == this); + MutexLocker locker(mutex_); auto iter = std::find_if(cameras_.begin(), cameras_.end(), [camera](std::shared_ptr &c) { - return c.get() == camera; + return c.get() == camera.get(); }); if (iter == cameras_.end()) return; @@ -185,12 +217,16 @@ void CameraManager::Private::removeCamera(Camera *camera) auto iter_d = std::find_if(camerasByDevnum_.begin(), camerasByDevnum_.end(), [camera](const std::pair> &p) { - return p.second.lock().get() == camera; + return p.second.lock().get() == camera.get(); }); if (iter_d != camerasByDevnum_.end()) camerasByDevnum_.erase(iter_d); cameras_.erase(iter); + + /* Report the removal to the public signal */ + CameraManager *const o = LIBCAMERA_O_PTR(); + o->cameraRemoved.emit(camera); } /** @@ -383,51 +419,6 @@ std::shared_ptr CameraManager::get(dev_t devnum) * perform any blocking operation. */ -/** - * \brief Add a camera to the camera manager - * \param[in] camera The camera to be added - * \param[in] devnums The device numbers to associate with \a camera - * - * This function is called by pipeline handlers to register the cameras they - * handle with the camera manager. Registered cameras are immediately made - * available to the system. - * - * \a devnums are used by the V4L2 compatibility layer to map V4L2 device nodes - * to Camera instances. - * - * \context This function shall be called from the CameraManager thread. - */ -void CameraManager::addCamera(std::shared_ptr camera, - const std::vector &devnums) -{ - Private *const d = _d(); - - ASSERT(Thread::current() == d); - - d->addCamera(camera, devnums); - cameraAdded.emit(camera); -} - -/** - * \brief Remove a camera from the camera manager - * \param[in] camera The camera to be removed - * - * This function is called by pipeline handlers to unregister cameras from the - * camera manager. Unregistered cameras won't be reported anymore by the - * cameras() and get() calls, but references may still exist in applications. - * - * \context This function shall be called from the CameraManager thread. - */ -void CameraManager::removeCamera(std::shared_ptr camera) -{ - Private *const d = _d(); - - ASSERT(Thread::current() == d); - - d->removeCamera(camera.get()); - cameraRemoved.emit(camera); -} - /** * \fn const std::string &CameraManager::version() * \brief Retrieve the libcamera version string diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index f72613b8e515..49092ea88a58 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -16,10 +16,10 @@ #include #include -#include #include #include "libcamera/internal/camera.h" +#include "libcamera/internal/camera_manager.h" #include "libcamera/internal/device_enumerator.h" #include "libcamera/internal/framebuffer.h" #include "libcamera/internal/media_device.h" @@ -624,7 +624,7 @@ void PipelineHandler::registerCamera(std::shared_ptr camera) } } - manager_->addCamera(std::move(camera), devnums); + manager_->_d()->addCamera(std::move(camera), devnums); } /** @@ -691,7 +691,7 @@ void PipelineHandler::disconnect() continue; camera->disconnect(); - manager_->removeCamera(camera); + manager_->_d()->removeCamera(camera); } } From patchwork Thu May 11 22:48:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 18618 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 2ED40C32A4 for ; Thu, 11 May 2023 22:48:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 058B9633CB; Fri, 12 May 2023 00:48:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1683845321; bh=3ExVC91FmGtc9FklNc+yXz0Wp0KSHyqL3SC0ExEt0S0=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Q4dMX8nAUTb67Yepb1VwcHhp0XbLyjY001wmJdNLNhHI2efJKi9oPbKZuCVRWpMkp QsLkI//d+fQADVWOHUHhzfEVPgU/4t/+/fDOy+iORO6jmJWVKQaCJ4wuE6AehJ3t4F pr8xHPcLD/leFCgeD3NnFlpo54OgOzqjYKZZUeFviWgR7mQmpRyTTabmfD/xzPJsao 0WCt6Zc/5RGoV0/1nc7Z3MhCQlFakFNizXwFN43JQnjNmR9/JLcbvpK3Ni0OheC6ge Q/qMQb5BHHn4TkRQ81bzfWgThdEq3Ru14s23gCzxnJL182p3fuCNtjbR/KpV0YMvSx uwtg2xGRLoTcQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 26F34633BA for ; Fri, 12 May 2023 00:48:37 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="fsLeNGkH"; dkim-atps=neutral Received: from Monstersaurus.local (aztw-30-b2-v4wan-166917-cust845.vm26.cable.virginm.net [82.37.23.78]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 914F81515; Fri, 12 May 2023 00:48:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1683845308; bh=3ExVC91FmGtc9FklNc+yXz0Wp0KSHyqL3SC0ExEt0S0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fsLeNGkH/CRQJsx8RzBFfCFgkPgOQ4zqpxZEO/XqrcSerBk4tgmRNh1kCMTErmMge slJv+gvpB3TI5v0OV/D7d7zxsa4BkU2W4sHEExjPqrkoUmiBMeMYzgxxXD40Ow9q3W SffJL+q2Ea7x4bY/TWS/1bTpKfde5Vd+I52CgCZM= To: libcamera devel Date: Thu, 11 May 2023 23:48:28 +0100 Message-Id: <20230511224830.356416-6-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230511224830.356416-1-kieran.bingham@ideasonboard.com> References: <20230511224830.356416-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 3/4] libcamera: camera_manager: Move {add, remove}Camera to internal 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: , X-Patchwork-Original-From: Kieran Bingham via libcamera-devel From: Kieran Bingham Reply-To: Kieran Bingham Cc: George Kiagiadakis , Robert Mader , Wim Taymans Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The CameraManager exposes addCamera and removeCamera as public API calls, while they should never be called from an application. These calls are only expected to be used by PipelineHandlers to update the CameraManager that a new Camera has been created and allow the Camera Manager to expose it to applications. Remove the public calls and update the private implementations such that they can be used directly by the PipelineHandler through the internal CameraManager::Private provided by the Extensible class. Signed-off-by: Kieran Bingham --- include/libcamera/camera_manager.h | 4 - include/libcamera/internal/camera_manager.h | 2 +- src/libcamera/camera_manager.cpp | 87 +++++++++------------ src/libcamera/pipeline_handler.cpp | 6 +- 4 files changed, 43 insertions(+), 56 deletions(-) diff --git a/include/libcamera/camera_manager.h b/include/libcamera/camera_manager.h index 4b1fb7568e83..9767acc42c89 100644 --- a/include/libcamera/camera_manager.h +++ b/include/libcamera/camera_manager.h @@ -34,10 +34,6 @@ public: std::shared_ptr get(const std::string &id); std::shared_ptr get(dev_t devnum); - void addCamera(std::shared_ptr camera, - const std::vector &devnums); - void removeCamera(std::shared_ptr camera); - static const std::string &version() { return version_; } Signal> cameraAdded; diff --git a/include/libcamera/internal/camera_manager.h b/include/libcamera/internal/camera_manager.h index 4bba3ac2eb29..8386e90e0f60 100644 --- a/include/libcamera/internal/camera_manager.h +++ b/include/libcamera/internal/camera_manager.h @@ -31,7 +31,7 @@ public: int start(); void addCamera(std::shared_ptr camera, const std::vector &devnums) LIBCAMERA_TSA_EXCLUDES(mutex_); - void removeCamera(Camera *camera) LIBCAMERA_TSA_EXCLUDES(mutex_); + void removeCamera(std::shared_ptr camera) LIBCAMERA_TSA_EXCLUDES(mutex_); /* * This mutex protects diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp index b95284ba5a80..34f09a4d181b 100644 --- a/src/libcamera/camera_manager.cpp +++ b/src/libcamera/camera_manager.cpp @@ -148,9 +148,25 @@ void CameraManager::Private::cleanup() enumerator_.reset(nullptr); } +/** + * \brief Add a camera to the camera manager + * \param[in] camera The camera to be added + * \param[in] devnums The device numbers to associate with \a camera + * + * This function is called by pipeline handlers to register the cameras they + * handle with the camera manager. Registered cameras are immediately made + * available to the system. + * + * \a devnums are used by the V4L2 compatibility layer to map V4L2 device nodes + * to Camera instances. + * + * \context This function shall be called from the CameraManager thread. + */ void CameraManager::Private::addCamera(std::shared_ptr camera, const std::vector &devnums) { + ASSERT(Thread::current() == this); + MutexLocker locker(mutex_); for (const std::shared_ptr &c : cameras_) { @@ -167,15 +183,31 @@ void CameraManager::Private::addCamera(std::shared_ptr camera, unsigned int index = cameras_.size() - 1; for (dev_t devnum : devnums) camerasByDevnum_[devnum] = cameras_[index]; + + /* Report the addition to the public signal */ + CameraManager *const o = LIBCAMERA_O_PTR(); + o->cameraAdded.emit(cameras_[index]); } -void CameraManager::Private::removeCamera(Camera *camera) +/** + * \brief Remove a camera from the camera manager + * \param[in] camera The camera to be removed + * + * This function is called by pipeline handlers to unregister cameras from the + * camera manager. Unregistered cameras won't be reported anymore by the + * cameras() and get() calls, but references may still exist in applications. + * + * \context This function shall be called from the CameraManager thread. + */ +void CameraManager::Private::removeCamera(std::shared_ptr camera) { + ASSERT(Thread::current() == this); + MutexLocker locker(mutex_); auto iter = std::find_if(cameras_.begin(), cameras_.end(), [camera](std::shared_ptr &c) { - return c.get() == camera; + return c.get() == camera.get(); }); if (iter == cameras_.end()) return; @@ -185,12 +217,16 @@ void CameraManager::Private::removeCamera(Camera *camera) auto iter_d = std::find_if(camerasByDevnum_.begin(), camerasByDevnum_.end(), [camera](const std::pair> &p) { - return p.second.lock().get() == camera; + return p.second.lock().get() == camera.get(); }); if (iter_d != camerasByDevnum_.end()) camerasByDevnum_.erase(iter_d); cameras_.erase(iter); + + /* Report the removal to the public signal */ + CameraManager *const o = LIBCAMERA_O_PTR(); + o->cameraRemoved.emit(camera); } /** @@ -383,51 +419,6 @@ std::shared_ptr CameraManager::get(dev_t devnum) * perform any blocking operation. */ -/** - * \brief Add a camera to the camera manager - * \param[in] camera The camera to be added - * \param[in] devnums The device numbers to associate with \a camera - * - * This function is called by pipeline handlers to register the cameras they - * handle with the camera manager. Registered cameras are immediately made - * available to the system. - * - * \a devnums are used by the V4L2 compatibility layer to map V4L2 device nodes - * to Camera instances. - * - * \context This function shall be called from the CameraManager thread. - */ -void CameraManager::addCamera(std::shared_ptr camera, - const std::vector &devnums) -{ - Private *const d = _d(); - - ASSERT(Thread::current() == d); - - d->addCamera(camera, devnums); - cameraAdded.emit(camera); -} - -/** - * \brief Remove a camera from the camera manager - * \param[in] camera The camera to be removed - * - * This function is called by pipeline handlers to unregister cameras from the - * camera manager. Unregistered cameras won't be reported anymore by the - * cameras() and get() calls, but references may still exist in applications. - * - * \context This function shall be called from the CameraManager thread. - */ -void CameraManager::removeCamera(std::shared_ptr camera) -{ - Private *const d = _d(); - - ASSERT(Thread::current() == d); - - d->removeCamera(camera.get()); - cameraRemoved.emit(camera); -} - /** * \fn const std::string &CameraManager::version() * \brief Retrieve the libcamera version string diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index f72613b8e515..49092ea88a58 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -16,10 +16,10 @@ #include #include -#include #include #include "libcamera/internal/camera.h" +#include "libcamera/internal/camera_manager.h" #include "libcamera/internal/device_enumerator.h" #include "libcamera/internal/framebuffer.h" #include "libcamera/internal/media_device.h" @@ -624,7 +624,7 @@ void PipelineHandler::registerCamera(std::shared_ptr camera) } } - manager_->addCamera(std::move(camera), devnums); + manager_->_d()->addCamera(std::move(camera), devnums); } /** @@ -691,7 +691,7 @@ void PipelineHandler::disconnect() continue; camera->disconnect(); - manager_->removeCamera(camera); + manager_->_d()->removeCamera(camera); } } From patchwork Thu May 11 22:48:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 18619 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 4F9BDC32A5 for ; Thu, 11 May 2023 22:48:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8FF60633CE; Fri, 12 May 2023 00:48:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1683845321; bh=Xg9QLFlM9LIiUN/2yhjh8ehnqdh9TxE4uobTVMhhvZU=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=IeEpXdO8GJwifufKspv7nI+nXTSF9JxsYSbT10O1TxtzaHpeNwfqkqkU2b2rkaxEn z45McuBY7V3G5Q0DH1/ghHUlp1TDc/vra7Wqv2gGRA2OzTyGUGd8jrPGtgPiTpasFI Mb9WR3diI6FIQMCQD9JBJvr3L0CjCS/6cJ+1gHvdV44qVE7ZHqAsUUCS5A7EssGvqU uXzE17L76ussAsbhKQWBTwxauHh+INvILay5Lel4MvIjUghO3jKhXawich26yNOX8J qkJz9vKTr4uLMQNgLMxbh0XMxtpSKQvkIjegqS+g9ZL1GmSaT7qZXlDpCatZS/9Jh0 S4Keh6UhJNf3w== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E7539633BD for ; Fri, 12 May 2023 00:48:37 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ZSrfl8e1"; dkim-atps=neutral Received: from Monstersaurus.local (aztw-30-b2-v4wan-166917-cust845.vm26.cable.virginm.net [82.37.23.78]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7C9B41583; Fri, 12 May 2023 00:48:29 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1683845309; bh=Xg9QLFlM9LIiUN/2yhjh8ehnqdh9TxE4uobTVMhhvZU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZSrfl8e1sSaXbBIcUK7sldyNj4kfunmHGv/PfKkJ2rsBK3dUbWPSTuycW3gHayr1A tiovwtfQy99Y2C5y/cZKIsathS0N1yNhfOFug+29UuEtWgO17I692imQJpz4N8ZSEd NXTqv4cnn4UXXPl1+nhrch+HjuAJBc1g14JoPpHY= To: libcamera devel Date: Thu, 11 May 2023 23:48:30 +0100 Message-Id: <20230511224830.356416-8-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230511224830.356416-1-kieran.bingham@ideasonboard.com> References: <20230511224830.356416-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 4/4] libcamera: pipeline: Register device numbers with camera 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: , X-Patchwork-Original-From: Kieran Bingham via libcamera-devel From: Kieran Bingham Reply-To: Kieran Bingham Cc: George Kiagiadakis , Robert Mader , Wim Taymans Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Register the identified device numbers with each camera as the Devices property. This facilitates camera daemons or other systems to identify which devices are being managed by libcamera, and can prevent duplication of camera resources. As the Devices property now provides this list of devices, use it directly from within the CameraManager when adding a Camera rather than passing it through the internal API. Signed-off-by: Kieran Bingham --- include/libcamera/internal/camera_manager.h | 3 +-- src/libcamera/camera_manager.cpp | 13 ++++++++----- src/libcamera/pipeline_handler.cpp | 12 ++++++++++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/include/libcamera/internal/camera_manager.h b/include/libcamera/internal/camera_manager.h index 8386e90e0f60..061d2c5083b0 100644 --- a/include/libcamera/internal/camera_manager.h +++ b/include/libcamera/internal/camera_manager.h @@ -29,8 +29,7 @@ public: Private(); int start(); - void addCamera(std::shared_ptr camera, - const std::vector &devnums) LIBCAMERA_TSA_EXCLUDES(mutex_); + void addCamera(std::shared_ptr camera) LIBCAMERA_TSA_EXCLUDES(mutex_); void removeCamera(std::shared_ptr camera) LIBCAMERA_TSA_EXCLUDES(mutex_); /* diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp index 34f09a4d181b..df5fdede85da 100644 --- a/src/libcamera/camera_manager.cpp +++ b/src/libcamera/camera_manager.cpp @@ -15,7 +15,9 @@ #include #include +#include +#include "libcamera/internal/camera.h" #include "libcamera/internal/camera_manager.h" #include "libcamera/internal/device_enumerator.h" #include "libcamera/internal/pipeline_handler.h" @@ -151,19 +153,17 @@ void CameraManager::Private::cleanup() /** * \brief Add a camera to the camera manager * \param[in] camera The camera to be added - * \param[in] devnums The device numbers to associate with \a camera * * This function is called by pipeline handlers to register the cameras they * handle with the camera manager. Registered cameras are immediately made * available to the system. * - * \a devnums are used by the V4L2 compatibility layer to map V4L2 device nodes - * to Camera instances. + * Device numbers from the Devices property are used by the V4L2 compatibility + * layer to map V4L2 device nodes to Camera instances. * * \context This function shall be called from the CameraManager thread. */ -void CameraManager::Private::addCamera(std::shared_ptr camera, - const std::vector &devnums) +void CameraManager::Private::addCamera(std::shared_ptr camera) { ASSERT(Thread::current() == this); @@ -178,6 +178,9 @@ void CameraManager::Private::addCamera(std::shared_ptr camera, } } + Camera::Private *data = camera->_d(); + auto devnums = data->properties_.get(properties::Devices).value_or(std::vector{}); + cameras_.push_back(std::move(camera)); unsigned int index = cameras_.size() - 1; diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 49092ea88a58..0b5fac7ad113 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "libcamera/internal/camera.h" #include "libcamera/internal/camera_manager.h" @@ -612,7 +613,7 @@ void PipelineHandler::registerCamera(std::shared_ptr camera) * Walk the entity list and map the devnums of all capture video nodes * to the camera. */ - std::vector devnums; + std::vector devnums; for (const std::shared_ptr &media : mediaDevices_) { for (const MediaEntity *entity : media->entities()) { if (entity->pads().size() == 1 && @@ -624,7 +625,14 @@ void PipelineHandler::registerCamera(std::shared_ptr camera) } } - manager_->_d()->addCamera(std::move(camera), devnums); + /* + * Store the associated devices as a property of the camera to allow + * systems to identify which devices are managed by libcamera. + */ + Camera::Private *data = camera->_d(); + data->properties_.set(properties::Devices, devnums); + + manager_->_d()->addCamera(std::move(camera)); } /**