From patchwork Wed Mar 24 11:25:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 11685 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 26578C32E7 for ; Wed, 24 Mar 2021 11:25:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E406168D68; Wed, 24 Mar 2021 12:25:11 +0100 (CET) Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 935EA602E3 for ; Wed, 24 Mar 2021 12:25:10 +0100 (CET) X-Originating-IP: 82.63.7.72 Received: from uno.homenet.telecomitalia.it (host-82-63-7-72.business.telecomitalia.it [82.63.7.72]) (Authenticated sender: jacopo@jmondi.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id E5BD224000C; Wed, 24 Mar 2021 11:25:06 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 24 Mar 2021 12:25:21 +0100 Message-Id: <20210324112527.63701-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210324112527.63701-1-jacopo@jmondi.org> References: <20210324112527.63701-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/7] 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. Signed-off-by: Jacopo Mondi Reviewed-by: Hirokazu Honda Reviewed-by: Laurent Pinchart Reviewed-by: Paul Elder --- README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.rst b/README.rst index 1427c7143fa6..28c33871140a 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 Camera3 HAL: [optional] + libexif libjpeg + Using GStreamer plugin ~~~~~~~~~~~~~~~~~~~~~~ From patchwork Wed Mar 24 11:25:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 11686 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 68CC8C32E7 for ; Wed, 24 Mar 2021 11:25:16 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 31D3D68D5E; Wed, 24 Mar 2021 12:25:16 +0100 (CET) Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 85D64602E3 for ; Wed, 24 Mar 2021 12:25:14 +0100 (CET) X-Originating-IP: 82.63.7.72 Received: from uno.homenet.telecomitalia.it (host-82-63-7-72.business.telecomitalia.it [82.63.7.72]) (Authenticated sender: jacopo@jmondi.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id 98A1224000E; Wed, 24 Mar 2021 11:25:11 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 24 Mar 2021 12:25:22 +0100 Message-Id: <20210324112527.63701-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210324112527.63701-1-jacopo@jmondi.org> References: <20210324112527.63701-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/7] libcamera: android: Add libyaml dependency 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 dependency to the libyaml library. The pkg-config symbol is named yaml-0.1 Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- README.rst | 2 +- src/android/meson.build | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 28c33871140a..1a888f86ac64 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 Camera3 HAL: [optional] - libexif libjpeg + libexif libjpeg libyaml Using GStreamer plugin ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/android/meson.build b/src/android/meson.build index 87d162c3bbea..19f94a4073f1 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 From patchwork Wed Mar 24 11:25:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 11687 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 AFF8CC32E7 for ; Wed, 24 Mar 2021 11:25:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7B23A68D70; Wed, 24 Mar 2021 12:25:21 +0100 (CET) Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F16F9602E3 for ; Wed, 24 Mar 2021 12:25:20 +0100 (CET) X-Originating-IP: 82.63.7.72 Received: from uno.homenet.telecomitalia.it (host-82-63-7-72.business.telecomitalia.it [82.63.7.72]) (Authenticated sender: jacopo@jmondi.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id DC86124000C; Wed, 24 Mar 2021 11:25:18 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 24 Mar 2021 12:25:24 +0100 Message-Id: <20210324112527.63701-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210324112527.63701-1-jacopo@jmondi.org> References: <20210324112527.63701-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/7] 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. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- src/android/camera_hal_config.cpp | 385 ++++++++++++++++++++++++++++++ src/android/camera_hal_config.h | 54 +++++ src/android/meson.build | 1 + 3 files changed, 440 insertions(+) create mode 100644 src/android/camera_hal_config.cpp create mode 100644 src/android/camera_hal_config.h diff --git a/src/android/camera_hal_config.cpp b/src/android/camera_hal_config.cpp new file mode 100644 index 000000000000..7e33dfb750ff --- /dev/null +++ b/src/android/camera_hal_config.cpp @@ -0,0 +1,385 @@ +/* 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 "libcamera/internal/file.h" +#include "libcamera/internal/log.h" + +using namespace libcamera; + +LOG_DEFINE_CATEGORY(HALConfig) + +const std::string CameraHalConfig::CameraBlock::toString() const +{ + std::stringstream ss; + + ss << "\'" << name << "\'" + << " model: " << model + << "(" << location << ")[" << rotation << "]"; + + return ss.str(); +} + +CameraHalConfig::CameraHalConfig() +{ + if (!yaml_parser_initialize(&parser_)) + LOG(HALConfig, Error) << "Failed to initialize yaml parser"; +} + +CameraHalConfig::~CameraHalConfig() +{ + yaml_parser_delete(&parser_); +} + +/* + * Configuration files can be stored in system paths, which are identified + * through the build configuration. + * + * However, when running uninstalled - the source location takes precedence. + */ +const std::string CameraHalConfig::findFilePath(const std::string &filename) +{ + static std::array searchPaths = { + LIBCAMERA_SYSCONF_DIR, + LIBCAMERA_DATA_DIR, + }; + + if (File::exists(filename)) + return filename; + + std::string root = utils::libcameraSourcePath(); + if (!root.empty()) { + std::string configurationPath = root + "data/" + filename; + + if (File::exists(configurationPath)) + return configurationPath; + } + + for (std::string &path : searchPaths) { + std::string configurationPath = path + "/" + filename; + if (File::exists(configurationPath)) + return configurationPath; + } + + return ""; +} + +/* + * \brief Open the HAL configuration file and validate its content + * \return 0 on success, a negative error code otherwise + */ +int CameraHalConfig::open() +{ + int ret; + + const std::string configPath = "camera_hal.yaml"; + const std::string filePath = findFilePath(configPath); + if (filePath.empty()) { + LOG(HALConfig, Warning) + << "File: \"" << configPath << "\" not found"; + return -ENOENT; + } + + FILE *fh = fopen(filePath.c_str(), "r"); + if (!fh) { + ret = -errno; + LOG(HALConfig, Error) << "Failed to open file " << filePath + << ": " << strerror(-ret); + return ret; + } + + yaml_parser_set_input_file(&parser_, fh); + + LOG(HALConfig, Debug) << "Reading configuration from " << filePath; + + ret = parseConfigFile(); + fclose(fh); + if (ret) + return ret; + + LOG(HALConfig, Info) << "Device model: " << model_; + LOG(HALConfig, Info) << "Device maker: " << maker_; + for (const auto &c : cameras_) { + const CameraBlock camera = c.second; + LOG(HALConfig, Info) << camera.toString(); + } + + return 0; +} + +const std::string &CameraHalConfig::cameraLocation(const std::string &camera) const +{ + static const std::string empty(""); + const auto &it = cameras_.find(camera); + if (it == cameras_.end()) { + LOG(HALConfig, Error) + << "Camera '" << camera + << "' not described in the HAL configuration file"; + return empty; + } + + const CameraBlock &cam = it->second; + return cam.location; +} + +unsigned int CameraHalConfig::cameraRotation(const std::string &camera) const +{ + static const std::string empty(""); + const auto &it = cameras_.find(camera); + if (it == cameras_.end()) { + LOG(HALConfig, Error) + << "Camera '" << camera + << "' not described in the HAL configuration file"; + return 0; + } + + const CameraBlock &cam = it->second; + return cam.rotation; +} + +const std::string &CameraHalConfig::cameraModel(const std::string &camera) const +{ + static const std::string empty(""); + const auto &it = cameras_.find(camera); + if (it == cameras_.end()) { + LOG(HALConfig, Error) + << "Camera '" << camera + << "' not described in the HAL configuration file"; + return empty; + } + + const CameraBlock &cam = it->second; + return cam.model; +} + +std::string CameraHalConfig::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) { + LOG(HALConfig, Error) << "Configuration file is not valid"; + return ""; + } + yaml_token_delete(&token); + + yaml_parser_scan(&parser_, &token); + if (token.type != YAML_SCALAR_TOKEN) { + LOG(HALConfig, Error) << "Configuration file is not valid"; + return ""; + } + + char *scalar = reinterpret_cast(token.data.scalar.value); + std::string value(scalar, token.data.scalar.length); + yaml_token_delete(&token); + + return value; +} + +std::string CameraHalConfig::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_KEY_TOKEN) { + LOG(HALConfig, Error) << "Configuration file is not valid"; + return ""; + } + yaml_token_delete(&token); + + yaml_parser_scan(&parser_, &token); + if (token.type != YAML_SCALAR_TOKEN) { + LOG(HALConfig, Error) << "Configuration file is not valid"; + return ""; + } + + char *scalar = reinterpret_cast(token.data.scalar.value); + std::string key(scalar, token.data.scalar.length); + yaml_token_delete(&token); + + return key; +} + +int CameraHalConfig::parseCameraBlock(yaml_token_t &token) +{ + /* The 'camera' block is a VALUE token type. */ + yaml_parser_scan(&parser_, &token); + if (token.type != YAML_VALUE_TOKEN) { + LOG(HALConfig, Error) << "Configuration file is not valid"; + return -EINVAL; + } + yaml_token_delete(&token); + + /* + * Parse the content of the camera block until we have an unbalanced + * BLOCK_END_TOKEN which closes the camera block. + * + * Add a safety counter to make sure we don't loop indefinitely in case + * the configuration file is malformed. + */ + unsigned int sentinel = 100; + CameraBlock cameraBlock{}; + int blockCounter = 0; + do { + yaml_parser_scan(&parser_, &token); + switch (token.type) { + case YAML_BLOCK_ENTRY_TOKEN: + yaml_token_delete(&token); + blockCounter++; + break; + case YAML_BLOCK_END_TOKEN: + yaml_token_delete(&token); + blockCounter--; + break; + case YAML_BLOCK_MAPPING_START_TOKEN: { + yaml_token_delete(&token); + + std::string key = parseKey(token); + std::string value = parseValue(token); + if (key.empty() || value.empty()) { + LOG(HALConfig, Error) + << "Configuration file is not valid"; + return -EINVAL; + } + + /* Validate that the parsed key is valid. */ + if (key == "location") { + if (value != "front" && value != "back" && + value != "external") { + LOG(HALConfig, Error) + << "Unknown location: " << value; + return -EINVAL; + } + cameraBlock.location = value; + } else if (key == "rotation") { + cameraBlock.rotation = strtoul(value.c_str(), + NULL, 10); + if (cameraBlock.rotation < 0) { + LOG(HALConfig, Error) + << "Unknown rotation: " + << cameraBlock.rotation; + return -EINVAL; + } + } else if (key == "name") { + cameraBlock.name = value; + } else if (key == "model") { + cameraBlock.model = value; + } else { + LOG(HALConfig, Error) + << "Configuration file is not valid " + << "unknown key: " << key; + return -EINVAL; + } + break; + } + default: + yaml_token_delete(&token); + break; + } + --sentinel; + } while (blockCounter >= 0 && sentinel); + if (!sentinel) { + LOG(HALConfig, Error) << "Configuration file is not valid "; + return -EINVAL; + } + + cameras_[cameraBlock.name] = cameraBlock; + + return 0; +} + +int CameraHalConfig::parseEntryBlock(yaml_token_t &token) +{ + int ret; + + yaml_parser_scan(&parser_, &token); + if (token.type != YAML_BLOCK_MAPPING_START_TOKEN) { + LOG(HALConfig, Error) << "Configuration file is not valid"; + return -EINVAL; + } + yaml_token_delete(&token); + + std::string key = parseKey(token); + if (key.empty()) { + LOG(HALConfig, Error) << "Configuration file is not valid"; + return -EINVAL; + } + + if (key == "camera") { + yaml_token_delete(&token); + ret = parseCameraBlock(token); + if (ret) + return ret; + } else if (key == "manufacturer") { + yaml_token_delete(&token); + maker_ = parseValue(token); + if (maker_.empty()) { + LOG(HALConfig, Error) << "Configuration file is not valid"; + return -EINVAL; + } + } else if (key == "model") { + yaml_token_delete(&token); + model_ = parseValue(token); + if (model_.empty()) { + LOG(HALConfig, Error) << "Configuration file is not valid"; + return -EINVAL; + } + } else { + yaml_token_delete(&token); + LOG(HALConfig, Error) << "Unknown key " << key; + return -EINVAL; + } + + return 0; +} + +int CameraHalConfig::parseConfigFile() +{ + yaml_token_t token; + int ret; + + yaml_parser_scan(&parser_, &token); + if (token.type != YAML_STREAM_START_TOKEN) { + LOG(HALConfig, Error) << "Configuration file is not valid"; + return EINVAL; + } + yaml_token_delete(&token); + + /* + * Start parsing the content of the configuration file which + * starts as with sequence block. + */ + yaml_parser_scan(&parser_, &token); + if (token.type != YAML_BLOCK_SEQUENCE_START_TOKEN) { + LOG(HALConfig, Error) << "Configuration file is not valid"; + return -EINVAL; + } + yaml_token_delete(&token); + + /* Parse the single entry blocks. */ + do { + yaml_parser_scan(&parser_, &token); + switch (token.type) { + case YAML_BLOCK_ENTRY_TOKEN: + yaml_token_delete(&token); + ret = parseEntryBlock(token); + break; + case YAML_STREAM_END_TOKEN: + /* Resources are released after the loop exit. */ + break; + default: + /* Release resources before re-parsing. */ + yaml_token_delete(&token); + break; + } + } while (token.type != YAML_STREAM_END_TOKEN && ret >= 0); + yaml_token_delete(&token); + + return ret; +} diff --git a/src/android/camera_hal_config.h b/src/android/camera_hal_config.h new file mode 100644 index 000000000000..69d42658e90a --- /dev/null +++ b/src/android/camera_hal_config.h @@ -0,0 +1,54 @@ +/* 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 + +class CameraHalConfig +{ +public: + CameraHalConfig(); + ~CameraHalConfig(); + + int open(); + + const std::string &deviceModel() const { return model_; } + const std::string &deviceMaker() const { return maker_; } + + const std::string &cameraLocation(const std::string &camera) const; + unsigned int cameraRotation(const std::string &camera) const; + const std::string &cameraModel(const std::string &camera) const; + +private: + yaml_parser_t parser_; + + std::string model_; + std::string maker_; + class CameraBlock + { + public: + std::string name; + std::string location; + std::string model; + unsigned int rotation; + + const std::string toString() const; + }; + std::map cameras_; + + const std::string findFilePath(const std::string &filename); + std::string parseValue(yaml_token_t &token); + std::string parseKey(yaml_token_t &token); + int parseCameraBlock(yaml_token_t &token); + int parseEntryBlock(yaml_token_t &token); + int parseConfigFile(); +}; + +#endif /* __ANDROID_CAMERA_HAL_CONFIG_H__ */ diff --git a/src/android/meson.build b/src/android/meson.build index 19f94a4073f1..34e5c494a492 100644 --- a/src/android/meson.build +++ b/src/android/meson.build @@ -44,6 +44,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 Wed Mar 24 11:25:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 11688 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 26231C32E7 for ; Wed, 24 Mar 2021 11:25:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E40FB68D62; Wed, 24 Mar 2021 12:25:23 +0100 (CET) Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B1E8868D62 for ; Wed, 24 Mar 2021 12:25:22 +0100 (CET) X-Originating-IP: 82.63.7.72 Received: from uno.homenet.telecomitalia.it (host-82-63-7-72.business.telecomitalia.it [82.63.7.72]) (Authenticated sender: jacopo@jmondi.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id 58AF324000C; Wed, 24 Mar 2021 11:25:21 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 24 Mar 2021 12:25:25 +0100 Message-Id: <20210324112527.63701-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210324112527.63701-1-jacopo@jmondi.org> References: <20210324112527.63701-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 5/7] android: camera_hal_manager: Use CameraHalConfig 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" Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- src/android/camera_hal_manager.cpp | 6 +++++- src/android/camera_hal_manager.h | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp index aeff14bdc14f..a19f80edede8 100644 --- a/src/android/camera_hal_manager.cpp +++ b/src/android/camera_hal_manager.cpp @@ -47,13 +47,17 @@ CameraHalManager::~CameraHalManager() int CameraHalManager::init() { + int ret = halConfig_.open(); + if (ret) + return ret; + cameraManager_ = new CameraManager(); /* Support camera hotplug. */ cameraManager_->cameraAdded.connect(this, &CameraHalManager::cameraAdded); cameraManager_->cameraRemoved.connect(this, &CameraHalManager::cameraRemoved); - int ret = cameraManager_->start(); + ret = cameraManager_->start(); if (ret) { LOG(HAL, Error) << "Failed to start camera manager: " << strerror(-ret); diff --git a/src/android/camera_hal_manager.h b/src/android/camera_hal_manager.h index 24bf716c9f9d..cb333293a441 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); libcamera::CameraManager *cameraManager_; + CameraHalConfig halConfig_; const camera_module_callbacks_t *callbacks_; std::vector> cameras_; From patchwork Wed Mar 24 11:25:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 11689 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 69468C32E7 for ; Wed, 24 Mar 2021 11:25:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2F67668D63; Wed, 24 Mar 2021 12:25:26 +0100 (CET) Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9BEDD602E3 for ; Wed, 24 Mar 2021 12:25:24 +0100 (CET) X-Originating-IP: 82.63.7.72 Received: from uno.homenet.telecomitalia.it (host-82-63-7-72.business.telecomitalia.it [82.63.7.72]) (Authenticated sender: jacopo@jmondi.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id E978524000A; Wed, 24 Mar 2021 11:25:22 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 24 Mar 2021 12:25:26 +0100 Message-Id: <20210324112527.63701-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210324112527.63701-1-jacopo@jmondi.org> References: <20210324112527.63701-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 6/7] android: camera_device: Get properties from config 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" Create the CameraDevice with a reference to the HAL configuration file and use it to retrieve device and camera properties. Signed-off-by: Jacopo Mondi --- src/android/camera_device.cpp | 71 ++++++++++++++++-------------- src/android/camera_device.h | 8 +++- src/android/camera_hal_manager.cpp | 3 +- 3 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 72a89258386d..403d149e4f68 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -312,33 +312,22 @@ CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor() * back to the framework using the designated callbacks. */ -CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr &camera) - : id_(id), running_(false), camera_(camera), staticMetadata_(nullptr), - facing_(CAMERA_FACING_FRONT), orientation_(0) +CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr &camera, + CameraHalConfig &halConfig) + : id_(id), running_(false), camera_(camera), halConfig_(&halConfig), + staticMetadata_(nullptr), facing_(CAMERA_FACING_FRONT), orientation_(0) { - camera_->requestCompleted.connect(this, &CameraDevice::requestComplete); - - maker_ = "libcamera"; - model_ = "cameraModel"; - - /* \todo Support getting properties on Android */ - std::ifstream fstream("/var/cache/camera/camera.prop"); - if (!fstream.is_open()) - return; - - std::string line; - while (std::getline(fstream, line)) { - std::string::size_type delimPos = line.find("="); - if (delimPos == std::string::npos) - continue; - std::string key = line.substr(0, delimPos); - std::string val = line.substr(delimPos + 1); - - if (!key.compare("ro.product.model")) - model_ = val; - else if (!key.compare("ro.product.manufacturer")) - maker_ = val; + maker_ = halConfig_->deviceMaker(); + model_ = halConfig_->deviceModel(); + if (maker_.empty() || model_.empty()) { + maker_ = "libcamera"; + model_ = "cameraModel"; + LOG(HAL, Warning) + << "Cannot find manufacturer information. " + << "Default it to '" << maker_ << " - " << model_; } + + camera_->requestCompleted.connect(this, &CameraDevice::requestComplete); } CameraDevice::~CameraDevice() @@ -351,9 +340,10 @@ CameraDevice::~CameraDevice() } std::shared_ptr CameraDevice::create(unsigned int id, - const std::shared_ptr &cam) + const std::shared_ptr &cam, + CameraHalConfig &halConfig) { - CameraDevice *camera = new CameraDevice(id, cam); + CameraDevice *camera = new CameraDevice(id, cam, halConfig); return std::shared_ptr(camera); } @@ -380,11 +370,28 @@ int CameraDevice::initialize() break; } } else { - /* - * \todo Retrieve the camera location from configuration file - * if not available from the library. - */ - facing_ = CAMERA_FACING_FRONT; + std::string location = halConfig_->cameraLocation(camera_->id()); + if (location.empty()) { + LOG(HAL, Error) << "Location for camera " + << camera_->id() << " not reported"; + return -EINVAL; + } + + if (location == "front") { + facing_ = CAMERA_FACING_FRONT; + } else if (location == "back") { + facing_ = CAMERA_FACING_BACK; + } else if (location == "external") { + facing_ = CAMERA_FACING_EXTERNAL; + } else { + LOG(HAL, Error) << "Unsupported camera location " + << location; + return -EINVAL; + } + + LOG(HAL, Debug) + << "Camera location retrieved from configration file: " + << location; } /* diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 823d561cc295..33bfd115a703 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -24,6 +24,7 @@ #include "libcamera/internal/log.h" #include "libcamera/internal/message.h" +#include "camera_hal_config.h" #include "camera_metadata.h" #include "camera_stream.h" #include "camera_worker.h" @@ -33,7 +34,8 @@ class CameraDevice : protected libcamera::Loggable { public: static std::shared_ptr create(unsigned int id, - const std::shared_ptr &cam); + const std::shared_ptr &cam, + CameraHalConfig &halConfig); ~CameraDevice(); int initialize(); @@ -66,7 +68,8 @@ protected: std::string logPrefix() const override; private: - CameraDevice(unsigned int id, const std::shared_ptr &camera); + CameraDevice(unsigned int id, const std::shared_ptr &camera, + CameraHalConfig &halConfig); struct Camera3RequestDescriptor { Camera3RequestDescriptor(libcamera::Camera *camera, @@ -113,6 +116,7 @@ private: bool running_; std::shared_ptr camera_; std::unique_ptr config_; + CameraHalConfig *halConfig_; CameraMetadata *staticMetadata_; std::map requestTemplates_; diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp index a19f80edede8..4fb5c87e2a68 100644 --- a/src/android/camera_hal_manager.cpp +++ b/src/android/camera_hal_manager.cpp @@ -129,7 +129,8 @@ void CameraHalManager::cameraAdded(std::shared_ptr cam) } /* Create a CameraDevice instance to wrap the libcamera Camera. */ - std::shared_ptr camera = CameraDevice::create(id, std::move(cam)); + std::shared_ptr camera = CameraDevice::create(id, std::move(cam), + halConfig_); int ret = camera->initialize(); if (ret) { LOG(HAL, Error) << "Failed to initialize camera: " << cam->id(); From patchwork Wed Mar 24 11:25:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 11690 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 BB27CC32E7 for ; Wed, 24 Mar 2021 11:25:27 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8A4B968D61; Wed, 24 Mar 2021 12:25:27 +0100 (CET) Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8D8DD68D5E for ; Wed, 24 Mar 2021 12:25:26 +0100 (CET) X-Originating-IP: 82.63.7.72 Received: from uno.homenet.telecomitalia.it (host-82-63-7-72.business.telecomitalia.it [82.63.7.72]) (Authenticated sender: jacopo@jmondi.org) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id 12DE124000A; Wed, 24 Mar 2021 11:25:24 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 24 Mar 2021 12:25:27 +0100 Message-Id: <20210324112527.63701-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210324112527.63701-1-jacopo@jmondi.org> References: <20210324112527.63701-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 7/7] 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. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund --- src/android/data/soraka/camera_hal.yaml | 14 ++++++++++++++ 1 file changed, 14 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..489e601ac5d0 --- /dev/null +++ b/src/android/data/soraka/camera_hal.yaml @@ -0,0 +1,14 @@ +- manufacturer: Google +- model: Soraka + +- camera: + - name: "\\_SB_.PCI0.I2C4.CAM1" + - model: "ov5670" + - location: "front" + - rotation: 0 + +- camera: + - name: "\\_SB_.PCI0.I2C2.CAM0" + - model: "ov13858" + - location: "back" + - rotation: 0