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#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
18#include <libcamera/base/span.h>
19
20#include <libcamera/geometry.h>
21
22namespace libcamera {
23
24class ControlValidator;
25
34 ControlTypeRectangle,
35 ControlTypeSize,
36};
37
38namespace details {
39
40template<typename T>
41struct control_type {
42};
43
44template<>
45struct control_type<void> {
46 static constexpr ControlType value = ControlTypeNone;
47};
48
49template<>
50struct control_type<bool> {
51 static constexpr ControlType value = ControlTypeBool;
52};
53
54template<>
55struct control_type<uint8_t> {
56 static constexpr ControlType value = ControlTypeByte;
57};
58
59template<>
60struct control_type<int32_t> {
61 static constexpr ControlType value = ControlTypeInteger32;
62};
63
64template<>
65struct control_type<int64_t> {
66 static constexpr ControlType value = ControlTypeInteger64;
67};
68
69template<>
70struct control_type<float> {
71 static constexpr ControlType value = ControlTypeFloat;
72};
73
74template<>
75struct control_type<std::string> {
76 static constexpr ControlType value = ControlTypeString;
77};
78
79template<>
80struct control_type<Rectangle> {
81 static constexpr ControlType value = ControlTypeRectangle;
82};
83
84template<>
85struct control_type<Size> {
86 static constexpr ControlType value = ControlTypeSize;
87};
88
89template<typename T, std::size_t N>
90struct control_type<Span<T, N>> : public control_type<std::remove_cv_t<T>> {
91};
92
93} /* namespace details */
94
96{
97public:
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
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
198private:
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{
214public:
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
224private:
226
227 unsigned int id_;
228 std::string name_;
229 ControlType type_;
230};
231
232static inline bool operator==(unsigned int lhs, const ControlId &rhs)
233{
234 return lhs == rhs.id();
235}
236
237static inline bool operator!=(unsigned int lhs, const ControlId &rhs)
238{
239 return !(lhs == rhs);
240}
241
242static inline bool operator==(const ControlId &lhs, unsigned int rhs)
243{
244 return lhs.id() == rhs;
245}
246
247static inline bool operator!=(const ControlId &lhs, unsigned int rhs)
248{
249 return !(lhs == rhs);
250}
251
252template<typename T>
253class Control : public ControlId
254{
255public:
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
263private:
265};
266
268{
269public:
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
295private:
296 ControlValue min_;
297 ControlValue max_;
298 ControlValue def_;
299 std::vector<ControlValue> values_;
300};
301
302using ControlIdMap = std::unordered_map<unsigned int, const ControlId *>;
303
304class ControlInfoMap : private std::unordered_map<const ControlId *, ControlInfo>
305{
306public:
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
342private:
343 bool validate();
344
345 const ControlIdMap *idmap_ = nullptr;
346};
347
349{
350private:
351 using ControlListMap = std::unordered_map<unsigned int, ControlValue>;
352
353public:
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
411private:
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 */
Utilities to help constructing class interfaces.
#define LIBCAMERA_DISABLE_COPY_AND_MOVE(klass)
Disable copy and move construction and assignment of the klass.
Control static metadata.
Definition: controls.h:213
ControlId(unsigned int id, const std::string &name, ControlType type)
Construct a ControlId instance.
Definition: controls.h:215
ControlType type() const
Retrieve the control data type.
Definition: controls.h:222
const std::string & name() const
Retrieve the control name.
Definition: controls.h:221
unsigned int id() const
Retrieve the control numerical ID.
Definition: controls.h:220
A map of ControlId to ControlInfo.
Definition: controls.h:305
mapped_type & at(unsigned int key)
Access specified element by numerical ID.
Definition: controls.cpp:720
const ControlIdMap & idmap() const
Retrieve the ControlId map.
Definition: controls.h:340
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:307
iterator find(unsigned int key)
Find the element matching a numerical ID.
Definition: controls.cpp:756
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:740
Describe the limits of valid values for a Control.
Definition: controls.h:268
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:488
const std::vector< ControlValue > & values() const
Retrieve the list of valid values.
Definition: controls.h:281
std::string toString() const
Provide a string representation of the ControlInfo.
Definition: controls.cpp:588
bool operator==(const ControlInfo &other) const
Compare ControlInfo instances for equality.
Definition: controls.h:285
bool operator!=(const ControlInfo &other) const
Compare ControlInfo instances for non equality.
Definition: controls.h:290
const ControlValue & max() const
Retrieve the maximum value of the control.
Definition: controls.h:279
const ControlValue & def() const
Retrieve the default value of the control.
Definition: controls.h:280
const ControlValue & min() const
Retrieve the minimum value of the control.
Definition: controls.h:278
Associate a list of ControlId with their values for an object.
Definition: controls.h:349
void clear()
Removes all controls from the list.
Definition: controls.h:369
const ControlInfoMap * infoMap() const
Retrieve the ControlInfoMap used to construct the ControlList.
Definition: controls.h:408
const ControlIdMap * idMap() const
Retrieve the ControlId map used to construct the ControlList.
Definition: controls.h:409
ControlListMap::const_iterator const_iterator
Const iterator for the controls contained within the list.
Definition: controls.h:359
iterator end()
Retrieve an iterator pointing to the past-the-end control in the list.
Definition: controls.h:362
bool contains(const ControlId &id) const
Check if the list contains a control with the specified id.
Definition: controls.cpp:940
void set(const Control< T > &ctrl, const V &value)
Set the control ctrl value to value.
Definition: controls.h:386
std::size_t size() const
Retrieve the number of controls in the list.
Definition: controls.h:367
ControlListMap::iterator iterator
Iterator for the controls contained within the list.
Definition: controls.h:358
bool empty() const
Identify if the list is empty.
Definition: controls.h:366
void set(const Control< T > &ctrl, const std::initializer_list< V > &value)
Definition: controls.h:396
T get(const Control< T > &ctrl) const
Get the value of control ctrl.
Definition: controls.h:376
iterator begin()
Retrieve an iterator to the first Control in the list.
Definition: controls.h:361
const_iterator begin() const
Retrieve a const_iterator to the first Control in the list.
Definition: controls.h:363
ControlList()
Construct a ControlList not associated with any object.
Definition: controls.cpp:810
const_iterator end() const
Retrieve a const iterator pointing to the past-the-end control in the list.
Definition: controls.h:364
void merge(const ControlList &source)
Merge the source into the ControlList.
Definition: controls.cpp:908
Interface for the control validator.
Definition: control_validator.h:17
Abstract type representing the value of a control.
Definition: controls.h:96
T get() const
Get the control value.
Definition: controls.h:163
bool isArray() const
Determine if the value stores an array.
Definition: controls.h:132
ControlValue & operator=(const ControlValue &other)
Replace the content of the ControlValue with a copy of the content of other.
Definition: controls.cpp:146
void reserve(ControlType type, bool isArray=false, std::size_t numElements=1)
Set the control type and reserve memory.
Definition: controls.cpp:355
bool operator==(const ControlValue &other) const
Compare ControlValue instances for equality.
Definition: controls.cpp:279
void set(const T &value)
Set the control value to value.
Definition: controls.h:189
ControlValue()
Construct an empty ControlValue.
Definition: controls.cpp:98
bool operator!=(const ControlValue &other) const
Compare ControlValue instances for non equality.
Definition: controls.h:140
ControlValue(const T &value)
Construct a ControlValue of type T.
Definition: controls.h:118
ControlType type() const
Retrieve the data type of the value.
Definition: controls.h:130
std::string toString() const
Assemble and return a string describing the value.
Definition: controls.cpp:208
bool isNone() const
Determine if the value is not initialised.
Definition: controls.h:131
std::size_t numElements() const
Retrieve the number of elements stored in the ControlValue.
Definition: controls.h:133
Span< const uint8_t > data() const
Retrieve the raw data of a control value.
Definition: controls.cpp:186
Describe a control and its intrinsic properties.
Definition: controls.h:254
T type
The Control template type T.
Definition: controls.h:256
Control(unsigned int id, const char *name)
Construct a Control instance.
Definition: controls.h:258
Data structures related to geometric objects.
Top-level libcamera namespace.
Definition: backtrace.h:17
ControlType
Define the data type of a Control.
Definition: controls.h:26
@ ControlTypeNone
Definition: controls.h:27
@ ControlTypeFloat
Definition: controls.h:32
@ ControlTypeBool
Definition: controls.h:28
@ ControlTypeInteger32
Definition: controls.h:30
@ ControlTypeString
Definition: controls.h:33
@ ControlTypeInteger64
Definition: controls.h:31
@ ControlTypeByte
Definition: controls.h:29
std::unordered_map< unsigned int, const ControlId * > ControlIdMap
A map of numerical control ID to ControlId.
Definition: controls.h:302
bool operator==(const ColorSpace &lhs, const ColorSpace &rhs)
Compare color spaces for equality.
Definition: color_space.cpp:303