libcamera v0.5.2+99-bfd68f78
Supporting cameras in Linux since 2019
Loading...
Searching...
No Matches
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 * Control handling
6 */
7
8#pragma once
9
10#include <assert.h>
11#include <map>
12#include <optional>
13#include <stdint.h>
14#include <string>
15#include <unordered_map>
16#include <vector>
17
20#include <libcamera/base/span.h>
21
22#include <libcamera/geometry.h>
23
24namespace libcamera {
25
26class ControlValidator;
27
42
43namespace details {
44
45template<typename T, typename = std::void_t<>>
46struct control_type {
47};
48
49template<>
50struct control_type<void> {
51 static constexpr ControlType value = ControlTypeNone;
52 static constexpr std::size_t size = 0;
53};
54
55template<>
56struct control_type<bool> {
57 static constexpr ControlType value = ControlTypeBool;
58 static constexpr std::size_t size = 0;
59};
60
61template<>
62struct control_type<uint8_t> {
63 static constexpr ControlType value = ControlTypeByte;
64 static constexpr std::size_t size = 0;
65};
66
67template<>
68struct control_type<uint16_t> {
69 static constexpr ControlType value = ControlTypeUnsigned16;
70 static constexpr std::size_t size = 0;
71};
72
73template<>
74struct control_type<uint32_t> {
75 static constexpr ControlType value = ControlTypeUnsigned32;
76 static constexpr std::size_t size = 0;
77};
78
79template<>
80struct control_type<int32_t> {
81 static constexpr ControlType value = ControlTypeInteger32;
82 static constexpr std::size_t size = 0;
83};
84
85template<>
86struct control_type<int64_t> {
87 static constexpr ControlType value = ControlTypeInteger64;
88 static constexpr std::size_t size = 0;
89};
90
91template<>
92struct control_type<float> {
93 static constexpr ControlType value = ControlTypeFloat;
94 static constexpr std::size_t size = 0;
95};
96
97template<>
98struct control_type<std::string> {
99 static constexpr ControlType value = ControlTypeString;
100 static constexpr std::size_t size = 0;
101};
102
103template<>
104struct control_type<Rectangle> {
105 static constexpr ControlType value = ControlTypeRectangle;
106 static constexpr std::size_t size = 0;
107};
108
109template<>
110struct control_type<Size> {
111 static constexpr ControlType value = ControlTypeSize;
112 static constexpr std::size_t size = 0;
113};
114
115template<>
116struct control_type<Point> {
117 static constexpr ControlType value = ControlTypePoint;
118 static constexpr std::size_t size = 0;
119};
120
121template<typename T, std::size_t N>
122struct control_type<Span<T, N>, std::enable_if_t<control_type<std::remove_cv_t<T>>::size == 0>> : public control_type<std::remove_cv_t<T>> {
123 static constexpr std::size_t size = N;
124};
125
126template<typename T>
127struct control_type<T, std::enable_if_t<std::is_enum_v<T> && sizeof(T) == sizeof(int32_t)>> : public control_type<int32_t> {
128};
129
130} /* namespace details */
131
133{
134public:
135 ControlValue();
136
137#ifndef __DOXYGEN__
139 details::control_type<T>::value &&
140 !std::is_same<std::string, std::remove_cv_t<T>>::value,
141 std::nullptr_t> = nullptr>
142 ControlValue(const T &value)
143 : type_(ControlTypeNone), numElements_(0)
144 {
145 set(details::control_type<std::remove_cv_t<T>>::value, false,
146 &value, 1, sizeof(T));
147 }
148
150 std::is_same<std::string, std::remove_cv_t<T>>::value,
151 std::nullptr_t> = nullptr>
152#else
153 template<typename T>
154#endif
155 ControlValue(const T &value)
156 : type_(ControlTypeNone), numElements_(0)
157 {
158 set(details::control_type<std::remove_cv_t<T>>::value, true,
159 value.data(), value.size(), sizeof(typename T::value_type));
160 }
161
163
166
167 ControlType type() const { return type_; }
168 bool isNone() const { return type_ == ControlTypeNone; }
169 bool isArray() const { return isArray_; }
170 std::size_t numElements() const { return numElements_; }
173
174 std::string toString() const;
175
176 bool operator==(const ControlValue &other) const;
177 bool operator!=(const ControlValue &other) const
178 {
179 return !(*this == other);
180 }
181
182#ifndef __DOXYGEN__
184 !std::is_same<std::string, std::remove_cv_t<T>>::value,
185 std::nullptr_t> = nullptr>
186 T get() const
187 {
188 assert(type_ == details::control_type<std::remove_cv_t<T>>::value);
189 assert(!isArray_);
190
191 return *reinterpret_cast<const T *>(data().data());
192 }
193
195 std::is_same<std::string, std::remove_cv_t<T>>::value,
196 std::nullptr_t> = nullptr>
197#else
198 template<typename T>
199#endif
200 T get() const
201 {
202 assert(type_ == details::control_type<std::remove_cv_t<T>>::value);
203 assert(isArray_);
204
205 using V = typename T::value_type;
206 const V *value = reinterpret_cast<const V *>(data().data());
207 return T{ value, numElements_ };
208 }
209
210#ifndef __DOXYGEN__
212 !std::is_same<std::string, std::remove_cv_t<T>>::value,
213 std::nullptr_t> = nullptr>
214 void set(const T &value)
215 {
216 set(details::control_type<std::remove_cv_t<T>>::value, false,
217 reinterpret_cast<const void *>(&value), 1, sizeof(T));
218 }
219
221 std::is_same<std::string, std::remove_cv_t<T>>::value,
222 std::nullptr_t> = nullptr>
223#else
224 template<typename T>
225#endif
226 void set(const T &value)
227 {
228 set(details::control_type<std::remove_cv_t<T>>::value, true,
229 value.data(), value.size(), sizeof(typename T::value_type));
230 }
231
232 void reserve(ControlType type, bool isArray = false,
233 std::size_t numElements = 1);
234
235private:
236 ControlType type_ : 8;
237 bool isArray_;
238 std::size_t numElements_ : 32;
239 union {
240 uint64_t value_;
241 void *storage_;
242 };
243
244 void release();
245 void set(ControlType type, bool isArray, const void *data,
246 std::size_t numElements, std::size_t elementSize);
247};
248
250{
251public:
252 enum class Direction {
253 In = (1 << 0),
254 Out = (1 << 1),
255 };
256
258
259 ControlId(unsigned int id, const std::string &name, const std::string &vendor,
261 std::size_t size = 0,
262 const std::map<std::string, int32_t> &enumStrMap = {});
263
264 unsigned int id() const { return id_; }
265 const std::string &name() const { return name_; }
266 const std::string &vendor() const { return vendor_; }
267 ControlType type() const { return type_; }
268 DirectionFlags direction() const { return direction_; }
269 bool isInput() const { return !!(direction_ & Direction::In); }
270 bool isOutput() const { return !!(direction_ & Direction::Out); }
271 bool isArray() const { return size_ > 0; }
272 std::size_t size() const { return size_; }
273 const std::map<int32_t, std::string> &enumerators() const { return reverseMap_; }
274
275private:
277
278 unsigned int id_;
279 std::string name_;
280 std::string vendor_;
281 ControlType type_;
282 DirectionFlags direction_;
283 std::size_t size_;
284 std::map<std::string, int32_t> enumStrMap_;
285 std::map<int32_t, std::string> reverseMap_;
286};
287
289
290static inline bool operator==(unsigned int lhs, const ControlId &rhs)
291{
292 return lhs == rhs.id();
293}
294
295static inline bool operator!=(unsigned int lhs, const ControlId &rhs)
296{
297 return !(lhs == rhs);
298}
299
300static inline bool operator==(const ControlId &lhs, unsigned int rhs)
301{
302 return lhs.id() == rhs;
303}
304
305static inline bool operator!=(const ControlId &lhs, unsigned int rhs)
306{
307 return !(lhs == rhs);
308}
309
310template<typename T>
311class Control : public ControlId
312{
313public:
314 using type = T;
315
316 Control(unsigned int id, const char *name, const char *vendor,
318 const std::map<std::string, int32_t> &enumStrMap = {})
319 : ControlId(id, name, vendor, details::control_type<std::remove_cv_t<T>>::value,
320 direction, details::control_type<std::remove_cv_t<T>>::size, enumStrMap)
321 {
322 }
323
324private:
326};
327
329{
330public:
331 explicit ControlInfo(const ControlValue &min = {},
332 const ControlValue &max = {},
333 const ControlValue &def = {});
334 explicit ControlInfo(Span<const ControlValue> values,
335 const ControlValue &def = {});
336
337 const ControlValue &min() const { return min_; }
338 const ControlValue &max() const { return max_; }
339 const ControlValue &def() const { return def_; }
340 const std::vector<ControlValue> &values() const { return values_; }
341
342 std::string toString() const;
343
344 bool operator==(const ControlInfo &other) const
345 {
346 return min_ == other.min_ && max_ == other.max_;
347 }
348
349 bool operator!=(const ControlInfo &other) const
350 {
351 return !(*this == other);
352 }
353
354private:
355 ControlValue min_;
356 ControlValue max_;
357 ControlValue def_;
358 std::vector<ControlValue> values_;
359};
360
361using ControlIdMap = std::unordered_map<unsigned int, const ControlId *>;
362
363class ControlInfoMap : private std::unordered_map<const ControlId *, ControlInfo>
364{
365public:
366 using Map = std::unordered_map<const ControlId *, ControlInfo>;
367
368 ControlInfoMap() = default;
369 ControlInfoMap(const ControlInfoMap &other) = default;
370 ControlInfoMap(std::initializer_list<Map::value_type> init,
371 const ControlIdMap &idmap);
372 ControlInfoMap(Map &&info, const ControlIdMap &idmap);
373
374 ControlInfoMap &operator=(const ControlInfoMap &other) = default;
375
376 using Map::key_type;
377 using Map::mapped_type;
378 using Map::value_type;
379 using Map::size_type;
380 using Map::iterator;
381 using Map::const_iterator;
382
383 using Map::begin;
384 using Map::cbegin;
385 using Map::end;
386 using Map::cend;
387 using Map::at;
388 using Map::empty;
389 using Map::size;
390 using Map::count;
391 using Map::find;
392
393 mapped_type &at(unsigned int key);
394 const mapped_type &at(unsigned int key) const;
395 size_type count(unsigned int key) const;
396 iterator find(unsigned int key);
397 const_iterator find(unsigned int key) const;
398
399 const ControlIdMap &idmap() const { return *idmap_; }
400
401private:
402 bool validate();
403
404 const ControlIdMap *idmap_ = nullptr;
405};
406
408{
409private:
410 using ControlListMap = std::unordered_map<unsigned int, ControlValue>;
411
412public:
413 enum class MergePolicy {
414 KeepExisting = 0,
416 };
417
418 ControlList();
419 ControlList(const ControlIdMap &idmap, const ControlValidator *validator = nullptr);
420 ControlList(const ControlInfoMap &infoMap, const ControlValidator *validator = nullptr);
421
422 using iterator = ControlListMap::iterator;
423 using const_iterator = ControlListMap::const_iterator;
424
425 iterator begin() { return controls_.begin(); }
426 iterator end() { return controls_.end(); }
427 const_iterator begin() const { return controls_.begin(); }
428 const_iterator end() const { return controls_.end(); }
429
430 bool empty() const { return controls_.empty(); }
431 std::size_t size() const { return controls_.size(); }
432
433 void clear() { controls_.clear(); }
435
436 bool contains(unsigned int id) const;
437
438 template<typename T>
439 std::optional<T> get(const Control<T> &ctrl) const
440 {
441 const auto entry = controls_.find(ctrl.id());
442 if (entry == controls_.end())
443 return std::nullopt;
444
445 const ControlValue &val = entry->second;
446 return val.get<T>();
447 }
448
449 template<typename T, typename V>
450 void set(const Control<T> &ctrl, const V &value)
451 {
452 ControlValue *val = find(ctrl.id());
453 if (!val)
454 return;
455
456 val->set<T>(value);
457 }
458
459 template<typename T, typename V, size_t Size>
460 void set(const Control<Span<T, Size>> &ctrl, const std::initializer_list<V> &value)
461 {
462 ControlValue *val = find(ctrl.id());
463 if (!val)
464 return;
465
466 val->set(Span<const typename std::remove_cv_t<V>, Size>{ value.begin(), value.size() });
467 }
468
469 const ControlValue &get(unsigned int id) const;
470 void set(unsigned int id, const ControlValue &value);
471
472 const ControlInfoMap *infoMap() const { return infoMap_; }
473 const ControlIdMap *idMap() const { return idmap_; }
474
475private:
476 const ControlValue *find(unsigned int id) const;
477 ControlValue *find(unsigned int id);
478
479 const ControlValidator *validator_;
480 const ControlIdMap *idmap_;
481 const ControlInfoMap *infoMap_;
482
483 ControlListMap controls_;
484};
485
486} /* 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.
Definition class.h:29
Control static metadata.
Definition controls.h:250
const std::map< int32_t, std::string > & enumerators() const
Retrieve the map of enum values to enum names.
Definition controls.h:273
ControlType type() const
Retrieve the control data type.
Definition controls.h:267
bool isOutput() const
Determine if the control is available to be used in output metadata.
Definition controls.h:270
bool isInput() const
Determine if the control is available to be used as an input control.
Definition controls.h:269
Flags< Direction > DirectionFlags
A wrapper for ControlId::Direction so that it can be used as flags.
Definition controls.h:257
Direction
The direction the control is capable of being passed from/to.
Definition controls.h:252
@ Out
The control can be returned as output in metadata.
@ In
The control can be passed as input in controls.
const std::string & vendor() const
Retrieve the vendor name.
Definition controls.h:266
bool isArray() const
Determine if the control is an array control.
Definition controls.h:271
DirectionFlags direction() const
Return the direction that the control can be used in.
Definition controls.h:268
const std::string & name() const
Retrieve the control name.
Definition controls.h:265
std::size_t size() const
Retrieve the size of the control if it is an array control.
Definition controls.h:272
unsigned int id() const
Retrieve the control numerical ID.
Definition controls.h:264
A map of ControlId to ControlInfo.
Definition controls.h:364
mapped_type & at(unsigned int key)
Access specified element by numerical ID.
Definition controls.cpp:805
const ControlIdMap & idmap() const
Retrieve the ControlId map.
Definition controls.h:399
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:366
iterator find(unsigned int key)
Find the element matching a numerical ID.
Definition controls.cpp:840
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:829
Describe the limits of valid values for a Control.
Definition controls.h:329
const std::vector< ControlValue > & values() const
Retrieve the list of valid values.
Definition controls.h:340
std::string toString() const
Provide a string representation of the ControlInfo.
Definition controls.cpp:670
bool operator==(const ControlInfo &other) const
Compare ControlInfo instances for equality.
Definition controls.h:344
bool operator!=(const ControlInfo &other) const
Compare ControlInfo instances for non equality.
Definition controls.h:349
const ControlValue & max() const
Retrieve the maximum value of the control.
Definition controls.h:338
const ControlValue & def() const
Retrieve the default value of the control.
Definition controls.h:339
const ControlValue & min() const
Retrieve the minimum value of the control.
Definition controls.h:337
Associate a list of ControlId with their values for an object.
Definition controls.h:408
void merge(const ControlList &source, MergePolicy policy=MergePolicy::KeepExisting)
Merge the source into the ControlList.
Definition controls.cpp:1012
void clear()
Removes all controls from the list.
Definition controls.h:433
const ControlInfoMap * infoMap() const
Retrieve the ControlInfoMap used to construct the ControlList.
Definition controls.h:472
const ControlIdMap * idMap() const
Retrieve the ControlId map used to construct the ControlList.
Definition controls.h:473
void set(const Control< Span< T, Size > > &ctrl, const std::initializer_list< V > &value)
Set the control ctrl value to value.
Definition controls.h:460
ControlListMap::const_iterator const_iterator
Const iterator for the controls contained within the list.
Definition controls.h:423
iterator end()
Retrieve an iterator pointing to the past-the-end control in the list.
Definition controls.h:426
MergePolicy
The policy used by the merge function.
Definition controls.h:413
@ OverwriteExisting
Existing controls in the target list are updated.
@ KeepExisting
Existing controls in the target list are kept.
std::size_t size() const
Retrieve the number of controls in the list.
Definition controls.h:431
ControlListMap::iterator iterator
Iterator for the controls contained within the list.
Definition controls.h:422
std::optional< T > get(const Control< T > &ctrl) const
Get the value of control ctrl.
Definition controls.h:439
bool empty() const
Identify if the list is empty.
Definition controls.h:430
void set(const Control< T > &ctrl, const V &value)
Set the control ctrl value to value.
Definition controls.h:450
iterator begin()
Retrieve an iterator to the first Control in the list.
Definition controls.h:425
bool contains(unsigned int id) const
Check if the list contains a control with the specified id.
Definition controls.cpp:1044
const_iterator begin() const
Retrieve a const_iterator to the first Control in the list.
Definition controls.h:427
ControlList()
Construct a ControlList not associated with any object.
Definition controls.cpp:900
const_iterator end() const
Retrieve a const iterator pointing to the past-the-end control in the list.
Definition controls.h:428
Interface for the control validator.
Definition control_validator.h:17
Abstract type representing the value of a control.
Definition controls.h:133
T get() const
Get the control value.
Definition controls.h:200
bool isArray() const
Determine if the value stores an array.
Definition controls.h:169
ControlValue & operator=(const ControlValue &other)
Replace the content of the ControlValue with a copy of the content of other.
Definition controls.cpp:152
void reserve(ControlType type, bool isArray=false, std::size_t numElements=1)
Set the control type and reserve memory.
Definition controls.cpp:376
bool operator==(const ControlValue &other) const
Compare ControlValue instances for equality.
Definition controls.cpp:300
void set(const T &value)
Set the control value to value.
Definition controls.h:226
ControlValue()
Construct an empty ControlValue.
Definition controls.cpp:104
bool operator!=(const ControlValue &other) const
Compare ControlValue instances for non equality.
Definition controls.h:177
ControlValue(const T &value)
Construct a ControlValue of type T.
Definition controls.h:155
ControlType type() const
Retrieve the data type of the value.
Definition controls.h:167
std::string toString() const
Assemble and return a string describing the value.
Definition controls.cpp:214
bool isNone() const
Determine if the value is not initialised.
Definition controls.h:168
std::size_t numElements() const
Retrieve the number of elements stored in the ControlValue.
Definition controls.h:170
Span< const uint8_t > data() const
Retrieve the raw data of a control value.
Definition controls.cpp:192
Describe a control and its intrinsic properties.
Definition controls.h:312
Control(unsigned int id, const char *name, const char *vendor, ControlId::DirectionFlags direction, const std::map< std::string, int32_t > &enumStrMap={})
Construct a Control instance.
Definition controls.h:316
T type
The Control template type T.
Definition controls.h:314
Describe a two-dimensional size.
Definition geometry.h:51
Enum-based bit fields.
#define LIBCAMERA_FLAGS_ENABLE_OPERATORS(_enum)
Enable bitwise operations on the enum enumeration.
Definition flags.h:189
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:28
@ ControlTypeNone
Definition controls.h:29
@ ControlTypeFloat
Definition controls.h:36
@ ControlTypeUnsigned16
Definition controls.h:32
@ ControlTypeBool
Definition controls.h:30
@ ControlTypeUnsigned32
Definition controls.h:33
@ ControlTypeInteger32
Definition controls.h:34
@ ControlTypeString
Definition controls.h:37
@ ControlTypeInteger64
Definition controls.h:35
@ ControlTypeByte
Definition controls.h:31
std::unordered_map< unsigned int, const ControlId * > ControlIdMap
A map of numerical control ID to ControlId.
Definition controls.h:361
bool operator==(const ColorSpace &lhs, const ColorSpace &rhs)
Compare color spaces for equality.
Definition color_space.cpp:506