From patchwork Wed Dec 11 14:53:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2423 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D74A2600F5 for ; Wed, 11 Dec 2019 15:51:19 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 6DE0AFF80F; Wed, 11 Dec 2019 14:51:19 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 11 Dec 2019 15:53:27 +0100 Message-Id: <20191211145327.58633-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191211145327.58633-1-jacopo@jmondi.org> References: <20191211145327.58633-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC 2/2] controls: Define controls as compound X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Dec 2019 14:51:20 -0000 Add 'isCompound' flag to the control framework. Signed-off-by: Jacopo Mondi --- 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 void set(const Control &ctrl, const Span &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(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(entry.id, "", type)); + controlIds_.emplace_back(utils::make_unique(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::Control(unsigned int id, const char *name) - : ControlId(id, name, ControlTypeNone) +Control::Control(unsigned int id, const char *name, bool isCompound) + : ControlId(id, name, ControlTypeNone, isCompound) { } template<> -Control::Control(unsigned int id, const char *name) - : ControlId(id, name, ControlTypeBool) +Control::Control(unsigned int id, const char *name, bool isCompound) + : ControlId(id, name, ControlTypeBool, isCompound) { } template<> -Control::Control(unsigned int id, const char *name) - : ControlId(id, name, ControlTypeInteger8) +Control::Control(unsigned int id, const char *name, bool isCompound) + : ControlId(id, name, ControlTypeInteger8, isCompound) { } template<> -Control::Control(unsigned int id, const char *name) - : ControlId(id, name, ControlTypeInteger32) +Control::Control(unsigned int id, const char *name, bool isCompound) + : ControlId(id, name, ControlTypeInteger32, isCompound) { } template<> -Control::Control(unsigned int id, const char *name) - : ControlId(id, name, ControlTypeInteger64) +Control::Control(unsigned int id, const char *name, bool isCompound) + : ControlId(id, name, ControlTypeInteger64, isCompound) { } template<> -Control::Control(unsigned int id, const char *name) - : ControlId(id, name, ControlTypeFloat) +Control::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 iSpan = list.get(controls::Brightness); + list.set(controls::CompoundControl, { 0, 125, 253 }); + Span 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 s = list.get(controls::Brightness); + list.set(controls::CompoundControl, 133); + Span 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; } };