From patchwork Mon Jan 13 16:42:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2636 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9662D60700 for ; Mon, 13 Jan 2020 17:40:40 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 30D90100003; Mon, 13 Jan 2020 16:40:40 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 13 Jan 2020 17:42:44 +0100 Message-Id: <20200113164245.52535-23-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200113164245.52535-1-jacopo@jmondi.org> References: <20200113164245.52535-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 22/23] libcamera: control_serializer: Add support for compound controls 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: Mon, 13 Jan 2020 16:40:42 -0000 Add support for serializing and deserializing control values which transport compound values. Signed-off-by: Jacopo Mondi --- src/libcamera/control_serializer.cpp | 123 ++++++++++++++++++--- src/libcamera/include/control_serializer.h | 10 +- 2 files changed, 117 insertions(+), 16 deletions(-) diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp index fd91baf15156..75e8ebc3d9d3 100644 --- a/src/libcamera/control_serializer.cpp +++ b/src/libcamera/control_serializer.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "byte_stream_buffer.h" #include "log.h" @@ -30,11 +31,15 @@ LOG_DEFINE_CATEGORY(Serializer) namespace { static constexpr size_t ControlValueSize[] = { - [ControlTypeNone] = 1, - [ControlTypeBool] = sizeof(bool), - [ControlTypeInteger32] = sizeof(int32_t), - [ControlTypeInteger64] = sizeof(int64_t), - [ControlTypeFloat] = sizeof(float), + [ControlTypeNone] = 1, + [ControlTypeBool] = sizeof(bool), + [ControlTypeInteger32] = sizeof(int32_t), + [ControlTypeInteger64] = sizeof(int64_t), + [ControlTypeFloat] = sizeof(float), + [ControlTypeCompoundBool] = sizeof(bool), + [ControlTypeCompoundInt32] = sizeof(int32_t), + [ControlTypeCompoundInt64] = sizeof(int64_t), + [ControlTypeCompoundFloat] = sizeof(float), }; } /* namespace */ @@ -107,7 +112,7 @@ void ControlSerializer::reset() size_t ControlSerializer::binarySize(const ControlValue &value) { - return ControlValueSize[value.type()]; + return ControlValueSize[value.type()] * value.numElements(); } size_t ControlSerializer::binarySize(const ControlRange &range) @@ -183,6 +188,30 @@ void ControlSerializer::store(const ControlValue &value, break; } + case ControlTypeCompoundBool: { + Span data = value.get>(); + buffer.write(&data); + break; + } + + case ControlTypeCompoundInt32: { + Span data = value.get>(); + buffer.write(data); + break; + } + + case ControlTypeCompoundInt64: { + Span data = value.get>(); + buffer.write(data); + break; + } + + case ControlTypeCompoundFloat: { + Span data = value.get>(); + buffer.write(data); + break; + } + default: break; } @@ -318,7 +347,7 @@ int ControlSerializer::serialize(const ControlList &list, struct ipa_control_value_entry entry; entry.id = id; - entry.count = 1; + entry.count = value.numElements(); entry.type = value.type(); entry.offset = values.offset(); entries.write(&entry); @@ -332,35 +361,74 @@ int ControlSerializer::serialize(const ControlList &list, return 0; } +template +void ControlSerializer::loadData(ByteStreamBuffer &buffer, unsigned int count, + ControlValue *value) +{ + Span data(new T[count], count); + buffer.read(&data); + + /* + * Use of ControlValue::set() guarantees the memory content + * is copied into the ControlValue. + */ + value->set(data); +} + template<> ControlValue ControlSerializer::load(ControlType type, - ByteStreamBuffer &b) + ByteStreamBuffer &buffer, + unsigned int count) { switch (type) { case ControlTypeBool: { bool value; - b.read(&value); + buffer.read(&value); return ControlValue(value); } case ControlTypeInteger32: { int32_t value; - b.read(&value); + buffer.read(&value); return ControlValue(value); } case ControlTypeInteger64: { int64_t value; - b.read(&value); + buffer.read(&value); return ControlValue(value); } case ControlTypeFloat: { float value; - b.read(&value); + buffer.read(&value); return ControlValue(value); } + case ControlTypeCompoundBool: { + ControlValue value; + loadData(buffer, count, &value); + return value; + } + + case ControlTypeCompoundInt32: { + ControlValue value; + loadData(buffer, count, &value); + return value; + } + + case ControlTypeCompoundInt64: { + ControlValue value; + loadData(buffer, count, &value); + return value; + } + + case ControlTypeCompoundFloat: { + ControlValue value; + loadData(buffer, count, &value); + return value; + } + default: return ControlValue(); } @@ -370,8 +438,32 @@ template<> ControlRange ControlSerializer::load(ControlType type, ByteStreamBuffer &b) { - ControlValue min = load(type, b); - ControlValue max = load(type, b); + /* + * The 'type' parameter represents the type of the Control + * the ControlRange refers to. Even if the Control is a compound, + * its range elements are not: adjust the type opportunely. + */ + ControlType rangeType; + switch (type) { + case ControlTypeCompoundBool: + rangeType = ControlTypeBool; + break; + case ControlTypeCompoundInt32: + rangeType = ControlTypeInteger32; + break; + case ControlTypeCompoundInt64: + rangeType = ControlTypeInteger64; + break; + case ControlTypeCompoundFloat: + rangeType = ControlTypeFloat; + break; + default: + rangeType = type; + break; + } + + ControlValue min = load(rangeType, b); + ControlValue max = load(rangeType, b); return ControlRange(min, max); } @@ -519,7 +611,8 @@ ControlList ControlSerializer::deserialize(ByteStreamBuffer &buffer } ControlType type = static_cast(entry.type); - ctrls.set(entry.id, load(type, values)); + ctrls.set(entry.id, + load(type, values, entry.count)); } return ctrls; diff --git a/src/libcamera/include/control_serializer.h b/src/libcamera/include/control_serializer.h index 55259913a2ca..2d76ffe7ed84 100644 --- a/src/libcamera/include/control_serializer.h +++ b/src/libcamera/include/control_serializer.h @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -40,8 +41,15 @@ private: static void store(const ControlValue &value, ByteStreamBuffer &buffer); static void store(const ControlRange &range, ByteStreamBuffer &buffer); + template::value>::type * = nullptr> + T load(ControlType type, ByteStreamBuffer &buffer, unsigned int count = 1); + template::value>::type * = nullptr> + T load(ControlType type, ByteStreamBuffer &buffer); template - T load(ControlType type, ByteStreamBuffer &b); + void loadData(ByteStreamBuffer &buffer, unsigned int count, + ControlValue *value); unsigned int serial_; std::vector> controlIds_;