[libcamera-devel] [RFC 2/2] controls: Define controls as compound
Jacopo Mondi
jacopo at jmondi.org
Wed Dec 11 15:53:27 CET 2019
Add 'isCompound' flag to the control framework.
Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
---
include/libcamera/controls.h | 12 +++++--
src/libcamera/control_ids.yaml | 3 +-
src/libcamera/control_serializer.cpp | 4 ++-
src/libcamera/controls.cpp | 24 +++++++-------
src/libcamera/gen-controls.py | 12 ++++++-
src/libcamera/v4l2_controls.cpp | 4 ++-
test/controls/compound_controls.cpp | 48 +++++++++++++++++-----------
7 files changed, 70 insertions(+), 37 deletions(-)
diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
index b9f8d4db0bea..ddd641e01655 100644
--- a/include/libcamera/controls.h
+++ b/include/libcamera/controls.h
@@ -94,14 +94,16 @@ private:
class ControlId
{
public:
- ControlId(unsigned int id, const std::string &name, ControlType type)
- : id_(id), name_(name), type_(type)
+ ControlId(unsigned int id, const std::string &name, ControlType type,
+ bool isCompound)
+ : id_(id), name_(name), type_(type), isCompound_(isCompound)
{
}
unsigned int id() const { return id_; }
const std::string &name() const { return name_; }
ControlType type() const { return type_; }
+ bool isCompound() const { return isCompound_; }
private:
ControlId &operator=(const ControlId &) = delete;
@@ -110,6 +112,7 @@ private:
unsigned int id_;
std::string name_;
ControlType type_;
+ bool isCompound_;
};
static inline bool operator==(unsigned int lhs, const ControlId &rhs)
@@ -138,7 +141,7 @@ class Control : public ControlId
public:
using type = T;
- Control(unsigned int id, const char *name);
+ Control(unsigned int id, const char *name, bool isCompound = false);
private:
Control(const Control &) = delete;
@@ -272,6 +275,9 @@ public:
template<typename T>
void set(const Control<T> &ctrl, const Span<T> &values)
{
+ if (!ctrl.isCompound())
+ return;
+
ControlValue *val = find(ctrl.id());
if (!val)
return;
diff --git a/src/libcamera/control_ids.yaml b/src/libcamera/control_ids.yaml
index b72e81dae060..1bdece651638 100644
--- a/src/libcamera/control_ids.yaml
+++ b/src/libcamera/control_ids.yaml
@@ -51,7 +51,8 @@ controls:
description: Specify a fixed gain parameter
- CompoundControl:
- type: int8_t
+ type: int32_t
description: A fictional compound control
+ compound: true
...
diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp
index 2140d3a5dd3f..82502285c5ca 100644
--- a/src/libcamera/control_serializer.cpp
+++ b/src/libcamera/control_serializer.cpp
@@ -415,8 +415,10 @@ ControlInfoMap ControlSerializer::deserialize<ControlInfoMap>(ByteStreamBuffer &
/**
* \todo Find a way to preserve the control name for debugging
* purpose.
+ *
+ * FIXME: set isCompound to false unconditionally
*/
- controlIds_.emplace_back(utils::make_unique<ControlId>(entry.id, "", type));
+ controlIds_.emplace_back(utils::make_unique<ControlId>(entry.id, "", type, false));
if (entry.offset != values.offset()) {
LOG(Serializer, Error)
diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp
index 64d99f7669b6..8fb0088150d0 100644
--- a/src/libcamera/controls.cpp
+++ b/src/libcamera/controls.cpp
@@ -581,38 +581,38 @@ bool ControlValue::operator==(const ControlValue &other) const
#ifndef __DOXYGEN__
template<>
-Control<void>::Control(unsigned int id, const char *name)
- : ControlId(id, name, ControlTypeNone)
+Control<void>::Control(unsigned int id, const char *name, bool isCompound)
+ : ControlId(id, name, ControlTypeNone, isCompound)
{
}
template<>
-Control<bool>::Control(unsigned int id, const char *name)
- : ControlId(id, name, ControlTypeBool)
+Control<bool>::Control(unsigned int id, const char *name, bool isCompound)
+ : ControlId(id, name, ControlTypeBool, isCompound)
{
}
template<>
-Control<int8_t>::Control(unsigned int id, const char *name)
- : ControlId(id, name, ControlTypeInteger8)
+Control<int8_t>::Control(unsigned int id, const char *name, bool isCompound)
+ : ControlId(id, name, ControlTypeInteger8, isCompound)
{
}
template<>
-Control<int32_t>::Control(unsigned int id, const char *name)
- : ControlId(id, name, ControlTypeInteger32)
+Control<int32_t>::Control(unsigned int id, const char *name, bool isCompound)
+ : ControlId(id, name, ControlTypeInteger32, isCompound)
{
}
template<>
-Control<int64_t>::Control(unsigned int id, const char *name)
- : ControlId(id, name, ControlTypeInteger64)
+Control<int64_t>::Control(unsigned int id, const char *name, bool isCompound)
+ : ControlId(id, name, ControlTypeInteger64, isCompound)
{
}
template<>
-Control<float>::Control(unsigned int id, const char *name)
- : ControlId(id, name, ControlTypeFloat)
+Control<float>::Control(unsigned int id, const char *name, bool isCompound)
+ : ControlId(id, name, ControlTypeFloat, isCompound)
{
}
#endif /* __DOXYGEN__ */
diff --git a/src/libcamera/gen-controls.py b/src/libcamera/gen-controls.py
index 4a1ee52cdb04..820b862dcf01 100755
--- a/src/libcamera/gen-controls.py
+++ b/src/libcamera/gen-controls.py
@@ -26,6 +26,7 @@ ${description}\n *\n''')
${description}
*/''')
def_template = string.Template('extern const Control<${type}> ${name}(${id_name}, "${name}");')
+ def_compound_template = string.Template('extern const Control<${type}> ${name}(${id_name}, "${name}", true);')
ctrls_doc = []
ctrls_def = []
@@ -67,8 +68,17 @@ ${description}
except KeyError:
pass
+ try:
+ compound = ctrl['compound']
+ isCompound = True
+ except KeyError:
+ isCompound = False
+
ctrls_doc.append(doc_template.substitute(info))
- ctrls_def.append(def_template.substitute(info))
+ if isCompound:
+ ctrls_def.append(def_compound_template.substitute(info))
+ else:
+ ctrls_def.append(def_template.substitute(info))
ctrls_map.append('\t{ ' + id_name + ', &' + name + ' },')
return {
diff --git a/src/libcamera/v4l2_controls.cpp b/src/libcamera/v4l2_controls.cpp
index 7446c3880330..cd1b39a1a4b3 100644
--- a/src/libcamera/v4l2_controls.cpp
+++ b/src/libcamera/v4l2_controls.cpp
@@ -97,9 +97,11 @@ ControlType v4l2_ctrl_type(const struct v4l2_query_ext_ctrl &ctrl)
/**
* \brief Construct a V4L2ControlId from a struct v4l2_query_ext_ctrl
* \param[in] ctrl The struct v4l2_query_ext_ctrl as returned by the kernel
+ *
+ * FIXME: set isCompound to false unconditionally
*/
V4L2ControlId::V4L2ControlId(const struct v4l2_query_ext_ctrl &ctrl)
- : ControlId(ctrl.id, v4l2_ctrl_name(ctrl), v4l2_ctrl_type(ctrl))
+ : ControlId(ctrl.id, v4l2_ctrl_name(ctrl), v4l2_ctrl_type(ctrl), false)
{
}
diff --git a/test/controls/compound_controls.cpp b/test/controls/compound_controls.cpp
index de00573df141..0ca72f683d1f 100644
--- a/test/controls/compound_controls.cpp
+++ b/test/controls/compound_controls.cpp
@@ -53,40 +53,52 @@ protected:
cout << span[0] << endl;
/*
- * Compound Controls
- *
- * As of now, all Controls are now 'compounds' when set with a
- * Span<> of values.
- *
- * We need to define how to establish that a Control is actually
- * a compound or supports a single value.
+ * Compound Controls: can be set with a span of values
*/
- list.set(controls::Brightness, {0, 125, 255});
- Span<int32_t> iSpan = list.get(controls::Brightness);
+ list.set(controls::CompoundControl, { 0, 125, 253 });
+ Span<int32_t> iSpan = list.get(controls::CompoundControl);
cout << iSpan.size() << endl;
for (uint32_t i : iSpan)
cout << i << endl;
/*
- * But they can still be accessed and operated with a single
- * value.
+ * But they can still be accessed and operated as a single
+ * value control.
*/
- list.set(controls::Brightness, 112);
- cout << list.get(controls::Brightness) << endl;
+ list.set(controls::CompoundControl, 112);
+ cout << list.get(controls::CompoundControl) << endl;
/*
* Or set with a Span and accessed by value. The first item
- * is returned.
+ * is returned in this case.
*/
- list.set(controls::Brightness, {50, 125});
- cout << list.get(controls::Brightness) << endl;
+ list.set(controls::CompoundControl, { 50, 125 });
+ cout << list.get(controls::CompoundControl) << endl;
/* The other way around works as well. */
- list.set(controls::Brightness, 133);
- Span<int32_t> s = list.get(controls::Brightness);
+ list.set(controls::CompoundControl, 133);
+ Span<int32_t> s = list.get(controls::CompoundControl);
cout << s << endl;
+ /*
+ * Try to set a non-compound control with a span<> and make
+ * sure it fails.
+ */
+ list.set(controls::Brightness, 55);
+ uint32_t brightness = list.get(controls::Brightness);
+ if (brightness != 55) {
+ cerr << "Failed to set non-compound control" << endl;
+ return TestFail;
+ }
+
+ list.set(controls::Brightness, { 45, 30 });
+ brightness = list.get(controls::Brightness);
+ if (brightness != 55) {
+ cerr << "non-compound control set with span<>" << endl;
+ return TestFail;
+ }
+
return TestPass;
}
};
--
2.24.0
More information about the libcamera-devel
mailing list