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