Fix a number of spelling errors and word duplications throughout the comments within libcamera. These were picked up with spellintian. Also one capitalisation of the first word of a \return statement picked up by checkstyle.py while creating this patch. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
553 lines
13 KiB
C++
553 lines
13 KiB
C++
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
/*
|
|
* Copyright (C) 2019, Google Inc.
|
|
*
|
|
* controls.cpp - Control handling
|
|
*/
|
|
|
|
#include <libcamera/controls.h>
|
|
|
|
#include <sstream>
|
|
#include <string>
|
|
|
|
#include <libcamera/camera.h>
|
|
|
|
#include "log.h"
|
|
#include "utils.h"
|
|
|
|
/**
|
|
* \file controls.h
|
|
* \brief Describes control framework and controls supported by a camera
|
|
*/
|
|
|
|
namespace libcamera {
|
|
|
|
LOG_DEFINE_CATEGORY(Controls)
|
|
|
|
/**
|
|
* \enum ControlValueType
|
|
* \brief Define the data type of value represented by a ControlValue
|
|
* \var ControlValueNone
|
|
* Identifies an unset control value
|
|
* \var ControlValueBool
|
|
* Identifies controls storing a boolean value
|
|
* \var ControlValueInteger
|
|
* Identifies controls storing an integer value
|
|
* \var ControlValueInteger64
|
|
* Identifies controls storing a 64-bit integer value
|
|
*/
|
|
|
|
/**
|
|
* \class ControlValue
|
|
* \brief Abstract type representing the value of a control
|
|
*/
|
|
|
|
/**
|
|
* \brief Construct an empty ControlValue.
|
|
*/
|
|
ControlValue::ControlValue()
|
|
: type_(ControlValueNone)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* \brief Construct a Boolean ControlValue
|
|
* \param[in] value Boolean value to store
|
|
*/
|
|
ControlValue::ControlValue(bool value)
|
|
: type_(ControlValueBool), bool_(value)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* \brief Construct an integer ControlValue
|
|
* \param[in] value Integer value to store
|
|
*/
|
|
ControlValue::ControlValue(int value)
|
|
: type_(ControlValueInteger), integer_(value)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* \brief Construct a 64 bit integer ControlValue
|
|
* \param[in] value Integer value to store
|
|
*/
|
|
ControlValue::ControlValue(int64_t value)
|
|
: type_(ControlValueInteger64), integer64_(value)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* \fn ControlValue::type()
|
|
* \brief Retrieve the data type of the value
|
|
* \return The value data type
|
|
*/
|
|
|
|
/**
|
|
* \fn ControlValue::isNone()
|
|
* \brief Determine if the value is not initialised
|
|
* \return True if the value type is ControlValueNone, false otherwise
|
|
*/
|
|
|
|
/**
|
|
* \brief Set the value with a boolean
|
|
* \param[in] value Boolean value to store
|
|
*/
|
|
void ControlValue::set(bool value)
|
|
{
|
|
type_ = ControlValueBool;
|
|
bool_ = value;
|
|
}
|
|
|
|
/**
|
|
* \brief Set the value with an integer
|
|
* \param[in] value Integer value to store
|
|
*/
|
|
void ControlValue::set(int value)
|
|
{
|
|
type_ = ControlValueInteger;
|
|
integer_ = value;
|
|
}
|
|
|
|
/**
|
|
* \brief Set the value with a 64 bit integer
|
|
* \param[in] value 64 bit integer value to store
|
|
*/
|
|
void ControlValue::set(int64_t value)
|
|
{
|
|
type_ = ControlValueInteger64;
|
|
integer64_ = value;
|
|
}
|
|
|
|
/**
|
|
* \brief Get the boolean value
|
|
*
|
|
* The value type must be Boolean.
|
|
*
|
|
* \return The boolean value
|
|
*/
|
|
bool ControlValue::getBool() const
|
|
{
|
|
ASSERT(type_ == ControlValueBool);
|
|
|
|
return bool_;
|
|
}
|
|
|
|
/**
|
|
* \brief Get the integer value
|
|
*
|
|
* The value type must be Integer or Integer64.
|
|
*
|
|
* \return The integer value
|
|
*/
|
|
int ControlValue::getInt() const
|
|
{
|
|
ASSERT(type_ == ControlValueInteger || type_ == ControlValueInteger64);
|
|
|
|
return integer_;
|
|
}
|
|
|
|
/**
|
|
* \brief Get the 64-bit integer value
|
|
*
|
|
* The value type must be Integer or Integer64.
|
|
*
|
|
* \return The 64-bit integer value
|
|
*/
|
|
int64_t ControlValue::getInt64() const
|
|
{
|
|
ASSERT(type_ == ControlValueInteger || type_ == ControlValueInteger64);
|
|
|
|
return integer64_;
|
|
}
|
|
|
|
/**
|
|
* \brief Assemble and return a string describing the value
|
|
* \return A string describing the ControlValue
|
|
*/
|
|
std::string ControlValue::toString() const
|
|
{
|
|
switch (type_) {
|
|
case ControlValueNone:
|
|
return "<None>";
|
|
case ControlValueBool:
|
|
return bool_ ? "True" : "False";
|
|
case ControlValueInteger:
|
|
return std::to_string(integer_);
|
|
case ControlValueInteger64:
|
|
return std::to_string(integer64_);
|
|
}
|
|
|
|
return "<ValueType Error>";
|
|
}
|
|
|
|
/**
|
|
* \enum ControlId
|
|
* \brief Numerical control ID
|
|
*/
|
|
|
|
/**
|
|
* \var AwbEnable
|
|
* ControlType: Bool
|
|
*
|
|
* Enables or disables the AWB. See also \a libcamera::ControlId::ManualGain
|
|
*/
|
|
|
|
/**
|
|
* \var Brightness
|
|
* ControlType: Integer
|
|
*
|
|
* Specify a fixed brightness parameter.
|
|
*/
|
|
|
|
/**
|
|
* \var Contrast
|
|
* ControlType: Integer
|
|
*
|
|
* Specify a fixed contrast parameter.
|
|
*/
|
|
|
|
/**
|
|
* \var Saturation
|
|
* ControlType: Integer
|
|
*
|
|
* Specify a fixed saturation parameter.
|
|
*/
|
|
|
|
/**
|
|
* \var ManualExposure
|
|
* ControlType: Integer
|
|
*
|
|
* Specify a fixed exposure time in milli-seconds
|
|
*/
|
|
|
|
/**
|
|
* \var ManualGain
|
|
* ControlType: Integer
|
|
*
|
|
* Specify a fixed gain parameter
|
|
*/
|
|
|
|
/**
|
|
* \struct ControlIdentifier
|
|
* \brief Describe a ControlId with control specific constant meta-data
|
|
*
|
|
* Defines a Control with a unique ID, a name, and a type.
|
|
* This structure is used as static part of the auto-generated control
|
|
* definitions, which are generated from the ControlId documentation.
|
|
*
|
|
* \var ControlIdentifier::id
|
|
* The unique ID for a control
|
|
* \var ControlIdentifier::name
|
|
* The string representation of the control
|
|
* \var ControlIdentifier::type
|
|
* The ValueType required to represent the control value
|
|
*/
|
|
|
|
/*
|
|
* The controlTypes are automatically generated to produce a control_types.cpp
|
|
* output. This file is not for public use, and so no suitable header exists
|
|
* for this sole usage of the controlTypes reference. As such the extern is
|
|
* only defined here for use during the ControlInfo constructor and should not
|
|
* be referenced directly elsewhere.
|
|
*/
|
|
extern const std::unordered_map<ControlId, ControlIdentifier> controlTypes;
|
|
|
|
/**
|
|
* \class ControlInfo
|
|
* \brief Describe the information and capabilities of a Control
|
|
*
|
|
* The ControlInfo represents control specific meta-data which is constant on a
|
|
* per camera basis. ControlInfo classes are constructed by pipeline handlers
|
|
* to expose the controls they support and the metadata needed to utilise those
|
|
* controls.
|
|
*/
|
|
|
|
/**
|
|
* \brief Construct a ControlInfo with minimum and maximum range parameters
|
|
* \param[in] id The control ID
|
|
* \param[in] min The control minimum value
|
|
* \param[in] max The control maximum value
|
|
*/
|
|
ControlInfo::ControlInfo(ControlId id, const ControlValue &min,
|
|
const ControlValue &max)
|
|
: min_(min), max_(max)
|
|
{
|
|
auto iter = controlTypes.find(id);
|
|
if (iter == controlTypes.end()) {
|
|
LOG(Controls, Fatal) << "Attempt to create invalid ControlInfo";
|
|
return;
|
|
}
|
|
|
|
ident_ = &iter->second;
|
|
}
|
|
|
|
/**
|
|
* \fn ControlInfo::id()
|
|
* \brief Retrieve the control ID
|
|
* \return The control ID
|
|
*/
|
|
|
|
/**
|
|
* \fn ControlInfo::name()
|
|
* \brief Retrieve the control name string
|
|
* \return The control name string
|
|
*/
|
|
|
|
/**
|
|
* \fn ControlInfo::type()
|
|
* \brief Retrieve the control data type
|
|
* \return The control data type
|
|
*/
|
|
|
|
/**
|
|
* \fn ControlInfo::min()
|
|
* \brief Retrieve the minimum value of the control
|
|
* \return A ControlValue with the minimum value for the control
|
|
*/
|
|
|
|
/**
|
|
* \fn ControlInfo::max()
|
|
* \brief Retrieve the maximum value of the control
|
|
* \return A ControlValue with the maximum value for the control
|
|
*/
|
|
|
|
/**
|
|
* \brief Provide a string representation of the ControlInfo
|
|
*/
|
|
std::string ControlInfo::toString() const
|
|
{
|
|
std::stringstream ss;
|
|
|
|
ss << name() << "[" << min_.toString() << ".." << max_.toString() << "]";
|
|
|
|
return ss.str();
|
|
}
|
|
|
|
/**
|
|
* \brief Compare control information for equality
|
|
* \param[in] lhs Left-hand side control information
|
|
* \param[in] rhs Right-hand side control information
|
|
*
|
|
* Control information is compared based on the ID only, as a camera may not
|
|
* have two separate controls with the same ID.
|
|
*
|
|
* \return True if \a lhs and \a rhs are equal, false otherwise
|
|
*/
|
|
bool operator==(const ControlInfo &lhs, const ControlInfo &rhs)
|
|
{
|
|
return lhs.id() == rhs.id();
|
|
}
|
|
|
|
/**
|
|
* \brief Compare control ID and information for equality
|
|
* \param[in] lhs Left-hand side control identifier
|
|
* \param[in] rhs Right-hand side control information
|
|
*
|
|
* Control information is compared based on the ID only, as a camera may not
|
|
* have two separate controls with the same ID.
|
|
*
|
|
* \return True if \a lhs and \a rhs are equal, false otherwise
|
|
*/
|
|
bool operator==(const ControlId &lhs, const ControlInfo &rhs)
|
|
{
|
|
return lhs == rhs.id();
|
|
}
|
|
|
|
/**
|
|
* \brief Compare control information and ID for equality
|
|
* \param[in] lhs Left-hand side control information
|
|
* \param[in] rhs Right-hand side control identifier
|
|
*
|
|
* Control information is compared based on the ID only, as a camera may not
|
|
* have two separate controls with the same ID.
|
|
*
|
|
* \return True if \a lhs and \a rhs are equal, false otherwise
|
|
*/
|
|
bool operator==(const ControlInfo &lhs, const ControlId &rhs)
|
|
{
|
|
return lhs.id() == rhs;
|
|
}
|
|
|
|
/**
|
|
* \typedef ControlInfoMap
|
|
* \brief A map of ControlId to ControlInfo
|
|
*/
|
|
|
|
/**
|
|
* \class ControlList
|
|
* \brief Associate a list of ControlId with their values for a camera
|
|
*
|
|
* A ControlList wraps a map of ControlId to ControlValue and provide
|
|
* additional validation against the control information exposed by a Camera.
|
|
*
|
|
* A list is only valid for as long as the camera it refers to is valid. After
|
|
* that calling any method of the ControlList class other than its destructor
|
|
* will cause undefined behaviour.
|
|
*/
|
|
|
|
/**
|
|
* \brief Construct a ControlList with a reference to the Camera it applies on
|
|
* \param[in] camera The camera
|
|
*/
|
|
ControlList::ControlList(Camera *camera)
|
|
: camera_(camera)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* \typedef ControlList::iterator
|
|
* \brief Iterator for the controls contained within the list
|
|
*/
|
|
|
|
/**
|
|
* \typedef ControlList::const_iterator
|
|
* \brief Const iterator for the controls contained within the list
|
|
*/
|
|
|
|
/**
|
|
* \fn iterator ControlList::begin()
|
|
* \brief Retrieve an iterator to the first Control in the list
|
|
* \return An iterator to the first Control in the list
|
|
*/
|
|
|
|
/**
|
|
* \fn const_iterator ControlList::begin() const
|
|
* \brief Retrieve a const_iterator to the first Control in the list
|
|
* \return A const_iterator to the first Control in the list
|
|
*/
|
|
|
|
/**
|
|
* \fn iterator ControlList::end()
|
|
* \brief Retrieve an iterator pointing to the past-the-end control in the list
|
|
* \return An iterator to the element following the last control in the list
|
|
*/
|
|
|
|
/**
|
|
* \fn const_iterator ControlList::end() const
|
|
* \brief Retrieve a const iterator pointing to the past-the-end control in the
|
|
* list
|
|
* \return A const iterator to the element following the last control in the
|
|
* list
|
|
*/
|
|
|
|
/**
|
|
* \brief Check if the list contains a control with the specified \a id
|
|
* \param[in] id The control ID
|
|
*
|
|
* The behaviour is undefined if the control \a id is not supported by the
|
|
* camera that the ControlList refers to.
|
|
*
|
|
* \return True if the list contains a matching control, false otherwise
|
|
*/
|
|
bool ControlList::contains(ControlId id) const
|
|
{
|
|
const ControlInfoMap &controls = camera_->controls();
|
|
const auto iter = controls.find(id);
|
|
if (iter == controls.end()) {
|
|
LOG(Controls, Error)
|
|
<< "Camera " << camera_->name()
|
|
<< " does not support control " << id;
|
|
|
|
return false;
|
|
}
|
|
|
|
return controls_.find(&iter->second) != controls_.end();
|
|
}
|
|
|
|
/**
|
|
* \brief Check if the list contains a control with the specified \a info
|
|
* \param[in] info The control info
|
|
* \return True if the list contains a matching control, false otherwise
|
|
*/
|
|
bool ControlList::contains(const ControlInfo *info) const
|
|
{
|
|
return controls_.find(info) != controls_.end();
|
|
}
|
|
|
|
/**
|
|
* \fn ControlList::empty()
|
|
* \brief Identify if the list is empty
|
|
* \return True if the list does not contain any control, false otherwise
|
|
*/
|
|
|
|
/**
|
|
* \fn ControlList::size()
|
|
* \brief Retrieve the number of controls in the list
|
|
* \return The number of Control entries stored in the list
|
|
*/
|
|
|
|
/**
|
|
* \fn ControlList::clear()
|
|
* \brief Removes all controls from the list
|
|
*/
|
|
|
|
/**
|
|
* \brief Access or insert the control specified by \a id
|
|
* \param[in] id The control ID
|
|
*
|
|
* This method returns a reference to the control identified by \a id, inserting
|
|
* it in the list if the ID is not already present.
|
|
*
|
|
* The behaviour is undefined if the control \a id is not supported by the
|
|
* camera that the ControlList refers to.
|
|
*
|
|
* \return A reference to the value of the control identified by \a id
|
|
*/
|
|
ControlValue &ControlList::operator[](ControlId id)
|
|
{
|
|
const ControlInfoMap &controls = camera_->controls();
|
|
const auto iter = controls.find(id);
|
|
if (iter == controls.end()) {
|
|
LOG(Controls, Error)
|
|
<< "Camera " << camera_->name()
|
|
<< " does not support control " << id;
|
|
|
|
static ControlValue empty;
|
|
return empty;
|
|
}
|
|
|
|
return controls_[&iter->second];
|
|
}
|
|
|
|
/**
|
|
* \fn ControlList::operator[](const ControlInfo *info)
|
|
* \brief Access or insert the control specified by \a info
|
|
* \param[in] info The control info
|
|
*
|
|
* This method returns a reference to the control identified by \a info,
|
|
* inserting it in the list if the info is not already present.
|
|
*
|
|
* \return A reference to the value of the control identified by \a info
|
|
*/
|
|
|
|
/**
|
|
* \brief Update the list with a union of itself and \a other
|
|
* \param other The other list
|
|
*
|
|
* Update the control list to include all values from the \a other list.
|
|
* Elements in the list whose control IDs are contained in \a other are updated
|
|
* with the value from \a other. Elements in the \a other list that have no
|
|
* corresponding element in the list are added to the list with their value.
|
|
*
|
|
* The behaviour is undefined if the two lists refer to different Camera
|
|
* instances.
|
|
*/
|
|
void ControlList::update(const ControlList &other)
|
|
{
|
|
if (other.camera_ != camera_) {
|
|
LOG(Controls, Error)
|
|
<< "Can't update ControlList from a different camera";
|
|
return;
|
|
}
|
|
|
|
for (auto it : other) {
|
|
const ControlInfo *info = it.first;
|
|
const ControlValue &value = it.second;
|
|
|
|
controls_[info] = value;
|
|
}
|
|
}
|
|
|
|
} /* namespace libcamera */
|