From patchwork Thu Jun 6 20:56:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 1373 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4AC9F64092 for ; Thu, 6 Jun 2019 22:56:58 +0200 (CEST) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C47BB549; Thu, 6 Jun 2019 22:56:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1559854617; bh=6I1PCG8fdueE3foNeBpttwGWSJJaHxOnK9M2uP+NVxw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QhAffW+1GRlGVN8ElvtMM4BBLMDzRb/lIjUSucl6IzNrqu5l3duks1Ut9/PazAe6y +o7LGkfwhMvD8OTGOI22D7/KKVdoyfo392GzITnWUB7+3IxbmxXJLaiJxVdcJNc/i/ lMOZNWyWDiw7pt1VIm7vAuGDkALGoIMZT5knOTtI= From: Kieran Bingham To: LibCamera Devel Date: Thu, 6 Jun 2019 21:56:50 +0100 Message-Id: <20190606205654.9311-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190606205654.9311-1-kieran.bingham@ideasonboard.com> References: <20190606205654.9311-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 1/5] libcamera: Add control handling X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Jun 2019 20:56:58 -0000 --- include/libcamera/controls.h | 106 ++++++++++++ include/libcamera/meson.build | 1 + src/libcamera/controls.cpp | 310 ++++++++++++++++++++++++++++++++++ src/libcamera/meson.build | 1 + 4 files changed, 418 insertions(+) create mode 100644 include/libcamera/controls.h create mode 100644 src/libcamera/controls.cpp diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h new file mode 100644 index 000000000000..0b751aa7a9d2 --- /dev/null +++ b/include/libcamera/controls.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * controls.h - Control handling + */ +#ifndef __LIBCAMERA_CONTROLS_H__ +#define __LIBCAMERA_CONTROLS_H__ + +#include +#include + +namespace libcamera { + +enum ControlId : uint32_t { + /* IPA Controls */ + IpaAwbEnable, + + /* Manual Controls */ + ManualBrightness, + ManualExposure, + ManualGain, +}; + +enum ControlType : uint32_t { + ControlBool, + ControlInteger, + ControlString, +}; + +enum ControlAction : uint8_t { + ControlWrite = 1, + ControlRead = 2, + ControlWriteRead = 3, +}; + +class ControlValue +{ +public: + ControlValue(enum ControlType type); + ControlValue(bool value); + ControlValue(int value); + ControlValue(const char *value); + ControlValue(const std::string &value); + + ControlType type() const { return type_; }; + + bool isRead() const { return action_ == ControlRead || + action_ == ControlWriteRead; }; + bool isWrite() const { return action_ == ControlWrite || + action_ == ControlWriteRead; }; + + void set(bool value); + void set(int value); + void set(unsigned int value); + + void set(const char *value); + void set(const std::string &value); + + bool getBool() const; + int getInt() const; + std::string getString() const; + + std::string toString() const; + +private: + ControlType type_; + ControlAction action_; + + union { + bool bool_; + int integer_; + }; + std::string string_; +}; + +std::ostream &operator<<(std::ostream &stream, const ControlValue &value); + +class Control +{ +public: + /* Create a Read control */ + Control(ControlId id); + + /* Create a Write control */ + Control(ControlId id, bool value); + Control(ControlId id, int value); + + ControlId id() const { return id_; }; + ControlValue &value() { return value_; }; + + std::string toString() const; + + /* Overloaded for std::set usage */ + bool operator<(const Control &rhs) const { return id_ < rhs.id_; }; + +private: + ControlId id_; + ControlValue value_; +}; + +std::ostream &operator<<(std::ostream &stream, const Control &control); + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_CONTROLS_H__ */ diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index 1fcf6b509a1e..6a69db60b3c9 100644 --- a/include/libcamera/meson.build +++ b/include/libcamera/meson.build @@ -1,5 +1,6 @@ libcamera_api = files([ 'buffer.h', + 'controls.h', 'camera.h', 'camera_manager.h', 'event_dispatcher.h', diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp new file mode 100644 index 000000000000..bef0ddcc89a3 --- /dev/null +++ b/src/libcamera/controls.cpp @@ -0,0 +1,310 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * controls.cpp - Control handling + */ + +#include +#include + +#include + +#include "log.h" + +/** + * \file controls.h + * \brief Describes all controls supported by a camera + */ + +namespace libcamera { + +LOG_DEFINE_CATEGORY(ControlId) + +/** + * \enum Controls + * Control Identifiers + * \var IpaAwbEnable + * bool: Enables or disables the AWB + * \var ManualExposure + * Manually control the exposure time in milli-seconds + * \var ManualGain + * Controls the value of the manual gain setting + */ + +/** + * \enum ControlType + * Determines the type of value represented by a \a ControlValue + * \var ControlBool + * Identifies controls storing a boolean value + * \var ControlInteger + * Identifies controls storing an integer value + * \var ControlString + * Identifies controls storing a string value. + */ + +/** + * \enum ControlAction + * Declare the intent of the ControlValue. + * \var ControlNoop + * The ControlValue has not been given an action to perform. It can exist as + * part of the request, but will not be acted upon by the device. + * \var ControlWrite + * The ControlValue is to be given and set at the camera + * \var ControlRead + * The ControlValue is to be read from the camera + * \var ControlWriteRead + * The ControlValue should be written to the camera and read before request + * completion + */ + +/* + * Two sets of tables are generated for the control definitions. + * + * An enum to declare the ID (in controls.h), and a type to establish its + * representation. + * + * Todo: Automate the generation of both tables from a single input table. + */ +struct ControlIdentifier { + ControlId id; + const char *name; + ControlType type; +} static const ControlTypes[] = { +#define CONTROL_TYPE(_id, _type) { _id, #_id, _type } + + CONTROL_TYPE(IpaAwbEnable, ControlBool), + CONTROL_TYPE(ManualBrightness, ControlInteger), + CONTROL_TYPE(ManualExposure, ControlInteger), + CONTROL_TYPE(ManualGain, ControlInteger), + +#undef CONTROL_TYPE +}; + +static struct ControlIdentifier FindControlType(ControlId id) +{ + for (auto ident : ControlTypes) { + if (ident.id == id) + return ident; + } + + LOG(ControlId, Fatal) << "Failed to find a ControlType."; + + /* Unreachable. */ + return {}; +} + +static ControlType GetControlType(ControlId id) +{ + return FindControlType(id).type; +} + +static std::string ControlIDName(ControlId id) +{ + return FindControlType(id).name; +} + +/** + * \brief Construct a ControlValue of a given type without initialising a value + * \param[in] type The type of ControlValue to be read + */ +ControlValue::ControlValue(ControlType type) + : type_(type), action_(ControlRead) +{ +} + +/** + * \brief Construct a Boolean Control Value + * \param[in] value Boolean value to store + */ +ControlValue::ControlValue(bool value) + : type_(ControlBool), action_(ControlWrite), bool_(value) +{ +} + +/** + * \brief Construct an integer Control Value + * \param[in] value Integer value to store + */ +ControlValue::ControlValue(int value) + : type_(ControlInteger), action_(ControlWrite), integer_(value) +{ +} + +/** + * \brief Construct a string Control Value + * \param[in] value String representation to store + */ +ControlValue::ControlValue(const char *value) + : type_(ControlString), action_(ControlWrite), string_(value) +{ +} + +/** + * \brief Construct a string Control Value + * \param[in] value String representation to store + */ +ControlValue::ControlValue(const std::string &value) + : type_(ControlString), action_(ControlWrite), string_(value) +{ +} + +/** + * \brief Set the Control value with a boolean + * \param[in] value Boolean value to store + */ +void ControlValue::set(bool value) +{ + ASSERT(type_ == ControlBool); + + bool_ = value; +} + +/** + * \brief Set the Control value with an integer + * \param[in] value Integer value to store + */ +void ControlValue::set(int value) +{ + ASSERT(type_ == ControlInteger); + + integer_ = value; +} + +/** + * \brief Set the Control value with a string representation + * \param[in] value String value to store + */ +void ControlValue::set(const char *value) +{ + ASSERT(type_ == ControlString); + + string_ = value; +} + +/** + * \brief Set the Control value with a string representation + * \param[in] value String value to store + */ +void ControlValue::set(const std::string &value) +{ + ASSERT(type_ == ControlString); + + string_ = value; +} + +/** + * \brief Get the Control value. + * + * The ControlValue type must be Boolean. + */ +bool ControlValue::getBool() const +{ + ASSERT(type_ == ControlBool); + + return bool_; +} + +/** + * \brief Get the Control value. + * + * The ControlValue type must be Integer. + */ +int ControlValue::getInt() const +{ + ASSERT(type_ == ControlInteger); + + return integer_; +} + +/** + * \brief Get the Control value. + * + * The ControlValue type must be String. + */ +std::string ControlValue::getString() const +{ + ASSERT(type_ == ControlString); + + return string_; +} + +/** + * \brief Prepare a string representation of the ControlValue + */ +std::string ControlValue::toString() const +{ + switch (type_) { + case ControlBool: + return bool_ ? "True" : "False"; + case ControlInteger: + return std::to_string(integer_); + case ControlString: + return string_; + } + + /* Unreachable */ + return ""; +} + +std::ostream &operator<<(std::ostream &stream, const ControlValue &value) +{ + return stream << value.toString(); +} + + +/** + * \brief Create a new empty control + * \param[in] id ID of the new control + * + * The control is constructed, and the type determined by the \a ControlId. + */ +Control::Control(ControlId id) + : id_(id), value_(GetControlType(id)) +{ +} + +/** + * \brief Create a new control + * \param[in] id ID of the new control + * \param[in] value Boolean value to apply to the new control + * + * The control is constructed, and the type determined by the \a ControlId. + */ +Control::Control(ControlId id, bool value) + : id_(id), value_(value) +{ + ASSERT(GetControlType(id) == ControlBool); +} + +/** + * \brief Create a new control + * \param[in] id ID of the new control + * \param[in] value Integer value to apply to the new control + * + * The control is constructed, and the type determined by the \a ControlId. + */ +Control::Control(ControlId id, int value) + : id_(id), value_(value) +{ + ASSERT(GetControlType(id) == ControlInteger); +} + +/** + * \brief Prepare a string representation of the Control + */ +std::string Control::toString() const +{ + std::stringstream ss; + + ss << "Control: " << ControlIDName(id_) << " : " << value_; + + return ss.str(); +} + +std::ostream &operator<<(std::ostream &stream, const Control &control) +{ + return stream << control.toString(); +} + +} /* namespace libcamera */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index fa1fbcb5faf5..7c67fdf3691a 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -3,6 +3,7 @@ libcamera_sources = files([ 'camera.cpp', 'camera_manager.cpp', 'camera_sensor.cpp', + 'controls.cpp', 'device_enumerator.cpp', 'device_enumerator_sysfs.cpp', 'event_dispatcher.cpp',