summaryrefslogtreecommitdiff
path: root/src/libcamera/controls.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcamera/controls.cpp')
-rw-r--r--src/libcamera/controls.cpp318
1 files changed, 159 insertions, 159 deletions
diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp
index 295ccd55..a34af588 100644
--- a/src/libcamera/controls.cpp
+++ b/src/libcamera/controls.cpp
@@ -18,6 +18,29 @@
/**
* \file controls.h
* \brief Describes control framework and controls supported by a camera
+ *
+ * A control is a mean to govern or influence the operation of a camera. Every
+ * control is defined by a unique numerical ID, a name string and the data type
+ * of the value it stores. The libcamera API defines a set of standard controls
+ * in the libcamera::controls namespace, as a set of instances of the Control
+ * class.
+ *
+ * The main way for applications to interact with controls is through the
+ * ControlList stored in the Request class:
+ *
+ * \code{.cpp}
+ * Request *req = ...;
+ * ControlList &controls = req->controls();
+ * controls->set(controls::AwbEnable, false);
+ * controls->set(controls::ManualExposure, 1000);
+ *
+ * ...
+ *
+ * int32_t exposure = controls->get(controls::ManualExposure);
+ * \endcode
+ *
+ * The ControlList::get() and ControlList::set() methods automatically deduce
+ * the data type based on the control.
*/
namespace libcamera {
@@ -173,76 +196,120 @@ std::string ControlValue::toString() const
}
/**
- * \enum ControlId
- * \brief Numerical control ID
+ * \class ControlId
+ * \brief Control static metadata
+ *
+ * The ControlId class stores a control ID, name and data type. It provides
+ * unique identification of a control, but without support for compile-time
+ * type deduction that the derived template Control class supports. See the
+ * Control class for more information.
*/
/**
- * \var AwbEnable
- * ControlType: Bool
- *
- * Enables or disables the AWB. See also \a libcamera::ControlId::ManualGain
+ * \fn ControlId::ControlId(unsigned int id, const char *name, ControlType type)
+ * \brief Construct a ControlId instance
+ * \param[in] id The control numerical ID
+ * \param[in] name The control name
+ * \param[in] type The control data type
*/
/**
- * \var Brightness
- * ControlType: Integer32
- *
- * Specify a fixed brightness parameter.
+ * \fn unsigned int ControlId::id() const
+ * \brief Retrieve the control numerical ID
+ * \return The control numerical ID
*/
/**
- * \var Contrast
- * ControlType: Integer32
- *
- * Specify a fixed contrast parameter.
+ * \fn const char *ControlId::name() const
+ * \brief Retrieve the control name
+ * \return The control name
*/
/**
- * \var Saturation
- * ControlType: Integer32
- *
- * Specify a fixed saturation parameter.
+ * \fn ControlType ControlId::type() const
+ * \brief Retrieve the control data type
+ * \return The control data type
*/
/**
- * \var ManualExposure
- * ControlType: Integer32
+ * \fn bool operator==(const ControlId &lhs, const ControlId &rhs)
+ * \brief Compare two ControlId instances for equality
+ * \param[in] lhs Left-hand side ControlId
+ * \param[in] rhs Right-hand side ControlId
+ *
+ * ControlId instances are compared based on the numerical ControlId::id()
+ * only, as an object may not have two separate controls with the same
+ * numerical ID.
*
- * Specify a fixed exposure time in milli-seconds
+ * \return True if \a lhs and \a rhs have equal control IDs, false otherwise
*/
/**
- * \var ManualGain
- * ControlType: Integer32
+ * \class Control
+ * \brief Describe a control and its intrinsic properties
*
- * Specify a fixed gain parameter
+ * The Control class models a control exposed by a camera. Its template type
+ * name T refers to the control data type, and allows methods that operate on
+ * control values to be defined as template methods using the same type T for
+ * the control value. See for instance how the ControlList::get() method
+ * returns a value corresponding to the type of the requested control.
+ *
+ * While this class is the main mean to refer to a control, the control
+ * identifying information are stored in the non-template base ControlId class.
+ * This allows code that operates on a set of controls of different types to
+ * reference those controls through a ControlId instead of a Control. For
+ * instance, the list of controls supported by a camera is exposed as ControlId
+ * instead of Control.
+ *
+ * Controls of any type can be defined through template specialisation, but
+ * libcamera only supports the bool, int32_t and int64_t types natively (this
+ * includes types that are equivalent to the supported types, such as int and
+ * long int).
+ *
+ * Controls IDs shall be unique. While nothing prevents multiple instances of
+ * the Control class to be created with the same ID, this may lead to undefined
+ * behaviour.
*/
/**
- * \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.
+ * \fn Control::Control(unsigned int id, const char *name)
+ * \brief Construct a Control instance
+ * \param[in] id The control numerical ID
+ * \param[in] name The control name
*
- * \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 control data type is automatically deduced from the template type T.
*/
-/*
- * 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.
+/**
+ * \typedef Control::type
+ * \brief The Control template type T
*/
-extern const std::unordered_map<ControlId, ControlIdentifier> controlTypes;
+
+#ifndef __DOXYGEN__
+template<>
+Control<void>::Control(unsigned int id, const char *name)
+ : ControlId(id, name, ControlTypeNone)
+{
+}
+
+template<>
+Control<bool>::Control(unsigned int id, const char *name)
+ : ControlId(id, name, ControlTypeBool)
+{
+}
+
+template<>
+Control<int32_t>::Control(unsigned int id, const char *name)
+ : ControlId(id, name, ControlTypeInteger32)
+{
+}
+
+template<>
+Control<int64_t>::Control(unsigned int id, const char *name)
+ : ControlId(id, name, ControlTypeInteger64)
+{
+}
+#endif /* __DOXYGEN__ */
/**
* \class ControlInfo
@@ -260,17 +327,10 @@ extern const std::unordered_map<ControlId, ControlIdentifier> controlTypes;
* \param[in] min The control minimum value
* \param[in] max The control maximum value
*/
-ControlInfo::ControlInfo(ControlId id, const ControlValue &min,
+ControlInfo::ControlInfo(const ControlId &id, const ControlValue &min,
const ControlValue &max)
- : min_(min), max_(max)
+ : id_(id), 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;
}
/**
@@ -280,18 +340,6 @@ ControlInfo::ControlInfo(ControlId id, const ControlValue &min,
*/
/**
- * \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
@@ -310,57 +358,12 @@ std::string ControlInfo::toString() const
{
std::stringstream ss;
- ss << name() << "[" << min_.toString() << ".." << max_.toString() << "]";
+ ss << id_.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
*/
@@ -431,29 +434,9 @@ ControlList::ControlList(Camera *camera)
*
* \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
+bool ControlList::contains(const ControlId &id) const
{
- return controls_.find(info) != controls_.end();
+ return controls_.find(&id) != controls_.end();
}
/**
@@ -474,45 +457,62 @@ bool ControlList::contains(const ControlInfo *info) const
*/
/**
- * \brief Access or insert the control specified by \a id
- * \param[in] id The control ID
+ * \fn template<typename T> const T &ControlList::get() const
+ * \brief Get the value of a control
+ * \param[in] ctrl The control
*
- * 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 ctrl is not present in the
+ * list. Use ControlList::contains() to test for the presence of a control in
+ * the list before retrieving its value.
*
- * The behaviour is undefined if the control \a id is not supported by the
- * camera that the ControlList refers to.
+ * The control value type shall match the type T, otherwise the behaviour is
+ * undefined.
+ *
+ * \return The control value
+ */
+
+/**
+ * \fn template<typename T> void ControlList::set()
+ * \brief Set the control value to \a value
+ * \param[in] ctrl The control
+ * \param[in] value The control value
+ *
+ * This method sets the value of a control in the control list. If the control
+ * is already present in the list, its value is updated, otherwise it is added
+ * to the list.
*
- * \return A reference to the value of the control identified by \a id
+ * The behaviour is undefined if the control \a ctrl is not supported by the
+ * camera that the list refers to.
*/
-ControlValue &ControlList::operator[](ControlId id)
+
+const ControlValue *ControlList::find(const ControlId &id) const
+{
+ const auto iter = controls_.find(&id);
+ if (iter == controls_.end()) {
+ LOG(Controls, Error)
+ << "Control " << id.name() << " not found";
+
+ return nullptr;
+ }
+
+ return &iter->second;
+}
+
+ControlValue *ControlList::find(const ControlId &id)
{
const ControlInfoMap &controls = camera_->controls();
- const auto iter = controls.find(id);
+ 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;
+ << " does not support control " << id.name();
+ return nullptr;
}
- return controls_[&iter->second];
+ return &controls_[&id];
}
/**
- * \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
*
@@ -533,10 +533,10 @@ void ControlList::update(const ControlList &other)
}
for (auto it : other) {
- const ControlInfo *info = it.first;
+ const ControlId *id = it.first;
const ControlValue &value = it.second;
- controls_[info] = value;
+ controls_[id] = value;
}
}