From a8c40942b99e7e50d43a40c4b0a601c7428b30fd Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 27 Sep 2019 23:59:43 +0300 Subject: libcamera: controls: Improve the API towards applications MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rework the control-related classes to improve the API towards applications. The goal is to enable writing code similar to Request *req = ...; ControlList &controls = req->controls(); controls->set(controls::AwbEnable, false); controls->set(controls::ManualExposure, 1000); ... int32_t exposure = controls->get(controls::ManualExposure); with the get and set operations ensuring type safety for the control values. This is achieved by creating the following classes: - Control defines controls and is the main way to reference a control. It is a template class to allow methods using it to refer to the control type. - ControlId is the base class of Control. It stores the control ID, name and type, and can be used in contexts where a control needs to be referenced regardless of its type (for instance in lists of controls). This class replaces ControlIdentifier. - ControlValue is kept as-is. The ControlList class now exposes two template get() and set() methods that replace the operator[]. They ensure type safety by infering the value type from the Control reference that they receive. The main way to refer to a control is now through the Control class, and optionally through its base ControlId class. The ControlId enumeration is removed, replaced by a list of global Control instances. Numerical control IDs are turned into macros, and are still exposed as they are required to communicate with IPAs (especially to deserialise control lists). They should however not be used by applications. Auto-generation of header and source files is removed for now to keep the change simple. It will be added back in the future in a more elaborate form. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- include/libcamera/control_ids.h | 42 ++++++++-------- include/libcamera/controls.h | 108 +++++++++++++++++++++++++++------------- 2 files changed, 93 insertions(+), 57 deletions(-) (limited to 'include') diff --git a/include/libcamera/control_ids.h b/include/libcamera/control_ids.h index 75b6a2d5..54235f1a 100644 --- a/include/libcamera/control_ids.h +++ b/include/libcamera/control_ids.h @@ -8,34 +8,32 @@ #ifndef __LIBCAMERA_CONTROL_IDS_H__ #define __LIBCAMERA_CONTROL_IDS_H__ -#include +#include -namespace libcamera { +#include -enum ControlId { - AwbEnable, - Brightness, - Contrast, - Saturation, - ManualExposure, - ManualGain, -}; +namespace libcamera { -} /* namespace libcamera */ +namespace controls { -namespace std { +enum { + AWB_ENABLE = 1, + BRIGHTNESS = 2, + CONTRAST = 3, + SATURATION = 4, + MANUAL_EXPOSURE = 5, + MANUAL_GAIN = 6, +}; -template<> -struct hash { - using argument_type = libcamera::ControlId; - using result_type = std::size_t; +extern const Control AwbEnable; +extern const Control Brightness; +extern const Control Contrast; +extern const Control Saturation; +extern const Control ManualExposure; +extern const Control ManualGain; - result_type operator()(const argument_type &key) const noexcept - { - return std::hash::type>()(key); - } -}; +} /* namespace controls */ -} /* namespace std */ +} /* namespace libcamera */ #endif // __LIBCAMERA_CONTROL_IDS_H__ diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index a3089064..9698bd1d 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -8,12 +8,9 @@ #ifndef __LIBCAMERA_CONTROLS_H__ #define __LIBCAMERA_CONTROLS_H__ -#include #include #include -#include - namespace libcamera { class Camera; @@ -53,55 +50,75 @@ private: }; }; -struct ControlIdentifier { - ControlId id; - const char *name; - ControlType type; +class ControlId +{ +public: + unsigned int id() const { return id_; } + const char *name() const { return name_; } + ControlType type() const { return type_; } + +protected: + ControlId(unsigned int id, const char *name, ControlType type) + : id_(id), name_(name), type_(type) + { + } + +private: + ControlId(const ControlId &) = delete; + ControlId &operator=(const ControlId &) = delete; + + unsigned int id_; + const char *name_; + ControlType type_; +}; + +static inline bool operator==(const ControlId &lhs, const ControlId &rhs) +{ + return lhs.id() == rhs.id(); +} + +static inline bool operator!=(const ControlId &lhs, const ControlId &rhs) +{ + return !(lhs == rhs); +} + +template +class Control : public ControlId +{ +public: + using type = T; + + Control(unsigned int id, const char *name); + +private: + Control(const Control &) = delete; + Control &operator=(const Control &) = delete; }; class ControlInfo { public: - explicit ControlInfo(ControlId id, const ControlValue &min = 0, + explicit ControlInfo(const ControlId &id, const ControlValue &min = 0, const ControlValue &max = 0); - ControlId id() const { return ident_->id; } - const char *name() const { return ident_->name; } - ControlType type() const { return ident_->type; } - + const ControlId &id() const { return id_; } const ControlValue &min() const { return min_; } const ControlValue &max() const { return max_; } std::string toString() const; private: - const struct ControlIdentifier *ident_; + const ControlId &id_; 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); -} - -using ControlInfoMap = std::unordered_map; +using ControlInfoMap = std::unordered_map; class ControlList { private: - using ControlListMap = std::unordered_map; + using ControlListMap = std::unordered_map; public: ControlList(Camera *camera); @@ -114,18 +131,39 @@ public: const_iterator begin() const { return controls_.begin(); } const_iterator end() const { return controls_.end(); } - bool contains(ControlId id) const; - bool contains(const ControlInfo *info) const; + bool contains(const ControlId &id) const; bool empty() const { return controls_.empty(); } std::size_t size() const { return controls_.size(); } void clear() { controls_.clear(); } - ControlValue &operator[](ControlId id); - ControlValue &operator[](const ControlInfo *info) { return controls_[info]; } + template + const T &get(const Control &ctrl) const + { + const ControlValue *val = find(ctrl); + if (!val) { + static T t(0); + return t; + } + + return val->get(); + } + + template + void set(const Control &ctrl, const T &value) + { + ControlValue *val = find(ctrl); + if (!val) + return; + + val->set(value); + } void update(const ControlList &list); private: + const ControlValue *find(const ControlId &id) const; + ControlValue *find(const ControlId &id); + Camera *camera_; ControlListMap controls_; }; -- cgit v1.2.1