From patchwork Thu Apr 15 13:52:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 11950 X-Patchwork-Delegate: jacopo@jmondi.org 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 ED21FBD22F for ; Thu, 15 Apr 2021 13:51:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AA1376881C; Thu, 15 Apr 2021 15:51:39 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0CBED605AE for ; Thu, 15 Apr 2021 15:51:38 +0200 (CEST) Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id CD49D24000A for ; Thu, 15 Apr 2021 13:51:37 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 15 Apr 2021 15:52:09 +0200 Message-Id: <20210415135213.94511-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210415135213.94511-1-jacopo@jmondi.org> References: <20210415135213.94511-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v6 1/5] libcamera: List dependency for Android Camera3 HAL 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 to the README.rst file the list of depdendencies for the Android Camera3 HAL. Reviewed-by: Hirokazu Honda Reviewed-by: Laurent Pinchart Reviewed-by: Paul Elder Signed-off-by: Jacopo Mondi --- README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.rst b/README.rst index 391c7a5f5e8f..c77e54b48b7a 100644 --- a/README.rst +++ b/README.rst @@ -87,6 +87,9 @@ for qcam: [optional] for tracing with lttng: [optional] liblttng-ust-dev python3-jinja2 lttng-tools +for android: [optional] + libexif libjpeg + Using GStreamer plugin ~~~~~~~~~~~~~~~~~~~~~~ From patchwork Thu Apr 15 13:52:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 11951 X-Patchwork-Delegate: jacopo@jmondi.org 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 E5571BD230 for ; Thu, 15 Apr 2021 13:51:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0672F68822; Thu, 15 Apr 2021 15:51:40 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E295C605AE for ; Thu, 15 Apr 2021 15:51:38 +0200 (CEST) Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id A4037240009 for ; Thu, 15 Apr 2021 13:51:38 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 15 Apr 2021 15:52:11 +0200 Message-Id: <20210415135213.94511-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210415135213.94511-1-jacopo@jmondi.org> References: <20210415135213.94511-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v6 3/5] android: Add CameraHalConfig class 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 CameraHalConfig class to the Android Camera3 HAL layer. Reviewed-by: Laurent Pinchart Reviewed-by: Hirokazu Honda Signed-off-by: Jacopo Mondi --- README.rst | 2 +- src/android/camera_hal_config.cpp | 400 ++++++++++++++++++++++++++++++ src/android/camera_hal_config.h | 40 +++ src/android/meson.build | 2 + 4 files changed, 443 insertions(+), 1 deletion(-) create mode 100644 src/android/camera_hal_config.cpp create mode 100644 src/android/camera_hal_config.h diff --git a/README.rst b/README.rst index c77e54b48b7a..fcf0f47f14c5 100644 --- a/README.rst +++ b/README.rst @@ -88,7 +88,7 @@ for tracing with lttng: [optional] liblttng-ust-dev python3-jinja2 lttng-tools for android: [optional] - libexif libjpeg + libexif libjpeg libyaml Using GStreamer plugin ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/android/camera_hal_config.cpp b/src/android/camera_hal_config.cpp new file mode 100644 index 000000000000..12d69a3f5f3c --- /dev/null +++ b/src/android/camera_hal_config.cpp @@ -0,0 +1,400 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * camera_hal_config.cpp - Camera HAL configuration file manager + */ +#include "camera_hal_config.h" + +#include +#include +#include +#include + +#include + +#include "libcamera/internal/log.h" + +using namespace libcamera; + +LOG_DEFINE_CATEGORY(HALConfig) + +class CameraHalConfig::Private : public Extensible::Private +{ + LIBCAMERA_DECLARE_PUBLIC(CameraHalConfig) + +public: + Private(CameraHalConfig *halConfig); + + int parseConfigFile(FILE *fh, std::map *cameras); + +private: + std::string parseValue(); + std::string parseKey(); + int parseValueBlock(); + int parseCameraLocation(CameraConfigData *cameraConfigData, + const std::string &location); + int parseCameraConfigData(const std::string &cameraId); + int parseCameras(); + int parseEntry(); + + yaml_parser_t parser_; + std::map *cameras_; +}; + +CameraHalConfig::Private::Private(CameraHalConfig *halConfig) + : Extensible::Private(halConfig) +{ +} + +std::string CameraHalConfig::Private::parseValue() +{ + yaml_token_t token; + + /* Make sure the token type is a value and get its content. */ + yaml_parser_scan(&parser_, &token); + if (token.type != YAML_VALUE_TOKEN) { + yaml_token_delete(&token); + return ""; + } + yaml_token_delete(&token); + + yaml_parser_scan(&parser_, &token); + if (token.type != YAML_SCALAR_TOKEN) { + yaml_token_delete(&token); + return ""; + } + + std::string value(reinterpret_cast(token.data.scalar.value), + token.data.scalar.length); + yaml_token_delete(&token); + + return value; +} + +std::string CameraHalConfig::Private::parseKey() +{ + yaml_token_t token; + + /* Make sure the token type is a key and get its value. */ + yaml_parser_scan(&parser_, &token); + if (token.type != YAML_SCALAR_TOKEN) { + yaml_token_delete(&token); + return ""; + } + + std::string value(reinterpret_cast(token.data.scalar.value), + token.data.scalar.length); + yaml_token_delete(&token); + + return value; +} + +int CameraHalConfig::Private::parseValueBlock() +{ + yaml_token_t token; + + /* Make sure the next token are VALUE and BLOCK_MAPPING_START. */ + yaml_parser_scan(&parser_, &token); + if (token.type != YAML_VALUE_TOKEN) { + yaml_token_delete(&token); + return -EINVAL; + } + yaml_token_delete(&token); + + yaml_parser_scan(&parser_, &token); + if (token.type != YAML_BLOCK_MAPPING_START_TOKEN) { + yaml_token_delete(&token); + return -EINVAL; + } + yaml_token_delete(&token); + + return 0; +} + +int CameraHalConfig::Private::parseCameraLocation(CameraConfigData *cameraConfigData, + const std::string &location) +{ + if (location == "front") + cameraConfigData->facing = CAMERA_FACING_FRONT; + else if (location == "back") + cameraConfigData->facing = CAMERA_FACING_BACK; + else if (location == "external") + cameraConfigData->facing = CAMERA_FACING_EXTERNAL; + else + return -EINVAL; + + return 0; +} + +int CameraHalConfig::Private::parseCameraConfigData(const std::string &cameraId) +{ + int ret = parseValueBlock(); + if (ret) + return ret; + + /* + * Parse the camera properties and store them in a cameraConfigData + * instance. + * + * Add a safety counter to make sure we don't loop indefinitely in case + * the configuration file is malformed. + */ + CameraConfigData cameraConfigData; + unsigned int sentinel = 100; + bool blockEnd = false; + yaml_token_t token; + + do { + yaml_parser_scan(&parser_, &token); + switch (token.type) { + case YAML_KEY_TOKEN: { + yaml_token_delete(&token); + + /* + * Parse the camera property key and make sure it is + * valid. + */ + std::string key = parseKey(); + std::string value = parseValue(); + if (key.empty() || value.empty()) + return -EINVAL; + + if (key == "location") { + ret = parseCameraLocation(&cameraConfigData, value); + if (ret) { + LOG(HALConfig, Error) + << "Unknown location: " << value; + return -EINVAL; + } + } else if (key == "rotation") { + ret = std::stoi(value); + if (ret < 0 || ret >= 360) { + LOG(HALConfig, Error) + << "Unknown rotation: " << value; + return -EINVAL; + } + cameraConfigData.rotation = ret; + } else { + LOG(HALConfig, Error) + << "Unknown key: " << key; + return -EINVAL; + } + break; + } + + case YAML_BLOCK_END_TOKEN: + blockEnd = true; + [[fallthrough]]; + default: + yaml_token_delete(&token); + break; + } + + --sentinel; + } while (!blockEnd && sentinel); + if (!sentinel) + return -EINVAL; + + (*cameras_)[cameraId] = cameraConfigData; + + return 0; +} + +int CameraHalConfig::Private::parseCameras() +{ + int ret = parseValueBlock(); + if (ret) { + LOG(HALConfig, Error) << "Configuration file is not valid"; + return ret; + } + + /* + * Parse the camera properties. + * + * Each camera properties block is a list of properties associated + * with the ID (as assembled by CameraSensor::generateId()) of the + * camera they refer to. + * + * cameras: + * "camera0 id": + * key: value + * key: value + * ... + * + * "camera1 id": + * key: value + * key: value + * ... + */ + bool blockEnd = false; + yaml_token_t token; + do { + yaml_parser_scan(&parser_, &token); + switch (token.type) { + case YAML_KEY_TOKEN: { + yaml_token_delete(&token); + + /* Parse the camera ID as key of the property list. */ + std::string cameraId = parseKey(); + if (cameraId.empty()) + return -EINVAL; + + ret = parseCameraConfigData(cameraId); + if (ret) + return -EINVAL; + break; + } + case YAML_BLOCK_END_TOKEN: + blockEnd = true; + [[fallthrough]]; + default: + yaml_token_delete(&token); + break; + } + } while (!blockEnd); + + return 0; +} + +int CameraHalConfig::Private::parseEntry() +{ + int ret = -EINVAL; + + /* + * Parse each key we find in the file. + * + * The 'cameras' keys maps to a list of (lists) of camera properties. + */ + + std::string key = parseKey(); + if (key.empty()) + return ret; + + if (key == "cameras") + ret = parseCameras(); + else + LOG(HALConfig, Error) << "Unknown key: " << key; + + return ret; +} + +int CameraHalConfig::Private::parseConfigFile(FILE *fh, + std::map *cameras) +{ + cameras_ = cameras; + + int ret = yaml_parser_initialize(&parser_); + if (!ret) { + LOG(HALConfig, Error) << "Failed to initialize yaml parser"; + return -EINVAL; + } + yaml_parser_set_input_file(&parser_, fh); + + yaml_token_t token; + yaml_parser_scan(&parser_, &token); + if (token.type != YAML_STREAM_START_TOKEN) { + LOG(HALConfig, Error) << "Configuration file is not valid"; + yaml_token_delete(&token); + yaml_parser_delete(&parser_); + return -EINVAL; + } + yaml_token_delete(&token); + + yaml_parser_scan(&parser_, &token); + if (token.type != YAML_BLOCK_MAPPING_START_TOKEN) { + LOG(HALConfig, Error) << "Configuration file is not valid"; + yaml_token_delete(&token); + yaml_parser_delete(&parser_); + return -EINVAL; + } + yaml_token_delete(&token); + + /* Parse the file and parse each single key one by one. */ + do { + yaml_parser_scan(&parser_, &token); + switch (token.type) { + case YAML_KEY_TOKEN: + yaml_token_delete(&token); + ret = parseEntry(); + break; + + case YAML_STREAM_END_TOKEN: + ret = -ENOENT; + [[fallthrough]]; + default: + yaml_token_delete(&token); + break; + } + } while (ret >= 0); + yaml_parser_delete(&parser_); + + if (ret && ret != -ENOENT) + LOG(HALConfig, Error) << "Configuration file is not valid"; + + return ret == -ENOENT ? 0 : ret; +} + +CameraHalConfig::CameraHalConfig() + : Extensible(new Private(this)), exists_(false), valid_(false) +{ + parseConfigurationFile(); +} + +/* + * Open the HAL configuration file and validate its content. + * Return 0 on success, a negative error code otherwise + * retval -ENOENT The configuration file is not available + * retval -EINVAL The configuration file is available but not valid + */ +int CameraHalConfig::parseConfigurationFile() +{ + std::filesystem::path filePath = LIBCAMERA_SYSCONF_DIR; + filePath /= "camera_hal.yaml"; + if (!std::filesystem::is_regular_file(filePath)) { + LOG(HALConfig, Debug) + << "Configuration file: \"" << filePath << "\" not found"; + return -ENOENT; + } + + FILE *fh = fopen(filePath.c_str(), "r"); + if (!fh) { + int ret = -errno; + LOG(HALConfig, Error) << "Failed to open configuration file " + << filePath << ": " << strerror(-ret); + return ret; + } + + exists_ = true; + + Private *const d = LIBCAMERA_D_PTR(); + int ret = d->parseConfigFile(fh, &cameras_); + fclose(fh); + if (ret) + return -EINVAL; + + valid_ = true; + + for (const auto &c : cameras_) { + const std::string &cameraId = c.first; + const CameraConfigData &camera = c.second; + LOG(HALConfig, Debug) << "'" << cameraId << "' " + << "(" << camera.facing << ")[" + << camera.rotation << "]"; + } + + return 0; +} + +const CameraConfigData *CameraHalConfig::cameraConfigData(const std::string &cameraId) const +{ + const auto &it = cameras_.find(cameraId); + if (it == cameras_.end()) { + LOG(HALConfig, Error) + << "Camera '" << cameraId + << "' not described in the HAL configuration file"; + return nullptr; + } + + return &it->second; +} diff --git a/src/android/camera_hal_config.h b/src/android/camera_hal_config.h new file mode 100644 index 000000000000..ef0b66f31b54 --- /dev/null +++ b/src/android/camera_hal_config.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * camera_hal_config.h - Camera HAL configuration file manager + */ +#ifndef __ANDROID_CAMERA_HAL_CONFIG_H__ +#define __ANDROID_CAMERA_HAL_CONFIG_H__ + +#include +#include +#include + +#include + +struct CameraConfigData { + int facing = -1; + int rotation = -1; +}; + +class CameraHalConfig final : public libcamera::Extensible +{ + LIBCAMERA_DECLARE_PRIVATE(CameraBuffer) + +public: + CameraHalConfig(); + + bool exists() const { return exists_; } + bool isValid() const { return valid_; } + + const CameraConfigData *cameraConfigData(const std::string &cameraId) const; + +private: + bool exists_; + bool valid_; + std::map cameras_; + + int parseConfigurationFile(); +}; +#endif /* __ANDROID_CAMERA_HAL_CONFIG_H__ */ diff --git a/src/android/meson.build b/src/android/meson.build index 2be20c97e118..3893e5b5b832 100644 --- a/src/android/meson.build +++ b/src/android/meson.build @@ -3,6 +3,7 @@ android_deps = [ dependency('libexif', required : get_option('android')), dependency('libjpeg', required : get_option('android')), + dependency('yaml-0.1', required : get_option('android')), ] android_enabled = true @@ -45,6 +46,7 @@ android_hal_sources = files([ 'camera3_hal.cpp', 'camera_hal_manager.cpp', 'camera_device.cpp', + 'camera_hal_config.cpp', 'camera_metadata.cpp', 'camera_ops.cpp', 'camera_stream.cpp', From patchwork Thu Apr 15 13:52:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 11952 X-Patchwork-Delegate: jacopo@jmondi.org 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 6AC7EBD22F for ; Thu, 15 Apr 2021 13:51:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 46B1668812; Thu, 15 Apr 2021 15:51:42 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 57F7E605AE for ; Thu, 15 Apr 2021 15:51:39 +0200 (CEST) Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 1D68024000F for ; Thu, 15 Apr 2021 13:51:38 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 15 Apr 2021 15:52:12 +0200 Message-Id: <20210415135213.94511-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210415135213.94511-1-jacopo@jmondi.org> References: <20210415135213.94511-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v6 4/5] android: camera_device: Get properties from configuration 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" Open the HAL configuration file in the Camera HAL manager and get the camera properties for each created CameraDevice and initialize it with them. Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi Reviewed-by: Hirokazu Honda --- src/android/camera_device.cpp | 56 +++++++++++++++++++++++++----- src/android/camera_device.h | 3 +- src/android/camera_hal_manager.cpp | 33 +++++++++++++++++- src/android/camera_hal_manager.h | 3 ++ 4 files changed, 85 insertions(+), 10 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 89044efa7ebe..50809c6ffbdc 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -6,6 +6,7 @@ */ #include "camera_device.h" +#include "camera_hal_config.h" #include "camera_ops.h" #include "post_processor.h" @@ -443,12 +444,25 @@ std::unique_ptr CameraDevice::create(unsigned int id, } /* - * Initialize the camera static information. + * Initialize the camera static information retrieved from the + * Camera::properties or from the cameraConfigData. + * + * cameraConfigData is optional for external camera devices and can be + * nullptr. + * * This method is called before the camera device is opened. */ -int CameraDevice::initialize() +int CameraDevice::initialize(const CameraConfigData *cameraConfigData) { - /* Initialize orientation and facing side of the camera. */ + /* + * Initialize orientation and facing side of the camera. + * + * If the libcamera::Camera provides those information as retrieved + * from firmware use them, otherwise fallback to values parsed from + * the configuration file. If the configuration file is not available + * the camera is external so its location and rotation can be safely + * defaulted. + */ const ControlList &properties = camera_->properties(); if (properties.contains(properties::Location)) { @@ -464,12 +478,22 @@ int CameraDevice::initialize() facing_ = CAMERA_FACING_EXTERNAL; break; } + + if (cameraConfigData && cameraConfigData->facing != -1 && + facing_ != cameraConfigData->facing) { + LOG(HAL, Warning) + << "Camera location does not match" + << " configuration file. Using " << facing_; + } + } else if (cameraConfigData) { + if (cameraConfigData->facing == -1) { + LOG(HAL, Error) + << "Camera facing not in configuration file"; + return -EINVAL; + } + facing_ = cameraConfigData->facing; } else { - /* - * \todo Retrieve the camera location from configuration file - * if not available from the library. - */ - facing_ = CAMERA_FACING_FRONT; + facing_ = CAMERA_FACING_EXTERNAL; } /* @@ -483,8 +507,24 @@ int CameraDevice::initialize() if (properties.contains(properties::Rotation)) { int rotation = properties.get(properties::Rotation); orientation_ = (360 - rotation) % 360; + if (cameraConfigData && cameraConfigData->rotation != -1 && + orientation_ != cameraConfigData->rotation) { + LOG(HAL, Warning) + << "Camera orientation does not match" + << " configuration file. Using " << orientation_; + } + } else if (cameraConfigData) { + if (cameraConfigData->rotation == -1) { + LOG(HAL, Error) + << "Camera rotation not in configuration file"; + return -EINVAL; + } + orientation_ = cameraConfigData->rotation; + } else { + orientation_ = 0; } + /* Acquire the camera and initialize available stream configurations. */ int ret = camera_->acquire(); if (ret) { LOG(HAL, Error) << "Failed to temporarily acquire the camera"; diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 11bdfec8d587..9cc0d4005242 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -29,6 +29,7 @@ #include "camera_worker.h" #include "jpeg/encoder.h" +struct CameraConfigData; class CameraDevice : protected libcamera::Loggable { public: @@ -36,7 +37,7 @@ public: std::shared_ptr cam); ~CameraDevice(); - int initialize(); + int initialize(const CameraConfigData *cameraConfigData); int open(const hw_module_t *hardwareModule); void close(); diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp index bf3fcda75237..f5b86974e8e3 100644 --- a/src/android/camera_hal_manager.cpp +++ b/src/android/camera_hal_manager.cpp @@ -41,6 +41,15 @@ int CameraHalManager::init() { cameraManager_ = std::make_unique(); + /* + * If the configuration file is not available the HAL only supports + * external cameras. If it exists but it's not valid then error out. + */ + if (halConfig_.exists() && !halConfig_.isValid()) { + LOG(HAL, Error) << "HAL configuration file is not valid"; + return -EINVAL; + } + /* Support camera hotplug. */ cameraManager_->cameraAdded.connect(this, &CameraHalManager::cameraAdded); cameraManager_->cameraRemoved.connect(this, &CameraHalManager::cameraRemoved); @@ -100,6 +109,8 @@ void CameraHalManager::cameraAdded(std::shared_ptr cam) auto iter = cameraIdsMap_.find(cam->id()); if (iter != cameraIdsMap_.end()) { id = iter->second; + if (id >= firstExternalCameraId_) + isCameraExternal = true; } else { isCameraNew = true; @@ -117,7 +128,27 @@ void CameraHalManager::cameraAdded(std::shared_ptr cam) /* Create a CameraDevice instance to wrap the libcamera Camera. */ std::unique_ptr camera = CameraDevice::create(id, cam); - int ret = camera->initialize(); + + /* + * The configuration file must be valid, and contain a corresponding + * entry for internal cameras. External cameras can be initialized + * without configuration file. + */ + if (!isCameraExternal && !halConfig_.exists()) { + LOG(HAL, Error) + << "HAL configuration file is mandatory for internal cameras"; + return; + } + + const CameraConfigData *cameraConfigData = halConfig_.cameraConfigData(cam->id()); + if (!isCameraExternal && !cameraConfigData) { + LOG(HAL, Error) + << "HAL configuration entry for internal camera " + << cam->id() << " is missing"; + return; + } + + int ret = camera->initialize(cameraConfigData); if (ret) { LOG(HAL, Error) << "Failed to initialize camera: " << cam->id(); return; diff --git a/src/android/camera_hal_manager.h b/src/android/camera_hal_manager.h index d9bf27989965..af1581da6579 100644 --- a/src/android/camera_hal_manager.h +++ b/src/android/camera_hal_manager.h @@ -19,6 +19,8 @@ #include +#include "camera_hal_config.h" + class CameraDevice; class CameraHalManager @@ -50,6 +52,7 @@ private: CameraDevice *cameraDeviceFromHalId(unsigned int id); std::unique_ptr cameraManager_; + CameraHalConfig halConfig_; const camera_module_callbacks_t *callbacks_; std::vector> cameras_; From patchwork Thu Apr 15 13:52:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 11953 X-Patchwork-Delegate: jacopo@jmondi.org 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 B6BC7BD231 for ; Thu, 15 Apr 2021 13:51:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0C1B868818; Thu, 15 Apr 2021 15:51:43 +0200 (CEST) Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EADDD68820 for ; Thu, 15 Apr 2021 15:51:39 +0200 (CEST) Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) (Authenticated sender: jacopo@jmondi.org) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 836CF240009 for ; Thu, 15 Apr 2021 13:51:39 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 15 Apr 2021 15:52:13 +0200 Message-Id: <20210415135213.94511-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210415135213.94511-1-jacopo@jmondi.org> References: <20210415135213.94511-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v6 5/5] android: soraka: Add camera HAL configuration 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 camera HAL configuration file for IPU3 Soraka. Reviewed-by: Laurent Pinchart Reviewed-by: Hirokazu Honda Signed-off-by: Jacopo Mondi --- src/android/data/soraka/camera_hal.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/android/data/soraka/camera_hal.yaml diff --git a/src/android/data/soraka/camera_hal.yaml b/src/android/data/soraka/camera_hal.yaml new file mode 100644 index 000000000000..2e9964035098 --- /dev/null +++ b/src/android/data/soraka/camera_hal.yaml @@ -0,0 +1,8 @@ +cameras: + "\\_SB_.PCI0.I2C4.CAM1": + location: front + rotation: 0 + + "\\_SB_.PCI0.I2C2.CAM0": + location: back + rotation: 0