From patchwork Mon Aug 17 20:26:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 9332 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 0A816BD87C for ; Mon, 17 Aug 2020 20:26:44 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9D78161ACF; Mon, 17 Aug 2020 22:26:42 +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="ZMxkGgPK"; 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 460E1616B1 for ; Mon, 17 Aug 2020 22:26:39 +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=ZMxkGgPKx71iSBCEPP5+WnmOf14IvfhvFcvqUjGcBdPHbGVMN34n6fibRB3/yyrl1Z3Q /u2tP9+16JTg6UA9BDbOnZk2DYBsnjePEYSlQD5KBhFBdpC9g447YeTeJ4hv5XOHlKXkL1 eq+r7NjtRBLY1LI7Dy2PuKaNbFsABJ46I= Received: by filterdrecv-p3las1-5785d94c6b-bvlsc with SMTP id filterdrecv-p3las1-5785d94c6b-bvlsc-18-5F3AE7FC-5D 2020-08-17 20:26:37.107163937 +0000 UTC m=+359830.985496349 Received: from mail.uajain.com (unknown) by ismtpd0004p1hnd1.sendgrid.net (SG) with ESMTP id LlweKJuDSfO0WtCXrc15ig Mon, 17 Aug 2020 20:26:36.758 +0000 (UTC) From: Umang Jain Date: Mon, 17 Aug 2020 20:26:37 +0000 (UTC) Message-Id: <20200817202629.4277-2-email@uajain.com> In-Reply-To: <20200817202629.4277-1-email@uajain.com> References: <20200817202629.4277-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcQ/i1ji5k4eTSSnQ1oTeZ4i1aWIanNJ7JI05Ha9PbbrgFf8kpucW9yJ2zlas7vnBB5xuFZNKxHpNRM4jDaPQToCquzxL8LZehSOkCzCCtGrVKx25DlgKo4bbaKkoH+D1GsueEkEB/bKoC08mPIlNYFsSGhIsp2jZJtcMxcXeywBJuhuI/jTjFFJcNzRYtZ/LSxnv3K1gg0lwTYYSTZvMZhw== To: libcamera-devel@lists.libcamera.org Subject: [libcamera-devel] [PATCH v3 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 Mon Aug 17 20:26:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 9334 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 555B7BD87C for ; Mon, 17 Aug 2020 20:26:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1D5B161992; Mon, 17 Aug 2020 22:26:45 +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="LMIYMhzi"; 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 F1244616B1 for ; Mon, 17 Aug 2020 22:26:40 +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=LMIYMhziUC8Rxfqbn/sR4rSHQA8/ldEiqdCnXLW0dokXYpstnn3yCPlDlQ8Omy3T1PUA v6CaV0Ch2SNCsY+qZPWNJIlM/0chQvDmOh8R6Kv1AlVX8yDdTn6kXiqPTk+Deiu+O0VnkU mBTmCuBzb75A8haOZBExmLADA/DjRy0vg= Received: by filterdrecv-p3las1-5785d94c6b-nwwmr with SMTP id filterdrecv-p3las1-5785d94c6b-nwwmr-20-5F3AE7FD-59 2020-08-17 20:26:38.073478137 +0000 UTC m=+359831.740488720 Received: from mail.uajain.com (unknown) by ismtpd0004p1maa1.sendgrid.net (SG) with ESMTP id LtHSEsxLQ92TgN7RevA2LQ Mon, 17 Aug 2020 20:26:37.250 +0000 (UTC) From: Umang Jain Date: Mon, 17 Aug 2020 20:26:38 +0000 (UTC) Message-Id: <20200817202629.4277-3-email@uajain.com> In-Reply-To: <20200817202629.4277-1-email@uajain.com> References: <20200817202629.4277-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcQ/i1ji5k4eTSSnQ1oTeZ4t6d2b9GmSo6yY9OJZQOVguTKvxACBn5rSs0UFG7sXgVj0oQCsUpQifx+/Ee/ukgGyAFfPq2xqRvPP4uVzgvxHmTaWoAwN76VrZIV9PcSkSZpjYSMW2wZwRTsWj6xGJCnW1WVvcRMC+0OnsSCaHuVe4XtMk2gIJAd2xwEim/85nDI3LhGorlyWcelSQcizuwUw== To: libcamera-devel@lists.libcamera.org Subject: [libcamera-devel] [PATCH v3 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 Mon Aug 17 20:26:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 9333 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 7819EBD87F for ; Mon, 17 Aug 2020 20:26:44 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6B94A619C0; Mon, 17 Aug 2020 22:26:43 +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="cp50GDrd"; 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 67C0661815 for ; Mon, 17 Aug 2020 22:26:40 +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=FXhILTUfxT0BFUBPIZ20p2fiVt6QYftLfIfgckevdHQ=; b=cp50GDrdPf/uPB/JhjKak/q57OCcTZtsnRSjvBc6C2c1Iz9LOGLa+G9ftWYEdNMT+/em +UvPmZNJIoiu/OR9Us6L5JFHu8IftSXKB3KxrsE+KVPWybLMgf2gSTQYSxRF15ORYxHqYD viEXlVw8buii8rTFiNjm19C+ZzbRkJNAc= Received: by filterdrecv-p3iad2-5c98798b7-zrzkk with SMTP id filterdrecv-p3iad2-5c98798b7-zrzkk-19-5F3AE7FE-53 2020-08-17 20:26:38.938016394 +0000 UTC m=+359824.402835252 Received: from mail.uajain.com (unknown) by ismtpd0002p1maa1.sendgrid.net (SG) with ESMTP id H_tfatOXSeKXc3rObZtlkw for ; Mon, 17 Aug 2020 20:26:38.202 +0000 (UTC) From: Umang Jain Date: Mon, 17 Aug 2020 20:26:39 +0000 (UTC) Message-Id: <20200817202629.4277-4-email@uajain.com> In-Reply-To: <20200817202629.4277-1-email@uajain.com> References: <20200817202629.4277-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcBLpXFhl3+P87RHKL8hWvbIAmAXRqUBwWps8sj3eeReFPzR4KyTXBMlaA8eMkSd1eF+xxDt70e6FDslqNdafPQle2hNeTap9WDXERFDRrTQHe9ZQ3W8ayVcVSPZrRuDnpzjP4zHPlXEeXS96hdv25e1FXEG7TOI0TIUcQjCLmzL+h6menKj1manAhsAj4miaabBfNo0kAvJoHXwVuhOcYZA== To: libcamera-devel@lists.libcamera.org Subject: [libcamera-devel] [PATCH v3 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 | 15 +++++++++++++++ src/android/camera_device.h | 7 +++++-- src/android/camera_hal_manager.cpp | 4 ++-- src/android/camera_hal_manager.h | 2 +- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index d918350..a79bb69 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -233,6 +233,21 @@ CameraDevice::~CameraDevice() delete it.second; } +std::shared_ptr CameraDevice::create(unsigned int id, + const std::shared_ptr &cam) +{ + struct Deleter : std::default_delete { + void operator()(CameraDevice *camera) + { + delete camera; + } + }; + + CameraDevice *camera = new CameraDevice(id, cam); + + return std::shared_ptr(camera, Deleter()); +} + /* * 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..b149043 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -47,8 +47,8 @@ struct CameraStream { class CameraDevice : protected libcamera::Loggable { public: - CameraDevice(unsigned int id, const std::shared_ptr &camera); - ~CameraDevice(); + static std::shared_ptr create(unsigned int id, + const std::shared_ptr &cam); int initialize(); @@ -72,6 +72,9 @@ protected: std::string logPrefix() const override; private: + CameraDevice(unsigned int id, const std::shared_ptr &camera); + ~CameraDevice(); + 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 Mon Aug 17 20:26:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 9335 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 B9D17BD87F for ; Mon, 17 Aug 2020 20:26:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7C9E661AC0; Mon, 17 Aug 2020 22:26:45 +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="s8bJ01pV"; 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 7934860384 for ; Mon, 17 Aug 2020 22:26:41 +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=cIVNxcy+fK6YvXjgadEN8IFcTyvhDnKtXbKusmkI7k8=; b=s8bJ01pVqkiQ0yP+orcOowLsgJjmD6V6GyPwW8f4NabEIlar6RyzzVYYN5sUuU5Iw9CE 8wpiAwXeZuki3mGYrY41krC5y59saDGp5YXay8nr3AL/tKeTAD1lObjdFmlaUlLWSYfa8o aJMC7oTp43tEFlxAQQPRZqEHp6tg107hA= Received: by filterdrecv-p3iad2-5c98798b7-lvbn8 with SMTP id filterdrecv-p3iad2-5c98798b7-lvbn8-19-5F3AE7FF-74 2020-08-17 20:26:40.122843818 +0000 UTC m=+359830.605448517 Received: from mail.uajain.com (unknown) by ismtpd0007p1hnd1.sendgrid.net (SG) with ESMTP id MapXxGhwR6qQ-bIEPbv7MA for ; Mon, 17 Aug 2020 20:26:39.777 +0000 (UTC) From: Umang Jain Date: Mon, 17 Aug 2020 20:26:40 +0000 (UTC) Message-Id: <20200817202629.4277-5-email@uajain.com> In-Reply-To: <20200817202629.4277-1-email@uajain.com> References: <20200817202629.4277-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPc+mYHlj5pFD2lBxsaGLVsOL1TgK5daouuYLtNg7G7Lv529LYZX0a3OuNg7qZxgv5icBNmqAUfRPAuftyRKSUtqeSoQMzh8fg72eG6PSgV9daRPgWrZJWO28TCd/UHghOfZ2DUfkc8l/OuPrYh6FbWewiU4EksKdQZmv4TPdVLnkp9dKmyZOoGi8MxvlYC3hLMiba0RnC605MvqQ8ldMlxMw== To: libcamera-devel@lists.libcamera.org Subject: [libcamera-devel] [PATCH v3 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 b149043..7908bc0 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -57,6 +57,7 @@ public: unsigned int id() const { return id_; } camera3_device_t *camera3Device() { return &camera3Device_; } + const libcamera::Camera *camera() { return camera_.get(); } int facing() const { return facing_; } int orientation() const { return orientation_; } From patchwork Mon Aug 17 20:26:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 9336 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 378D6BD87C for ; Mon, 17 Aug 2020 20:26:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DD5A361AEF; Mon, 17 Aug 2020 22:26:45 +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="HFdTLvng"; 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 F2FBD61AC0 for ; Mon, 17 Aug 2020 22:26:41 +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=yiHFIpZQ4kL+dL6weigacL2kbn4cA/MFi6/Usily6/U=; b=HFdTLvngPllYZl/Yw2DwArTltxsN/PjdQY2/59FDspXr6TopAbF8YEl/jBdKkg05TwCK w0i9DYfCM4879d/V9ugEdQVofs9sZX6jlOUqq5ARkw060xq8HqKhKKEaOU8S+pnRLEba8H FkgLmHWl6i+H8Yse/RWxd7zRaJEz+ge/w= Received: by filterdrecv-p3iad2-5c98798b7-shmb5 with SMTP id filterdrecv-p3iad2-5c98798b7-shmb5-18-5F3AE800-6E 2020-08-17 20:26:40.882614427 +0000 UTC m=+359831.957013569 Received: from mail.uajain.com (unknown) by ismtpd0008p1maa1.sendgrid.net (SG) with ESMTP id 85Lhv3GpRk6n0ciau08yBQ for ; Mon, 17 Aug 2020 20:26:40.078 +0000 (UTC) From: Umang Jain Date: Mon, 17 Aug 2020 20:26:40 +0000 (UTC) Message-Id: <20200817202629.4277-6-email@uajain.com> In-Reply-To: <20200817202629.4277-1-email@uajain.com> References: <20200817202629.4277-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcZj5z9XHfwy1Ge6f/0y1LYwCA/v9XUm1JqRF7ylVeh12n0FwBW8t59CcHJhPITUZXGGGQgUqnsqxj5v/XY65EzXbreL7hK/T92NfH2u0fNm0haQKhw+/XWpW9t8Dqvtln933X7hTQVJuuGGIxxCDhYr+kt0hpLcQVsLlUKj8JSnHX9zVnqGmLm6g+AH9TvPfVcBDra35Xbbr7xiA0TowW4g== To: libcamera-devel@lists.libcamera.org Subject: [libcamera-devel] [PATCH v3 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 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, it's old id is reused. IDs for internal cameras start with '0' and for external cameras, they start with '1000'. Note, for the current implementation, we assume all UVC cameras are external cameras. Also, acess to camerasMap_ and cameras_ are protected by a mutex. Signed-off-by: Umang Jain --- src/android/camera_hal_manager.cpp | 174 +++++++++++++++++++++++++---- src/android/camera_hal_manager.h | 18 +++ 2 files changed, 170 insertions(+), 22 deletions(-) diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp index 3a744af..e851185 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" @@ -35,6 +36,7 @@ CameraHalManager::CameraHalManager() CameraHalManager::~CameraHalManager() { cameras_.clear(); + camerasMap_.clear(); if (cameraManager_) { cameraManager_->stop(); @@ -47,6 +49,13 @@ int CameraHalManager::init() { cameraManager_ = new CameraManager(); + /* Support camera hotplug. */ + cameraManager_->cameraAdded.connect(this, &CameraHalManager::cameraAdded); + cameraManager_->cameraRemoved.connect(this, &CameraHalManager::cameraRemoved); + + internalCameras_ = 0; + externalCameras_ = 1000; + int ret = cameraManager_->start(); if (ret) { LOG(HAL, Error) << "Failed to start camera manager: " @@ -56,35 +65,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 = cameraIterFromId(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 +89,114 @@ 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 and the camera is marked as CAMERA_DEVICE_STATUS_PRESENT + * subsequently. + * + * IDs starts from '0' for internal cameras and '1000' for external + * cameras. + */ + auto iter = camerasMap_.find(cam->id()); + if (iter != camerasMap_.end()) { + id = iter->second; + } else { + isCameraNew = true; + + /* + * Now check if this is an external camera and assign + * its id accordingly. + */ + const ControlList &properties = cam->properties(); + if (properties.contains(properties::Location) && + properties.get(properties::Location) == + properties::CameraLocationExternal) { + isCameraExternal = true; + id = externalCameras_; + } else { + id = internalCameras_; + } + } + + /* + * For each Camera registered in the system, a CameraDevice + * gets created here to wraps a libcamera Camera instance. + */ + 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) { + camerasMap_.emplace(cam->id(), id); + + if (isCameraExternal) + externalCameras_++; + else + internalCameras_++; + } + + 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 = cameraIterFromCamera(cam.get()); + if (iter == cameras_.end()) + return; + + unsigned int id = (*iter)->id(); + 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 it's absence before deleting it's + * reference here. + */ + cameras_.erase(iter); + + LOG(HAL, Debug) << "Camera ID: " << id << " removed successfully."; +} + +CameraHalManager::cameraDeviceIter CameraHalManager::cameraIterFromId(unsigned int id) +{ + return std::find_if(cameras_.begin(), cameras_.end(), + [id](std::shared_ptr &camera) { + return camera->id() == id; + }); +} + +CameraHalManager::cameraDeviceIter CameraHalManager::cameraIterFromCamera(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 internalCameras_; } 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 = cameraIterFromId(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,30 @@ 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 enabled. Iterate any 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 (auto &cam : cameraManager_->cameras()) { + auto iter = camerasMap_.find(cam->id()); + if (iter == camerasMap_.end()) + continue; + + unsigned int id = iter->second; + const ControlList &properties = cam->properties(); + if (properties.contains(properties::Location) && + properties.get(properties::Location) & + 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..f8adade 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,21 @@ public: void setCallbacks(const camera_module_callbacks_t *callbacks); private: + void cameraAdded(std::shared_ptr cam); + void cameraRemoved(std::shared_ptr cam); + + cameraDeviceIter cameraIterFromId(unsigned int id); + cameraDeviceIter cameraIterFromCamera(libcamera::Camera *cam); + libcamera::CameraManager *cameraManager_; const camera_module_callbacks_t *callbacks_; std::vector> cameras_; + std::map camerasMap_; + Mutex mutex_; + + unsigned int internalCameras_; + unsigned int externalCameras_; }; #endif /* __ANDROID_CAMERA_MANAGER_H__ */