libcamera  v0.0.0
Supporting cameras in Linux since 2019
controls.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 /*
3  * Copyright (C) 2019, Google Inc.
4  *
5  * controls.h - Control handling
6  */
7 
8 #ifndef __LIBCAMERA_CONTROLS_H__
9 #define __LIBCAMERA_CONTROLS_H__
10 
11 #include <assert.h>
12 #include <stdint.h>
13 #include <string>
14 #include <unordered_map>
15 
16 #include <libcamera/geometry.h>
17 #include <libcamera/span.h>
18 
19 namespace libcamera {
20 
21 class ControlValidator;
22 
31  ControlTypeRectangle,
32  ControlTypeSize,
33 };
34 
35 namespace details {
36 
37 template<typename T>
38 struct control_type {
39 };
40 
41 template<>
42 struct control_type<void> {
43  static constexpr ControlType value = ControlTypeNone;
44 };
45 
46 template<>
47 struct control_type<bool> {
48  static constexpr ControlType value = ControlTypeBool;
49 };
50 
51 template<>
52 struct control_type<uint8_t> {
53  static constexpr ControlType value = ControlTypeByte;
54 };
55 
56 template<>
57 struct control_type<int32_t> {
58  static constexpr ControlType value = ControlTypeInteger32;
59 };
60 
61 template<>
62 struct control_type<int64_t> {
63  static constexpr ControlType value = ControlTypeInteger64;
64 };
65 
66 template<>
67 struct control_type<float> {
68  static constexpr ControlType value = ControlTypeFloat;
69 };
70 
71 template<>
72 struct control_type<std::string> {
73  static constexpr ControlType value = ControlTypeString;
74 };
75 
76 template<>
77 struct control_type<Rectangle> {
78  static constexpr ControlType value = ControlTypeRectangle;
79 };
80 
81 template<>
82 struct control_type<Size> {
83  static constexpr ControlType value = ControlTypeSize;
84 };
85 
86 template<typename T, std::size_t N>
87 struct control_type<Span<T, N>> : public control_type<std::remove_cv_t<T>> {
88 };
89 
90 } /* namespace details */
91 
93 {
94 public:
95  ControlValue();
96 
97 #ifndef __DOXYGEN__
98  template<typename T, typename std::enable_if_t<!details::is_span<T>::value &&
99  !std::is_same<std::string, std::remove_cv_t<T>>::value,
100  std::nullptr_t> = nullptr>
101  ControlValue(const T &value)
102  : type_(ControlTypeNone), numElements_(0)
103  {
104  set(details::control_type<std::remove_cv_t<T>>::value, false,
105  &value, 1, sizeof(T));
106  }
107 
108  template<typename T, typename std::enable_if_t<details::is_span<T>::value ||
109  std::is_same<std::string, std::remove_cv_t<T>>::value,
110  std::nullptr_t> = nullptr>
111 #else
112  template<typename T>
113 #endif
114  ControlValue(const T &value)
115  : type_(ControlTypeNone), numElements_(0)
116  {
117  set(details::control_type<std::remove_cv_t<T>>::value, true,
118  value.data(), value.size(), sizeof(typename T::value_type));
119  }
120 
121  ~ControlValue();
122 
123  ControlValue(const ControlValue &other);
124  ControlValue &operator=(const ControlValue &other);
125 
126  ControlType type() const { return type_; }
127  bool isNone() const { return type_ == ControlTypeNone; }
128  bool isArray() const { return isArray_; }
129  std::size_t numElements() const { return numElements_; }
130  Span<const uint8_t> data() const;
131  Span<uint8_t> data();
132 
133  std::string toString() const;
134 
135  bool operator==(const ControlValue &other) const;
136  bool operator!=(const ControlValue &other) const
137  {
138  return !(*this == other);
139  }
140 
141 #ifndef __DOXYGEN__
142  template<typename T, typename std::enable_if_t<!details::is_span<T>::value &&
143  !std::is_same<std::string, std::remove_cv_t<T>>::value,
144  std::nullptr_t> = nullptr>
145  T get() const
146  {
147  assert(type_ == details::control_type<std::remove_cv_t<T>>::value);
148  assert(!isArray_);
149 
150  return *reinterpret_cast<const T *>(data().data());
151  }
152 
153  template<typename T, typename std::enable_if_t<details::is_span<T>::value ||
154  std::is_same<std::string, std::remove_cv_t<T>>::value,
155  std::nullptr_t> = nullptr>
156 #else
157  template<typename T>
158 #endif
159  T get() const
160  {
161  assert(type_ == details::control_type<std::remove_cv_t<T>>::value);
162  assert(isArray_);
163 
164  using V = typename T::value_type;
165  const V *value = reinterpret_cast<const V *>(data().data());
166  return { value, numElements_ };
167  }
168 
169 #ifndef __DOXYGEN__
170  template<typename T, typename std::enable_if_t<!details::is_span<T>::value &&
171  !std::is_same<std::string, std::remove_cv_t<T>>::value,
172  std::nullptr_t> = nullptr>
173  void set(const T &value)
174  {
175  set(details::control_type<std::remove_cv_t<T>>::value, false,
176  reinterpret_cast<const void *>(&value), 1, sizeof(T));
177  }
178 
179  template<typename T, typename std::enable_if_t<details::is_span<T>::value ||
180  std::is_same<std::string, std::remove_cv_t<T>>::value,
181  std::nullptr_t> = nullptr>
182 #else
183  template<typename T>
184 #endif
185  void set(const T &value)
186  {
187  set(details::control_type<std::remove_cv_t<T>>::value, true,
188  value.data(), value.size(), sizeof(typename T::value_type));
189  }
190 
191  void reserve(ControlType type, bool isArray = false,
192  std::size_t numElements = 1);
193 
194 private:
195  ControlType type_ : 8;
196  bool isArray_;
197  std::size_t numElements_ : 32;
198  union {
199  uint64_t value_;
200  void *storage_;
201  };
202 
203  void release();
204  void set(ControlType type, bool isArray, const void *data,
205  std::size_t numElements, std::size_t elementSize);
206 };
207 
209 {
210 public:
211  ControlId(unsigned int id, const std::string &name, ControlType type)
212  : id_(id), name_(name), type_(type)
213  {
214  }
215 
216  unsigned int id() const { return id_; }
217  const std::string &name() const { return name_; }
218  ControlType type() const { return type_; }
219 
220 private:
221  ControlId &operator=(const ControlId &) = delete;
222  ControlId(const ControlId &) = delete;
223 
224  unsigned int id_;
225  std::string name_;
226  ControlType type_;
227 };
228 
229 static inline bool operator==(unsigned int lhs, const ControlId &rhs)
230 {
231  return lhs == rhs.id();
232 }
233 
234 static inline bool operator!=(unsigned int lhs, const ControlId &rhs)
235 {
236  return !(lhs == rhs);
237 }
238 
239 static inline bool operator==(const ControlId &lhs, unsigned int rhs)
240 {
241  return lhs.id() == rhs;
242 }
243 
244 static inline bool operator!=(const ControlId &lhs, unsigned int rhs)
245 {
246  return !(lhs == rhs);
247 }
248 
249 template<typename T>
250 class Control : public ControlId
251 {
252 public:
253  using type = T;
254 
255  Control(unsigned int id, const char *name)
256  : ControlId(id, name, details::control_type<std::remove_cv_t<T>>::value)
257  {
258  }
259 
260 private:
261  Control(const Control &) = delete;
262  Control &operator=(const Control &) = delete;
263 };
264 
266 {
267 public:
268  explicit ControlInfo(const ControlValue &min = 0,
269  const ControlValue &max = 0,
270  const ControlValue &def = 0);
271 
272  const ControlValue &min() const { return min_; }
273  const ControlValue &max() const { return max_; }
274  const ControlValue &def() const { return def_; }
275 
276  std::string toString() const;
277 
278  bool operator==(const ControlInfo &other) const
279  {
280  return min_ == other.min_ && max_ == other.max_;
281  }
282 
283  bool operator!=(const ControlInfo &other) const
284  {
285  return !(*this == other);
286  }
287 
288 private:
289  ControlValue min_;
290  ControlValue max_;
291  ControlValue def_;
292 };
293 
294 using ControlIdMap = std::unordered_map<unsigned int, const ControlId *>;
295 
296 class ControlInfoMap : private std::unordered_map<const ControlId *, ControlInfo>
297 {
298 public:
299  using Map = std::unordered_map<const ControlId *, ControlInfo>;
300 
301  ControlInfoMap() = default;
302  ControlInfoMap(const ControlInfoMap &other) = default;
303  ControlInfoMap(std::initializer_list<Map::value_type> init);
304  ControlInfoMap(Map &&info);
305 
306  ControlInfoMap &operator=(const ControlInfoMap &other) = default;
307  ControlInfoMap &operator=(std::initializer_list<Map::value_type> init);
308  ControlInfoMap &operator=(Map &&info);
309 
310  using Map::key_type;
311  using Map::mapped_type;
312  using Map::value_type;
313  using Map::size_type;
314  using Map::iterator;
315  using Map::const_iterator;
316 
317  using Map::begin;
318  using Map::cbegin;
319  using Map::end;
320  using Map::cend;
321  using Map::at;
322  using Map::empty;
323  using Map::size;
324  using Map::count;
325  using Map::find;
326 
327  mapped_type &at(unsigned int key);
328  const mapped_type &at(unsigned int key) const;
329  size_type count(unsigned int key) const;
330  iterator find(unsigned int key);
331  const_iterator find(unsigned int key) const;
332 
333  const ControlIdMap &idmap() const { return idmap_; }
334 
335 private:
336  void generateIdmap();
337 
338  ControlIdMap idmap_;
339 };
340 
342 {
343 private:
344  using ControlListMap = std::unordered_map<unsigned int, ControlValue>;
345 
346 public:
347  ControlList();
348  ControlList(const ControlIdMap &idmap, ControlValidator *validator = nullptr);
349  ControlList(const ControlInfoMap &infoMap, ControlValidator *validator = nullptr);
350 
351  using iterator = ControlListMap::iterator;
352  using const_iterator = ControlListMap::const_iterator;
353 
354  iterator begin() { return controls_.begin(); }
355  iterator end() { return controls_.end(); }
356  const_iterator begin() const { return controls_.begin(); }
357  const_iterator end() const { return controls_.end(); }
358 
359  bool empty() const { return controls_.empty(); }
360  std::size_t size() const { return controls_.size(); }
361  void clear() { controls_.clear(); }
362 
363  bool contains(const ControlId &id) const;
364  bool contains(unsigned int id) const;
365 
366  template<typename T>
367  T get(const Control<T> &ctrl) const
368  {
369  const ControlValue *val = find(ctrl.id());
370  if (!val)
371  return T{};
372 
373  return val->get<T>();
374  }
375 
376  template<typename T, typename V>
377  void set(const Control<T> &ctrl, const V &value)
378  {
379  ControlValue *val = find(ctrl.id());
380  if (!val)
381  return;
382 
383  val->set<T>(value);
384  }
385 
386  template<typename T, typename V>
387  void set(const Control<T> &ctrl, const std::initializer_list<V> &value)
388  {
389  ControlValue *val = find(ctrl.id());
390  if (!val)
391  return;
392 
393  val->set<T>(Span<const typename std::remove_cv_t<V>>{ value.begin(), value.size() });
394  }
395 
396  const ControlValue &get(unsigned int id) const;
397  void set(unsigned int id, const ControlValue &value);
398 
399  const ControlInfoMap *infoMap() const { return infoMap_; }
400 
401 private:
402  const ControlValue *find(unsigned int id) const;
403  ControlValue *find(unsigned int id);
404 
405  ControlValidator *validator_;
406  const ControlIdMap *idmap_;
407  const ControlInfoMap *infoMap_;
408 
409  ControlListMap controls_;
410 };
411 
412 } /* namespace libcamera */
413 
414 #endif /* __LIBCAMERA_CONTROLS_H__ */
Control static metadata.
Definition: controls.h:209
ControlId(unsigned int id, const std::string &name, ControlType type)
Construct a ControlId instance.
Definition: controls.h:211
ControlType type() const
Retrieve the control data type.
Definition: controls.h:218
const std::string & name() const
Retrieve the control name.
Definition: controls.h:217
unsigned int id() const
Retrieve the control numerical ID.
Definition: controls.h:216
A map of ControlId to ControlInfo.
Definition: controls.h:297
mapped_type & at(unsigned int key)
Access specified element by numerical ID.
Definition: controls.cpp:645
const ControlIdMap & idmap() const
Retrieve the ControlId map.
Definition: controls.h:333
ControlInfoMap & operator=(const ControlInfoMap &other)=default
Copy assignment operator, replace the contents with a copy of other.
std::unordered_map< const ControlId *, ControlInfo > Map
The base std::unsorted_map<> container.
Definition: controls.h:299
iterator find(unsigned int key)
Find the element matching a numerical ID.
Definition: controls.cpp:681
ControlInfoMap(const ControlInfoMap &other)=default
Copy constructor, construct a ControlInfoMap from a copy of other.
size_type count(unsigned int key) const
Count the number of elements matching a numerical ID.
Definition: controls.cpp:665
Describe the limits of valid values for a Control.
Definition: controls.h:266
ControlInfo(const ControlValue &min=0, const ControlValue &max=0, const ControlValue &def=0)
Construct a ControlInfo with minimum and maximum range parameters.
Definition: controls.cpp:487
std::string toString() const
Provide a string representation of the ControlInfo.
Definition: controls.cpp:525
bool operator==(const ControlInfo &other) const
Compare ControlInfo instances for equality.
Definition: controls.h:278
bool operator!=(const ControlInfo &other) const
Compare ControlInfo instances for non equality.
Definition: controls.h:283
const ControlValue & max() const
Retrieve the maximum value of the control.
Definition: controls.h:273
const ControlValue & def() const
Retrieve the default value of the control.
Definition: controls.h:274
const ControlValue & min() const
Retrieve the minimum value of the control.
Definition: controls.h:272
Associate a list of ControlId with their values for an object.
Definition: controls.h:342
void clear()
Removes all controls from the list.
Definition: controls.h:361
const ControlInfoMap * infoMap() const
Retrieve the ControlInfoMap used to construct the ControlList.
Definition: controls.h:399
ControlListMap::const_iterator const_iterator
Const iterator for the controls contained within the list.
Definition: controls.h:352
iterator end()
Retrieve an iterator pointing to the past-the-end control in the list.
Definition: controls.h:355
bool contains(const ControlId &id) const
Check if the list contains a control with the specified id.
Definition: controls.cpp:850
void set(const Control< T > &ctrl, const V &value)
Set the control ctrl value to value.
Definition: controls.h:377
std::size_t size() const
Retrieve the number of controls in the list.
Definition: controls.h:360
ControlListMap::iterator iterator
Iterator for the controls contained within the list.
Definition: controls.h:351
bool empty() const
Identify if the list is empty.
Definition: controls.h:359
void set(const Control< T > &ctrl, const std::initializer_list< V > &value)
Set the control ctrl value to value.
Definition: controls.h:387
T get(const Control< T > &ctrl) const
Get the value of control ctrl.
Definition: controls.h:367
iterator begin()
Retrieve an iterator to the first Control in the list.
Definition: controls.h:354
const_iterator begin() const
Retrieve a const_iterator to the first Control in the list.
Definition: controls.h:356
ControlList()
Construct a ControlList not associated with any object.
Definition: controls.cpp:762
const_iterator end() const
Retrieve a const iterator pointing to the past-the-end control in the list.
Definition: controls.h:357
Interface for the control validator.
Definition: control_validator.h:17
Abstract type representing the value of a control.
Definition: controls.h:93
T get() const
Get the control value.
Definition: controls.h:159
bool isArray() const
Determine if the value stores an array.
Definition: controls.h:128
ControlValue & operator=(const ControlValue &other)
Replace the content of the ControlValue with a copy of the content of other.
Definition: controls.cpp:145
void reserve(ControlType type, bool isArray=false, std::size_t numElements=1)
Set the control type and reserve memory.
Definition: controls.cpp:354
bool operator==(const ControlValue &other) const
Compare ControlValue instances for equality.
Definition: controls.cpp:278
void set(const T &value)
Set the control value to value.
Definition: controls.h:185
ControlValue()
Construct an empty ControlValue.
Definition: controls.cpp:97
bool operator!=(const ControlValue &other) const
Compare ControlValue instances for non equality.
Definition: controls.h:136
ControlValue(const T &value)
Construct a ControlValue of type T.
Definition: controls.h:114
ControlType type() const
Retrieve the data type of the value.
Definition: controls.h:126
std::string toString() const
Assemble and return a string describing the value.
Definition: controls.cpp:207
bool isNone() const
Determine if the value is not initialised.
Definition: controls.h:127
std::size_t numElements() const
Retrieve the number of elements stored in the ControlValue.
Definition: controls.h:129
Span< const uint8_t > data() const
Retrieve the raw data of a control value.
Definition: controls.cpp:185
Describe a control and its intrinsic properties.
Definition: controls.h:251
T type
The Control template type T.
Definition: controls.h:253
Control(unsigned int id, const char *name)
Construct a Control instance.
Definition: controls.h:255
ControlType
Define the data type of a Control.
Definition: controls.h:23
@ ControlTypeNone
Definition: controls.h:24
@ ControlTypeFloat
Definition: controls.h:29
@ ControlTypeBool
Definition: controls.h:25
@ ControlTypeInteger32
Definition: controls.h:27
@ ControlTypeString
Definition: controls.h:30
@ ControlTypeInteger64
Definition: controls.h:28
@ ControlTypeByte
Definition: controls.h:26
std::unordered_map< unsigned int, const ControlId * > ControlIdMap
A map of numerical control ID to ControlId.
Definition: controls.h:294
Data structures related to geometric objects.