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