[libcamera-devel,04/21] libcamera: controls: Implement ControlList serialization

Message ID 20190924172503.30864-5-jacopo@jmondi.org
State Superseded
Headers show
Series
  • Implement control serialization
Related show

Commit Message

Jacopo Mondi Sept. 24, 2019, 5:24 p.m. UTC
Make the ControlList class implement the Serializable interface and
implement the serialize() and deserialize() operations to dumps all
control values registered in the list to a memory blob and to re-create
a ControlList from a memory buffer.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 include/libcamera/controls.h |  7 +++-
 src/libcamera/controls.cpp   | 73 ++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 1 deletion(-)

Patch

diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
index c299ed94d9e2..8a7ddc510497 100644
--- a/include/libcamera/controls.h
+++ b/include/libcamera/controls.h
@@ -15,6 +15,8 @@ 
 #include <libcamera/control_ids.h>
 #include <libcamera/data_value.h>
 
+#include <libcamera/serializable.h>
+
 namespace libcamera {
 
 class Camera;
@@ -44,7 +46,7 @@  using ControlInfoMap = std::unordered_map<ControlId, ControlInfo>;
 
 using ControlValue = DataValue;
 
-class ControlList
+class ControlList : public Serializable
 {
 private:
 	using ControlMap = std::unordered_map<const ControlInfo *, ControlValue>;
@@ -71,6 +73,9 @@  public:
 
 	bool merge(const ControlList &list);
 
+	std::unique_ptr<DataBlob> serialize() const override;
+	int deserialize(uint8_t *data, size_t len) override;
+
 private:
 	const ControlInfoMap &infoMap_;
 	ControlMap controls_;
diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp
index 65001259a3df..ee19eb6dc014 100644
--- a/src/libcamera/controls.cpp
+++ b/src/libcamera/controls.cpp
@@ -10,6 +10,7 @@ 
 #include <libcamera/camera.h>
 
 #include "log.h"
+#include "serializer.h"
 #include "utils.h"
 
 /**
@@ -398,4 +399,76 @@  bool ControlList::merge(const ControlList &other)
 	return true;
 }
 
+/**
+ * \brief Serialize a ControlList to a memory buffer
+ *
+ * Serialize the control list to a DataBlob and return the ownership
+ * of the blob to the caller.
+ *
+ * The memory format used to serialize each control to memory is defined by
+ * the Serializer helper class.
+ *
+ * \sa Serializer::serialize()
+ *
+ * \return A unique pointer to a DataBlob containing the serialized control
+ * list
+ */
+std::unique_ptr<DataBlob> ControlList::serialize() const
+{
+	unsigned int bufferSize = 0;
+	for (auto it : controls_)
+		bufferSize += Serializer::size(it.second);
+
+	std::unique_ptr<DataBlob> blob(new DataBlob(bufferSize));
+	if (!blob->valid())
+		return nullptr;
+
+	uint8_t *b = blob->data();
+	for (auto it : controls_)
+		b += Serializer::serialize(it.first->id(), it.second, b);
+
+	return blob;
+}
+
+/**
+ * \brief De-serialize a ControlList from a memory buffer
+ * \param[in] data The memory buffer containing serialized control info data
+ * \param[in] len The memory buffer length in bytes
+ *
+ * De-serialize the content of the control list from a memory buffer. The memory
+ * buffer is expected to having been serialized from the
+ * ControlList::serialize() operation.
+ *
+ * \sa Serializer::deserializeData()
+ *
+ * \return 0 on success, a negative error code otherwise
+ */
+int ControlList::deserialize(uint8_t *data, size_t len)
+{
+	uint8_t *b = data;
+	size_t dataSize = 0;
+
+	while (dataSize < len) {
+		unsigned int id;
+		DataValue value;
+		size_t size;
+		std::tie(id, value, size) = Serializer::deserializeValue(b);
+
+		const auto info = infoMap_.find(static_cast<ControlId>(id));
+		if (info == infoMap_.end()) {
+			LOG(Controls, Error)
+				<< "Control id " << id << "not supported: "
+				<< "Abort deserialization";
+			return -EINVAL;
+		}
+
+		controls_[&info->second] = value;
+
+		dataSize += size;
+		b += size;
+	}
+
+	return 0;
+}
+
 } /* namespace libcamera */