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