diff options
author | Jacopo Mondi <jacopo@jmondi.org> | 2020-01-02 12:01:32 +0100 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2020-03-06 18:10:27 +0200 |
commit | 1fa4b43402a0af7cc41bb22b58cede687663cc7b (patch) | |
tree | abe06f7432c9aa0c05c7e1c0a04ebccf38e67602 /include | |
parent | cd0f7929ec0bdf3c98e552a6ce2e9147b8c6dd17 (diff) |
libcamera: controls: Support array controls in ControlValue
Add array controls support to the ControlValue class. The polymorphic
class can now store more than a single element and supports access and
creation through the use of Span<>.
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/libcamera/controls.h | 81 |
1 files changed, 68 insertions, 13 deletions
diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 4538be06..1e24ae30 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -9,6 +9,7 @@ #define __LIBCAMERA_CONTROLS_H__ #include <assert.h> +#include <stdint.h> #include <string> #include <unordered_map> @@ -51,6 +52,10 @@ struct control_type<int64_t> { static constexpr ControlType value = ControlTypeInteger64; }; +template<typename T, std::size_t N> +struct control_type<Span<T, N>> : public control_type<std::remove_cv_t<T>> { +}; + } /* namespace details */ class ControlValue @@ -58,15 +63,35 @@ class ControlValue public: ControlValue(); +#ifndef __DOXYGEN__ + template<typename T, typename std::enable_if_t<!details::is_span<T>::value, std::nullptr_t> = nullptr> + ControlValue(const T &value) + : type_(ControlTypeNone), numElements_(0) + { + set(details::control_type<std::remove_cv_t<T>>::value, false, + &value, 1, sizeof(T)); + } + + template<typename T, typename std::enable_if_t<details::is_span<T>::value, std::nullptr_t> = nullptr> +#else template<typename T> - ControlValue(T value) - : type_(details::control_type<std::remove_cv_t<T>>::value) +#endif + ControlValue(const T &value) + : type_(ControlTypeNone), numElements_(0) { - *reinterpret_cast<T *>(&bool_) = value; + set(details::control_type<std::remove_cv_t<T>>::value, true, + value.data(), value.size(), sizeof(typename T::value_type)); } + ~ControlValue(); + + ControlValue(const ControlValue &other); + ControlValue &operator=(const ControlValue &other); + ControlType type() const { return type_; } bool isNone() const { return type_ == ControlTypeNone; } + bool isArray() const { return isArray_; } + std::size_t numElements() const { return numElements_; } Span<const uint8_t> data() const; std::string toString() const; @@ -77,31 +102,61 @@ public: return !(*this == other); } +#ifndef __DOXYGEN__ + template<typename T, typename std::enable_if_t<!details::is_span<T>::value, std::nullptr_t> = nullptr> + T get() const + { + assert(type_ == details::control_type<std::remove_cv_t<T>>::value); + assert(!isArray_); + + return *reinterpret_cast<const T *>(data().data()); + } + + template<typename T, typename std::enable_if_t<details::is_span<T>::value, std::nullptr_t> = nullptr> +#else template<typename T> +#endif T get() const { assert(type_ == details::control_type<std::remove_cv_t<T>>::value); + assert(isArray_); + + using V = typename T::value_type; + const V *value = reinterpret_cast<const V *>(data().data()); + return { value, numElements_ }; + } - return *reinterpret_cast<const T *>(&bool_); +#ifndef __DOXYGEN__ + template<typename T, typename std::enable_if_t<!details::is_span<T>::value, std::nullptr_t> = nullptr> + void set(const T &value) + { + set(details::control_type<std::remove_cv_t<T>>::value, false, + reinterpret_cast<const void *>(&value), 1, sizeof(T)); } + template<typename T, typename std::enable_if_t<details::is_span<T>::value, std::nullptr_t> = nullptr> +#else template<typename T> +#endif void set(const T &value) { - type_ = details::control_type<std::remove_cv_t<T>>::value; - *reinterpret_cast<T *>(&bool_) = value; + set(details::control_type<std::remove_cv_t<T>>::value, true, + value.data(), value.size(), sizeof(typename T::value_type)); } private: - ControlType type_; - - union { - bool bool_; - int32_t integer32_; - int64_t integer64_; - }; + ControlType type_ : 8; + bool isArray_ : 1; + std::size_t numElements_ : 16; + uint64_t storage_; + + void release(); + void set(ControlType type, bool isArray, const void *data, + std::size_t numElements, std::size_t elementSize); }; +static_assert(sizeof(ControlValue) == 16, "Invalid size of ControlValue class"); + class ControlId { public: |