libcamera: controls: Introduce control-related data types
Add a set of data types to support controls: - ControlValue stores a control type and value in a generic way - ControlId enumerates all the control identifiers - ControlIdentifier declares the types of a control and map their names - ControlInfo stores runtime information for controls - ControlList contains a set of control info and value pairs The control definitions map is generated from the controls documentation to ensure that the two will always be synchronised. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
This commit is contained in:
parent
a110cc94ab
commit
20d5640ca4
7 changed files with 741 additions and 1 deletions
|
@ -868,7 +868,8 @@ EXCLUDE_SYMBOLS = libcamera::SignalBase \
|
||||||
libcamera::SlotArgs \
|
libcamera::SlotArgs \
|
||||||
libcamera::SlotBase \
|
libcamera::SlotBase \
|
||||||
libcamera::SlotMember \
|
libcamera::SlotMember \
|
||||||
libcamera::SlotStatic
|
libcamera::SlotStatic \
|
||||||
|
std::*
|
||||||
|
|
||||||
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
|
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
|
||||||
# that contain example code fragments that are included (see the \include
|
# that contain example code fragments that are included (see the \include
|
||||||
|
|
35
include/libcamera/control_ids.h
Normal file
35
include/libcamera/control_ids.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019, Google Inc.
|
||||||
|
*
|
||||||
|
* control_ids.h : Control ID list
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LIBCAMERA_CONTROL_IDS_H__
|
||||||
|
#define __LIBCAMERA_CONTROL_IDS_H__
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace libcamera {
|
||||||
|
|
||||||
|
enum ControlId {
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace libcamera */
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct hash<libcamera::ControlId> {
|
||||||
|
using argument_type = libcamera::ControlId;
|
||||||
|
using result_type = std::size_t;
|
||||||
|
|
||||||
|
result_type operator()(const argument_type &key) const noexcept
|
||||||
|
{
|
||||||
|
return std::hash<std::underlying_type<argument_type>::type>()(key);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace std */
|
||||||
|
|
||||||
|
#endif // __LIBCAMERA_CONTROL_IDS_H__
|
134
include/libcamera/controls.h
Normal file
134
include/libcamera/controls.h
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
/* 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 <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <libcamera/control_ids.h>
|
||||||
|
|
||||||
|
namespace libcamera {
|
||||||
|
|
||||||
|
class Camera;
|
||||||
|
|
||||||
|
enum ControlValueType {
|
||||||
|
ControlValueNone,
|
||||||
|
ControlValueBool,
|
||||||
|
ControlValueInteger,
|
||||||
|
ControlValueInteger64,
|
||||||
|
};
|
||||||
|
|
||||||
|
class ControlValue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ControlValue();
|
||||||
|
ControlValue(bool value);
|
||||||
|
ControlValue(int value);
|
||||||
|
ControlValue(int64_t value);
|
||||||
|
|
||||||
|
ControlValueType type() const { return type_; };
|
||||||
|
bool isNone() const { return type_ == ControlValueNone; };
|
||||||
|
|
||||||
|
void set(bool value);
|
||||||
|
void set(int value);
|
||||||
|
void set(int64_t value);
|
||||||
|
|
||||||
|
bool getBool() const;
|
||||||
|
int getInt() const;
|
||||||
|
int64_t getInt64() const;
|
||||||
|
|
||||||
|
std::string toString() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ControlValueType type_;
|
||||||
|
|
||||||
|
union {
|
||||||
|
bool bool_;
|
||||||
|
int integer_;
|
||||||
|
int64_t integer64_;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ControlIdentifier {
|
||||||
|
ControlId id;
|
||||||
|
const char *name;
|
||||||
|
ControlValueType type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ControlInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ControlInfo(ControlId id, const ControlValue &min = 0,
|
||||||
|
const ControlValue &max = 0);
|
||||||
|
|
||||||
|
ControlId id() const { return ident_->id; }
|
||||||
|
const char *name() const { return ident_->name; }
|
||||||
|
ControlValueType type() const { return ident_->type; }
|
||||||
|
|
||||||
|
const ControlValue &min() const { return min_; }
|
||||||
|
const ControlValue &max() const { return max_; }
|
||||||
|
|
||||||
|
std::string toString() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const struct ControlIdentifier *ident_;
|
||||||
|
ControlValue min_;
|
||||||
|
ControlValue max_;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const ControlInfo &lhs, const ControlInfo &rhs);
|
||||||
|
bool operator==(const ControlId &lhs, const ControlInfo &rhs);
|
||||||
|
bool operator==(const ControlInfo &lhs, const ControlId &rhs);
|
||||||
|
static inline bool operator!=(const ControlInfo &lhs, const ControlInfo &rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
static inline bool operator!=(const ControlId &lhs, const ControlInfo &rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
static inline bool operator!=(const ControlInfo &lhs, const ControlId &rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ControlList
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
using ControlListMap = std::unordered_map<const ControlInfo *, ControlValue>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ControlList(Camera *camera);
|
||||||
|
|
||||||
|
using iterator = ControlListMap::iterator;
|
||||||
|
using const_iterator = ControlListMap::const_iterator;
|
||||||
|
|
||||||
|
iterator begin() { return controls_.begin(); }
|
||||||
|
iterator end() { return controls_.end(); }
|
||||||
|
const_iterator begin() const { return controls_.begin(); }
|
||||||
|
const_iterator end() const { return controls_.end(); }
|
||||||
|
|
||||||
|
bool contains(const ControlInfo *info) const;
|
||||||
|
bool empty() const { return controls_.empty(); }
|
||||||
|
std::size_t size() const { return controls_.size(); }
|
||||||
|
void clear() { controls_.clear(); }
|
||||||
|
|
||||||
|
ControlValue &operator[](const ControlInfo *info) { return controls_[info]; }
|
||||||
|
|
||||||
|
void update(const ControlList &list);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Camera *camera_;
|
||||||
|
ControlListMap controls_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace libcamera */
|
||||||
|
|
||||||
|
#endif /* __LIBCAMERA_CONTROLS_H__ */
|
|
@ -2,6 +2,8 @@ libcamera_api = files([
|
||||||
'buffer.h',
|
'buffer.h',
|
||||||
'camera.h',
|
'camera.h',
|
||||||
'camera_manager.h',
|
'camera_manager.h',
|
||||||
|
'control_ids.h',
|
||||||
|
'controls.h',
|
||||||
'event_dispatcher.h',
|
'event_dispatcher.h',
|
||||||
'event_notifier.h',
|
'event_notifier.h',
|
||||||
'geometry.h',
|
'geometry.h',
|
||||||
|
|
451
src/libcamera/controls.cpp
Normal file
451
src/libcamera/controls.cpp
Normal file
|
@ -0,0 +1,451 @@
|
||||||
|
/* 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 "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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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 */
|
106
src/libcamera/gen-controls.awk
Executable file
106
src/libcamera/gen-controls.awk
Executable file
|
@ -0,0 +1,106 @@
|
||||||
|
#!/usr/bin/awk -f
|
||||||
|
|
||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
|
# Controls are documented using Doxygen in the main controls.cpp source.
|
||||||
|
#
|
||||||
|
# Generate control tables directly from the documentation, creating enumerations
|
||||||
|
# to support the IDs and static type information regarding each control.
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
id=0
|
||||||
|
input=ARGV[1]
|
||||||
|
mode=ARGV[2]
|
||||||
|
output=ARGV[3]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Detect Doxygen style comment blocks and ignore other lines
|
||||||
|
/^\/\*\*$/ { in_doxygen=1; first_line=1; next }
|
||||||
|
// { if (!in_doxygen) next }
|
||||||
|
|
||||||
|
# Entry point for the Control Documentation
|
||||||
|
/ * \\enum ControlId$/ { in_controls=1; first_line=0; next }
|
||||||
|
// { if (!in_controls) next }
|
||||||
|
|
||||||
|
# Extract control information
|
||||||
|
/ \* \\var/ { names[++id]=$3; first_line=0; next }
|
||||||
|
/ \* ControlType:/ { types[id] = $3 }
|
||||||
|
|
||||||
|
# End of comment blocks
|
||||||
|
/^ \*\// { in_doxygen=0 }
|
||||||
|
|
||||||
|
# Identify the end of controls
|
||||||
|
/^ \* \\/ { if (first_line) exit }
|
||||||
|
// { first_line=0 }
|
||||||
|
|
||||||
|
################################
|
||||||
|
# Support output file generation
|
||||||
|
|
||||||
|
function basename(file) {
|
||||||
|
sub(".*/", "", file)
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
|
||||||
|
function Header(file, description) {
|
||||||
|
print "/* SPDX-License-Identifier: LGPL-2.1-or-later */" > file
|
||||||
|
print "/*" > file
|
||||||
|
print " * Copyright (C) 2019, Google Inc." > file
|
||||||
|
print " *" > file
|
||||||
|
print " * " basename(file) " - " description > file
|
||||||
|
print " *" > file
|
||||||
|
print " * This file is auto-generated. Do not edit." > file
|
||||||
|
print " */" > file
|
||||||
|
print "" > file
|
||||||
|
}
|
||||||
|
|
||||||
|
function EnterNameSpace(file) {
|
||||||
|
print "namespace libcamera {" > file
|
||||||
|
print "" > file
|
||||||
|
}
|
||||||
|
|
||||||
|
function ExitNameSpace(file) {
|
||||||
|
print "" > file
|
||||||
|
print "} /* namespace libcamera */" > file
|
||||||
|
}
|
||||||
|
|
||||||
|
function GenerateHeader(file) {
|
||||||
|
Header(file, "Control ID list")
|
||||||
|
|
||||||
|
print "#ifndef __LIBCAMERA_CONTROL_IDS_H__" > file
|
||||||
|
print "#define __LIBCAMERA_CONTROL_IDS_H__" > file
|
||||||
|
print "" > file
|
||||||
|
|
||||||
|
EnterNameSpace(file)
|
||||||
|
print "enum ControlId {" > file
|
||||||
|
for (i=1; i <= id; ++i) {
|
||||||
|
printf "\t%s,\n", names[i] > file
|
||||||
|
}
|
||||||
|
print "};" > file
|
||||||
|
ExitNameSpace(file)
|
||||||
|
|
||||||
|
print "" > file
|
||||||
|
print "#endif // __LIBCAMERA_CONTROL_IDS_H__" > file
|
||||||
|
}
|
||||||
|
|
||||||
|
function GenerateTable(file) {
|
||||||
|
Header(file, "Control types")
|
||||||
|
print "#include <libcamera/controls.h>" > file
|
||||||
|
print "" > file
|
||||||
|
|
||||||
|
EnterNameSpace(file)
|
||||||
|
|
||||||
|
print "extern const std::unordered_map<ControlId, ControlIdentifier>" > file
|
||||||
|
print "controlTypes {" > file
|
||||||
|
for (i=1; i <= id; ++i) {
|
||||||
|
printf "\t{ %s, { %s, \"%s\", ControlValue%s } },\n", names[i], names[i], names[i], types[i] > file
|
||||||
|
}
|
||||||
|
print "};" > file
|
||||||
|
ExitNameSpace(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
END {
|
||||||
|
if (mode == "--header")
|
||||||
|
GenerateHeader(output)
|
||||||
|
else
|
||||||
|
GenerateTable(output)
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ libcamera_sources = files([
|
||||||
'camera.cpp',
|
'camera.cpp',
|
||||||
'camera_manager.cpp',
|
'camera_manager.cpp',
|
||||||
'camera_sensor.cpp',
|
'camera_sensor.cpp',
|
||||||
|
'controls.cpp',
|
||||||
'device_enumerator.cpp',
|
'device_enumerator.cpp',
|
||||||
'device_enumerator_sysfs.cpp',
|
'device_enumerator_sysfs.cpp',
|
||||||
'event_dispatcher.cpp',
|
'event_dispatcher.cpp',
|
||||||
|
@ -68,6 +69,16 @@ if libudev.found()
|
||||||
])
|
])
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
gen_controls = files('gen-controls.awk')
|
||||||
|
|
||||||
|
control_types_cpp = custom_target('control_types_cpp',
|
||||||
|
input : files('controls.cpp'),
|
||||||
|
output : 'control_types.cpp',
|
||||||
|
depend_files : gen_controls,
|
||||||
|
command : [gen_controls, '@INPUT@', '--code', '@OUTPUT@'])
|
||||||
|
|
||||||
|
libcamera_sources += control_types_cpp
|
||||||
|
|
||||||
libcamera_deps = [
|
libcamera_deps = [
|
||||||
cc.find_library('dl'),
|
cc.find_library('dl'),
|
||||||
libudev,
|
libudev,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue