From patchwork Fri Aug 21 14:46:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 9342 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 F40ABBD87C for ; Fri, 21 Aug 2020 14:46:11 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5169F61FE7; Fri, 21 Aug 2020 16:46:11 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="WaqZTsY2"; dkim-atps=neutral Received: from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5C25360383 for ; Fri, 21 Aug 2020 16:46:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uajain.com; h=from:subject:in-reply-to:references:mime-version:to:cc:content-type: content-transfer-encoding; s=s1; bh=bDhthrO6iz7youdFrsP8Xzu7GFBabmYGQfFNjuzf8Lc=; b=WaqZTsY2hutRcHqoJGwgw4ttEFkCewsijvh29xo7SUHRYq79vzRitpW61g5TIzfnI8LM 9jXFPDcBXrHl+7dlz6C/cwBQ0QlZCw/8f3bjexoa+XQP9vSECRTJsRhvZ2QKXMZgTi6DRw EuTBVgiW6xCrZnGpHz0QLbtKILpXETfKs= Received: by filterdrecv-p3iad2-86945d9569-xwnpr with SMTP id filterdrecv-p3iad2-86945d9569-xwnpr-20-5F3FDE2E-87 2020-08-21 14:46:06.855812348 +0000 UTC m=+74586.787788678 Received: from mail.uajain.com (unknown) by ismtpd0008p1hnd1.sendgrid.net (SG) with ESMTP id AVVJrOyqR2SNmZOB4qEiJQ Fri, 21 Aug 2020 14:46:06.357 +0000 (UTC) From: Umang Jain Date: Fri, 21 Aug 2020 14:46:06 +0000 (UTC) Message-Id: <20200821144601.67860-2-email@uajain.com> In-Reply-To: <20200821144601.67860-1-email@uajain.com> References: <20200821144601.67860-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcREc2X1LpIgLW8oEasGbeg5/y0q7HvjiQWMRkTS5oElgo/JeCQCPn9EsF5tlGGDhq4LXmXWmJEuIPcNbZFdW6/7ePNjbBuCTboxcjujj2FW5MfpQbnUlVW/RIJKgm6hxW+ID3GLS63dyLAUBmso/UPP+45SSrTl0CGQs5UC7AFpTnGMWLQ5NryqcjNx5h3qFJ688qzzkMoyS+k2XfODpE8Q== To: libcamera-devel@lists.libcamera.org Subject: [libcamera-devel] [PATCH v4 1/5] libcamera: pipeline: uvcvideo: Treat all UVC cameras as external 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" We currently have no way to identify if the UVC device is external or internal(i.e. non-removable) to the system to set this property. Until we have a starting point to resolve this, treat all UVC cameras. Add a \todo explaining the situation for the same. Signed-off-by: Umang Jain Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index bc892ec..bafe6f1 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -500,6 +501,12 @@ int UVCCameraData::init(MediaEntity *entity) video_->bufferReady.connect(this, &UVCCameraData::bufferReady); + /* + * \todo Find a way to tell internal and external UVC cameras apart. + * Until then, treat all UVC cameras as external. + */ + properties_.set(properties::Location, properties::CameraLocationExternal); + /* Initialise the supported controls. */ ControlInfoMap::Map ctrls; From patchwork Fri Aug 21 14:46:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 9343 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 F1323BE174 for ; Fri, 21 Aug 2020 14:46:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 11D0762113; Fri, 21 Aug 2020 16:46:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="RMgLOP+r"; dkim-atps=neutral Received: from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AB7E461B4F for ; Fri, 21 Aug 2020 16:46:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uajain.com; h=from:subject:in-reply-to:references:mime-version:to:cc:content-type: content-transfer-encoding; s=s1; bh=WlyI45ayfL5lw/SJQXCZOK/kp6kF5E1uzpkjn96L88U=; b=RMgLOP+rIFpv/x9RZEqLMXdGsefzs/5MNpiP3PeCa/k+buY55gk+g8VznbEfN8ld+nID ccTLArTrSH/n4fczOwtb/tpJSImouvMiX9KJwqjsc7Ck3b/yQnBtRjdZjt/RjAo9hN7OwX GoNl8+z6rWSOIj4totb6bsHOt2YxAMxm4= Received: by filterdrecv-p3iad2-86945d9569-wzrpx with SMTP id filterdrecv-p3iad2-86945d9569-wzrpx-18-5F3FDE2F-2C 2020-08-21 14:46:07.451894897 +0000 UTC m=+74583.034326788 Received: from mail.uajain.com (unknown) by ismtpd0008p1maa1.sendgrid.net (SG) with ESMTP id gGxWJ-QDRkmfi3o3ouVs8A Fri, 21 Aug 2020 14:46:06.680 +0000 (UTC) From: Umang Jain Date: Fri, 21 Aug 2020 14:46:07 +0000 (UTC) Message-Id: <20200821144601.67860-3-email@uajain.com> In-Reply-To: <20200821144601.67860-1-email@uajain.com> References: <20200821144601.67860-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcj9TjcWbOI2k4lJ0fKJaeewpvHcUm93kY5HdydhkbnJ7nXQIpKLvE5/Gga7wednw3myD8ny9GkcvFk3HjjNVaIsMWBE20ZZlLWRS8XXSIqknyJZ8GcC6TN8bgThPjrKG3Vwq9q9qsiuTtYwCWhRNQgSsLz7M2H4yqCN5BRny1DeOhQTV/3+bgEJ113Brdtg+PsdANtduT+BZad5qKAhX9HQ== To: libcamera-devel@lists.libcamera.org Subject: [libcamera-devel] [PATCH v4 2/5] android: camera_hal_manager: Set camera module callbacks 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" camera_module_callbacks are invoked to inform the framework about the events occurring module-wide. Allow to set these callbacks in camera_hal_manager as this will be used to integration camera hotplug support via camera_module_callbacks::camera_device_status_change in subsequent commit. Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Reviewed-by: Kieran Bingham --- src/android/camera3_hal.cpp | 2 ++ src/android/camera_hal_manager.cpp | 5 +++++ src/android/camera_hal_manager.h | 3 +++ 3 files changed, 10 insertions(+) diff --git a/src/android/camera3_hal.cpp b/src/android/camera3_hal.cpp index 716e36c..c2cba29 100644 --- a/src/android/camera3_hal.cpp +++ b/src/android/camera3_hal.cpp @@ -34,6 +34,8 @@ static int hal_get_camera_info(int id, struct camera_info *info) static int hal_set_callbacks(const camera_module_callbacks_t *callbacks) { + cameraManager.setCallbacks(callbacks); + return 0; } diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp index 02b6418..3d6d2b4 100644 --- a/src/android/camera_hal_manager.cpp +++ b/src/android/camera_hal_manager.cpp @@ -120,3 +120,8 @@ int CameraHalManager::getCameraInfo(unsigned int id, struct camera_info *info) return 0; } + +void CameraHalManager::setCallbacks(const camera_module_callbacks_t *callbacks) +{ + callbacks_ = callbacks; +} diff --git a/src/android/camera_hal_manager.h b/src/android/camera_hal_manager.h index 0619037..a582f04 100644 --- a/src/android/camera_hal_manager.h +++ b/src/android/camera_hal_manager.h @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -29,10 +30,12 @@ public: unsigned int numCameras() const; int getCameraInfo(unsigned int id, struct camera_info *info); + void setCallbacks(const camera_module_callbacks_t *callbacks); private: libcamera::CameraManager *cameraManager_; + const camera_module_callbacks_t *callbacks_; std::vector> cameras_; }; From patchwork Fri Aug 21 14:46:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 9345 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 C8201BE174 for ; Fri, 21 Aug 2020 14:46:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0F6276211C; Fri, 21 Aug 2020 16:46:13 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="QgGzkQ6/"; dkim-atps=neutral Received: from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 651AA61B4F for ; Fri, 21 Aug 2020 16:46:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uajain.com; h=from:subject:in-reply-to:references:mime-version:to:cc:content-type: content-transfer-encoding; s=s1; bh=7JPVmRK/eFw1gTrH2wmgD2gmPY/CFv59plWVYemxWxo=; b=QgGzkQ6/+cjdsgAP4hkc/qcj0SWKWF8dFqeKtJHt+PGZ0Dnu4/ICIpjlRV35s7FVqqBi RGDZog9/h+mRMUrTvsTKanmu91FYoXUUB28AD90ZnSUyopqeICe9ODwj6WQ+CxPR2yVZhZ 9JqzJwSwF5vJ18sAGCnLYJWLl+g8WW5aY= Received: by filterdrecv-p3iad2-86945d9569-tl4zj with SMTP id filterdrecv-p3iad2-86945d9569-tl4zj-17-5F3FDE2F-12C 2020-08-21 14:46:08.193268624 +0000 UTC m=+74588.801882622 Received: from mail.uajain.com (unknown) by ismtpd0002p1maa1.sendgrid.net (SG) with ESMTP id ujNN064dTr63HV9cIcE2cw Fri, 21 Aug 2020 14:46:07.760 +0000 (UTC) From: Umang Jain Date: Fri, 21 Aug 2020 14:46:08 +0000 (UTC) Message-Id: <20200821144601.67860-4-email@uajain.com> In-Reply-To: <20200821144601.67860-1-email@uajain.com> References: <20200821144601.67860-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcbjgBrPKwU6zsq5Nc1XDaVjFR/iFc4shZU4fvBEIs/r9zO4E6PsoypsFPhvx2SHHx4luUBFEua31z1hd3ImscIXsgjy9614Du3ef7lVPFJnLLiTE+xmnGJ5clYeUBkplB36W9sR4B1HrSr6odbCKKf3Fz1IHZWRK2AbchAGpSgdDLqyz5dHyKt/3uCj3xlVTCb4i/DYeMJhgeLb7YcBmD5w== To: libcamera-devel@lists.libcamera.org Subject: [libcamera-devel] [PATCH v4 3/5] android: camera_device: Make CameraDevice a shared object 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" CameraDevice needs to be wrapper into the std::shared_ptr instead of std::unique_ptr to enable refcounting. The refcounting will help us to support hotplug and hot-unplug CameraHalManager operations in the subsequent commit. Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- src/android/camera_device.cpp | 7 +++++++ src/android/camera_device.h | 5 ++++- src/android/camera_hal_manager.cpp | 4 ++-- src/android/camera_hal_manager.h | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 3419236..550fcfa 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -233,6 +233,13 @@ CameraDevice::~CameraDevice() delete it.second; } +std::shared_ptr CameraDevice::create(unsigned int id, + const std::shared_ptr &cam) +{ + CameraDevice *camera = new CameraDevice(id, cam); + return std::shared_ptr(camera); +} + /* * Initialize the camera static information. * This method is called before the camera device is opened. diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 7be9e11..3e472c7 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -47,7 +47,8 @@ struct CameraStream { class CameraDevice : protected libcamera::Loggable { public: - CameraDevice(unsigned int id, const std::shared_ptr &camera); + static std::shared_ptr create(unsigned int id, + const std::shared_ptr &cam); ~CameraDevice(); int initialize(); @@ -72,6 +73,8 @@ protected: std::string logPrefix() const override; private: + CameraDevice(unsigned int id, const std::shared_ptr &camera); + struct Camera3RequestDescriptor { Camera3RequestDescriptor(unsigned int frameNumber, unsigned int numBuffers); diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp index 3d6d2b4..3a744af 100644 --- a/src/android/camera_hal_manager.cpp +++ b/src/android/camera_hal_manager.cpp @@ -64,12 +64,12 @@ int CameraHalManager::init() */ unsigned int index = 0; for (auto &cam : cameraManager_->cameras()) { - CameraDevice *camera = new CameraDevice(index, cam); + std::shared_ptr camera = CameraDevice::create(index, cam); ret = camera->initialize(); if (ret) continue; - cameras_.emplace_back(camera); + cameras_.emplace_back(std::move(camera)); ++index; } diff --git a/src/android/camera_hal_manager.h b/src/android/camera_hal_manager.h index a582f04..3e34d63 100644 --- a/src/android/camera_hal_manager.h +++ b/src/android/camera_hal_manager.h @@ -36,7 +36,7 @@ private: libcamera::CameraManager *cameraManager_; const camera_module_callbacks_t *callbacks_; - std::vector> cameras_; + std::vector> cameras_; }; #endif /* __ANDROID_CAMERA_MANAGER_H__ */ From patchwork Fri Aug 21 14:46:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 9346 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 B3AAFBD87C for ; Fri, 21 Aug 2020 14:46:14 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7CE9E620FD; Fri, 21 Aug 2020 16:46:14 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="esMhUVQm"; dkim-atps=neutral Received: from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AA17861ED9 for ; Fri, 21 Aug 2020 16:46:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uajain.com; h=from:subject:in-reply-to:references:mime-version:to:cc:content-type: content-transfer-encoding; s=s1; bh=B4NwZajWiYqznI3i2QI/8UyMBs4UKDLmOYA5LemIMv8=; b=esMhUVQm0B9y5DIp29MZ8NK9yNhgnV+kzEBGdu0307FMkWltrknj8n6jSlwB1VZnZFdK 2ckNlpQJQMmHyiOS6DTlU9mrDnptDe3JfzEzb1mWHlgmwgLoQID1gTOTm9L/fbYjFHBuLd KKhY0b0PG6W1oThi+ioJd6tkcNLrUUQrc= Received: by filterdrecv-p3iad2-86945d9569-pf8bd with SMTP id filterdrecv-p3iad2-86945d9569-pf8bd-18-5F3FDE31-64 2020-08-21 14:46:09.624123219 +0000 UTC m=+74582.104247101 Received: from mail.uajain.com (unknown) by ismtpd0003p1hnd1.sendgrid.net (SG) with ESMTP id KDOU-PvmSIW8wJ8ARNqf1g Fri, 21 Aug 2020 14:46:09.263 +0000 (UTC) From: Umang Jain Date: Fri, 21 Aug 2020 14:46:09 +0000 (UTC) Message-Id: <20200821144601.67860-5-email@uajain.com> In-Reply-To: <20200821144601.67860-1-email@uajain.com> References: <20200821144601.67860-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcclL1jEi7n/kJwGMQDXxjoQ/7A8F8Qzmcnkzv5SyKOxEB/mEvQ56CFjGWFyW//kgR+5Hdgk/hDD6cvtDtSJPcLyTCJ6hM9Zio7eNE4iR85YBSILDLnbSXEHAdUGV7FJUC2Yk74eTsIbVdb+yazUSphmg6XqaJMl/N6ZnRPMY2s4xyh/NEYzZCmqm5ytbNpl004jjo8ikyfVFn6CW5i64rGw== To: libcamera-devel@lists.libcamera.org Subject: [libcamera-devel] [PATCH v4 4/5] android: camera_device: Add a getter to get libcamera::Camera pointer 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 public member function to get the libcamera::Camera pointer associated with the CameraDevice. This will help to find the CameraDevice object in CameraHalManager when the hotplug support is extended in the Android layer. Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- src/android/camera_device.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 3e472c7..3934f19 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -58,6 +58,7 @@ public: unsigned int id() const { return id_; } camera3_device_t *camera3Device() { return &camera3Device_; } + const libcamera::Camera *camera() const { return camera_.get(); } int facing() const { return facing_; } int orientation() const { return orientation_; } From patchwork Fri Aug 21 14:46:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 9347 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 2ABF4BE174 for ; Fri, 21 Aug 2020 14:46:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EA7F960383; Fri, 21 Aug 2020 16:46:14 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="rI/Ieu4d"; dkim-atps=neutral Received: from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 231CD626D7 for ; Fri, 21 Aug 2020 16:46:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uajain.com; h=from:subject:in-reply-to:references:mime-version:to:cc: content-transfer-encoding:content-type; s=s1; bh=0AdfjBzBFre9Ibpo4A+kfyu1klkpE4cHPVynmjrcXjo=; b=rI/Ieu4dQgjfgQevJQ6Fq8wwNBr3/JZXLg/BozhhkYz2VFLi739X0oEtDo9Z+cIoG6vZ teY+Je+kaHa2oVRUTWggS+yGEB7de/M6zA75CFkVORt9Rzn4RIGcUlPNrenfKDQahxrfU6 DUwaZ9Rbl6/w89ouw3+0vK/SXpOhZVt0s= Received: by filterdrecv-p3iad2-86945d9569-cz9wf with SMTP id filterdrecv-p3iad2-86945d9569-cz9wf-18-5F3FDE32-C5 2020-08-21 14:46:11.060935757 +0000 UTC m=+74587.077069693 Received: from mail.uajain.com (unknown) by ismtpd0007p1hnd1.sendgrid.net (SG) with ESMTP id 89T6A6PJTiGTRywuMDMDWA for ; Fri, 21 Aug 2020 14:46:10.447 +0000 (UTC) From: Umang Jain Date: Fri, 21 Aug 2020 14:46:11 +0000 (UTC) Message-Id: <20200821144601.67860-6-email@uajain.com> In-Reply-To: <20200821144601.67860-1-email@uajain.com> References: <20200821144601.67860-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcZj5z9XHfwy1Ge6f/0y1LY07/N75Zl1ysKi4mEXbg6WV4jCL7dIPckLBUks/kUjN5rAxMv79xCi16yU8xvJF0mzkJf2ML0gENu9lG4ytDHtXtJo/tPDtMz9VgWGMyHJx3vtlIbMDKKchZlQLWVxHI9vxlnlCJDRj6Z1bb5FYWbkU9lm0NDinf3FyNbVMPninubISppzLia+CFKkCw24XDyQ== To: libcamera-devel@lists.libcamera.org Subject: [libcamera-devel] [PATCH v4 5/5] android: camera_hal_manager: Support camera hotplug 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" Extend the support for camera hotplug from libcamera's CameraManager to CameraHalManager. Use camera module callbacks to let the framework know about the hotplug events and change the status of cameras being hotplugged or unplugged via camera_device_status_change(). Introduce a map camerasMap_ which book-keeps all cameras seen in the past by the CameraHalManager. If the camera is seen for the first time, a new id is assigned to it. If the camera has been seen before by the manager, its old id is reused. IDs for internal cameras start with '0' and for external cameras, they start with '1000'. Accesses to camerasMap_ and cameras_ are protected by a mutex. Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart --- src/android/camera_hal_manager.cpp | 171 +++++++++++++++++++++++++---- src/android/camera_hal_manager.h | 20 ++++ 2 files changed, 168 insertions(+), 23 deletions(-) diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp index 3a744af..4b32c4f 100644 --- a/src/android/camera_hal_manager.cpp +++ b/src/android/camera_hal_manager.cpp @@ -8,6 +8,7 @@ #include "camera_hal_manager.h" #include +#include #include "libcamera/internal/log.h" @@ -28,7 +29,7 @@ LOG_DECLARE_CATEGORY(HAL); */ CameraHalManager::CameraHalManager() - : cameraManager_(nullptr) + : cameraManager_(nullptr), numInternalCameras_(0), nextExternalCameraId_(1000) { } @@ -47,6 +48,10 @@ int CameraHalManager::init() { cameraManager_ = new CameraManager(); + /* Support camera hotplug. */ + cameraManager_->cameraAdded.connect(this, &CameraHalManager::cameraAdded); + cameraManager_->cameraRemoved.connect(this, &CameraHalManager::cameraRemoved); + int ret = cameraManager_->start(); if (ret) { LOG(HAL, Error) << "Failed to start camera manager: " @@ -56,35 +61,22 @@ int CameraHalManager::init() return ret; } - /* - * For each Camera registered in the system, a CameraDevice - * gets created here to wraps a libcamera Camera instance. - * - * \todo Support camera hotplug. - */ - unsigned int index = 0; - for (auto &cam : cameraManager_->cameras()) { - std::shared_ptr camera = CameraDevice::create(index, cam); - ret = camera->initialize(); - if (ret) - continue; - - cameras_.emplace_back(std::move(camera)); - ++index; - } - return 0; } CameraDevice *CameraHalManager::open(unsigned int id, const hw_module_t *hardwareModule) { - if (id >= numCameras()) { + MutexLocker locker(mutex_); + + auto iter = cameraDeviceFromHALId(id); + if (iter == cameras_.end()) { LOG(HAL, Error) << "Invalid camera id '" << id << "'"; return nullptr; } - CameraDevice *camera = cameras_[id].get(); + CameraDevice *camera = iter->get(); + if (camera->open(hardwareModule)) return nullptr; @@ -93,9 +85,118 @@ CameraDevice *CameraHalManager::open(unsigned int id, return camera; } +void CameraHalManager::cameraAdded(std::shared_ptr cam) +{ + unsigned int id; + bool isCameraExternal = false; + bool isCameraNew = false; + + MutexLocker locker(mutex_); + + /* + * Each camera is assigned a unique integer ID when it is seen for the + * first time. If the camera has been seen before, the previous ID is + * re-used. + * + * IDs starts from '0' for internal cameras and '1000' for external + * cameras. + */ + auto iter = cameraIdsMap_.find(cam->id()); + if (iter != cameraIdsMap_.end()) { + id = iter->second; + } else { + isCameraNew = true; + + /* + * Now check if this is an external camera and assign + * its id accordingly. + */ + if (cameraLocation(cam.get()) == properties::CameraLocationExternal) { + isCameraExternal = true; + id = nextExternalCameraId_; + } else { + id = numInternalCameras_; + } + } + + /* Create a CameraDevice instance to wrap the libcamera Camera. */ + std::shared_ptr camera = CameraDevice::create(id, std::move(cam)); + int ret = camera->initialize(); + if (ret) { + LOG(HAL, Error) << "Failed to initialize camera: " << cam->id(); + return; + } + + if (isCameraNew) { + cameraIdsMap_.emplace(cam->id(), id); + + if (isCameraExternal) + nextExternalCameraId_++; + else + numInternalCameras_++; + } + + cameras_.emplace_back(std::move(camera)); + + if (callbacks_) + callbacks_->camera_device_status_change(callbacks_, id, + CAMERA_DEVICE_STATUS_PRESENT); + + LOG(HAL, Debug) << "Camera ID: " << id << " added successfully."; +} + +void CameraHalManager::cameraRemoved(std::shared_ptr cam) +{ + MutexLocker locker(mutex_); + + auto iter = cameraDeviceFromCamera(cam.get()); + if (iter == cameras_.end()) + return; + + /* CAMERA_DEVICE_STATUS_NOT_PRESENT should be set for external cameras only. */ + unsigned int id = (*iter)->id(); + if (id >= 1000) + callbacks_->camera_device_status_change(callbacks_, id, + CAMERA_DEVICE_STATUS_NOT_PRESENT); + + /* + * \todo Check if the camera is already open and running. + * Inform the framework about its absence before deleting its + * reference here. + */ + cameras_.erase(iter); + + LOG(HAL, Debug) << "Camera ID: " << id << " removed successfully."; +} + +int32_t CameraHalManager::cameraLocation(const Camera *cam) +{ + const ControlList &properties = cam->properties(); + if (!properties.contains(properties::Location)) + return -1; + + return properties.get(properties::Location); +} + +CameraHalManager::cameraDeviceIter CameraHalManager::cameraDeviceFromHALId(unsigned int id) +{ + return std::find_if(cameras_.begin(), cameras_.end(), + [id](std::shared_ptr &camera) { + return camera->id() == id; + }); +} + +CameraHalManager::cameraDeviceIter CameraHalManager::cameraDeviceFromCamera(Camera *cam) +{ + return std::find_if(cameras_.begin(), cameras_.end(), + [cam](std::shared_ptr &camera) { + return cam == camera->camera(); + }); +} + unsigned int CameraHalManager::numCameras() const { - return cameraManager_->cameras().size(); + return numInternalCameras_; } int CameraHalManager::getCameraInfo(unsigned int id, struct camera_info *info) @@ -103,12 +204,15 @@ int CameraHalManager::getCameraInfo(unsigned int id, struct camera_info *info) if (!info) return -EINVAL; - if (id >= numCameras()) { + MutexLocker locker(mutex_); + + auto iter = cameraDeviceFromHALId(id); + if (iter == cameras_.end()) { LOG(HAL, Error) << "Invalid camera id '" << id << "'"; return -EINVAL; } - CameraDevice *camera = cameras_[id].get(); + CameraDevice *camera = iter->get(); info->facing = camera->facing(); info->orientation = camera->orientation(); @@ -124,4 +228,25 @@ int CameraHalManager::getCameraInfo(unsigned int id, struct camera_info *info) void CameraHalManager::setCallbacks(const camera_module_callbacks_t *callbacks) { callbacks_ = callbacks; + + MutexLocker locker(mutex_); + + /* + * Some external cameras may have been identified before the + * callbacks_ were set. Iterate all existing external cameras + * and mark them as CAMERA_DEVICE_STATUS_PRESENT explicitly. + * + * Internal cameras are already assumed to be present at module + * load time by the Android framework. + */ + for (std::shared_ptr &camera : cameras_) { + const Camera *cam = camera->camera(); + unsigned int id = camera->id(); + if (id < 1000) + continue; + + if (cameraLocation(cam) == properties::CameraLocationExternal) + callbacks_->camera_device_status_change(callbacks_, id, + CAMERA_DEVICE_STATUS_PRESENT); + } } diff --git a/src/android/camera_hal_manager.h b/src/android/camera_hal_manager.h index 3e34d63..3fecaa5 100644 --- a/src/android/camera_hal_manager.h +++ b/src/android/camera_hal_manager.h @@ -7,6 +7,8 @@ #ifndef __ANDROID_CAMERA_MANAGER_H__ #define __ANDROID_CAMERA_MANAGER_H__ +#include +#include #include #include @@ -18,12 +20,17 @@ class CameraDevice; +using Mutex = std::mutex; +using MutexLocker = std::unique_lock; + class CameraHalManager { public: CameraHalManager(); ~CameraHalManager(); + using cameraDeviceIter = std::vector>::iterator; + int init(); CameraDevice *open(unsigned int id, const hw_module_t *module); @@ -33,10 +40,23 @@ public: void setCallbacks(const camera_module_callbacks_t *callbacks); private: + static int32_t cameraLocation(const libcamera::Camera *cam); + + void cameraAdded(std::shared_ptr cam); + void cameraRemoved(std::shared_ptr cam); + + cameraDeviceIter cameraDeviceFromHALId(unsigned int id); + cameraDeviceIter cameraDeviceFromCamera(libcamera::Camera *cam); + libcamera::CameraManager *cameraManager_; const camera_module_callbacks_t *callbacks_; std::vector> cameras_; + std::map cameraIdsMap_; + Mutex mutex_; + + unsigned int numInternalCameras_; + unsigned int nextExternalCameraId_; }; #endif /* __ANDROID_CAMERA_MANAGER_H__ */