summaryrefslogtreecommitdiff
path: root/src/libcamera/control_serializer.cpp
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo@jmondi.org>2021-07-28 16:03:54 +0200
committerJacopo Mondi <jacopo@jmondi.org>2021-08-12 10:08:28 +0200
commit62c82ab93ff5fb07d581d3a78bc52a621a2a9c8f (patch)
tree98e211febc0f5608576bf45acb655a14df0eb97b /src/libcamera/control_serializer.cpp
parent0d7db1b5111f2ef0418d4f777549b2b9b8ab1df8 (diff)
libcamera: controls: Use ControlIdMap in deserialization
Introduce a new field in the controls serialization protocol to allow discerning which ControlIdMap a ControlInfoMap refers to. The newly introduced IdMapType enumeration describes the possible info maps: - Either the globally available controls::controls and properties::properties maps, which are valid across IPC boundaries - A ControlIdMap created locally by the V4L2 device, which is not valid across the IPC boundaries At de-serialization time the idMapType field is inspected and - If the idmap is a globally defined one, there's no need to create new ControlId instances when populating the de-serialized ControlInfoMap. Use the globally available map to retrieve the ControlId reference and use it. - If the idmap is a map only available locally, create a new ControlId as it used to happen before this patch. As a direct consequence, this change allows us to perform lookup by ControlId reference on de-serialized ControlIdMap that refers to the libcamera defined controls::controls and properties::properties. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/libcamera/control_serializer.cpp')
-rw-r--r--src/libcamera/control_serializer.cpp66
1 files changed, 54 insertions, 12 deletions
diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp
index ed456fd4..27360526 100644
--- a/src/libcamera/control_serializer.cpp
+++ b/src/libcamera/control_serializer.cpp
@@ -16,6 +16,8 @@
#include <libcamera/control_ids.h>
#include <libcamera/controls.h>
+#include <libcamera/property_ids.h>
+
#include <libcamera/ipa/ipa_controls.h>
#include "libcamera/internal/byte_stream_buffer.h"
@@ -188,6 +190,15 @@ int ControlSerializer::serialize(const ControlInfoMap &infoMap,
for (const auto &ctrl : infoMap)
valuesSize += binarySize(ctrl.second);
+ const ControlIdMap *idmap = &infoMap.idmap();
+ enum ipa_controls_id_map_type idMapType;
+ if (idmap == &controls::controls)
+ idMapType = IPA_CONTROL_ID_MAP_CONTROLS;
+ else if (idmap == &properties::properties)
+ idMapType = IPA_CONTROL_ID_MAP_PROPERTIES;
+ else
+ idMapType = IPA_CONTROL_ID_MAP_V4L2;
+
/* Prepare the packet header, assign a handle to the ControlInfoMap. */
struct ipa_controls_header hdr;
hdr.version = IPA_CONTROLS_FORMAT_VERSION;
@@ -195,6 +206,7 @@ int ControlSerializer::serialize(const ControlInfoMap &infoMap,
hdr.entries = infoMap.size();
hdr.size = sizeof(hdr) + entriesSize + valuesSize;
hdr.data_offset = sizeof(hdr) + entriesSize;
+ hdr.id_map_type = idMapType;
buffer.write(&hdr);
@@ -368,6 +380,33 @@ ControlInfoMap ControlSerializer::deserialize<ControlInfoMap>(ByteStreamBuffer &
return {};
}
+ /*
+ * Use the ControlIdMap corresponding to the id map type. If the type
+ * references a globally defined id map (such as controls::controls
+ * or properties::properties), use it. Otherwise, create a local id map
+ * that will be populated with dynamically created ControlId instances
+ * when deserializing individual ControlInfoMap entries.
+ */
+ const ControlIdMap *idMap = nullptr;
+ ControlIdMap *localIdMap = nullptr;
+ switch (hdr->id_map_type) {
+ case IPA_CONTROL_ID_MAP_CONTROLS:
+ idMap = &controls::controls;
+ break;
+ case IPA_CONTROL_ID_MAP_PROPERTIES:
+ idMap = &properties::properties;
+ break;
+ case IPA_CONTROL_ID_MAP_V4L2:
+ controlIdMaps_.emplace_back(std::make_unique<ControlIdMap>());
+ localIdMap = controlIdMaps_.back().get();
+ idMap = localIdMap;
+ break;
+ default:
+ LOG(Serializer, Error)
+ << "Unknown id map type: " << hdr->id_map_type;
+ return {};
+ }
+
ByteStreamBuffer entries = buffer.carveOut(hdr->data_offset - sizeof(*hdr));
ByteStreamBuffer values = buffer.carveOut(hdr->size - hdr->data_offset);
@@ -377,9 +416,6 @@ ControlInfoMap ControlSerializer::deserialize<ControlInfoMap>(ByteStreamBuffer &
}
ControlInfoMap::Map ctrls;
- controlIdMaps_.emplace_back(std::make_unique<ControlIdMap>());
- ControlIdMap *localIdMap = controlIdMaps_.back().get();
-
for (unsigned int i = 0; i < hdr->entries; ++i) {
const struct ipa_control_info_entry *entry =
entries.read<decltype(*entry)>();
@@ -388,15 +424,21 @@ ControlInfoMap ControlSerializer::deserialize<ControlInfoMap>(ByteStreamBuffer &
return {};
}
- /* Create and cache the individual ControlId. */
ControlType type = static_cast<ControlType>(entry->type);
- /**
- * \todo Find a way to preserve the control name for debugging
- * purpose.
- */
- controlIds_.emplace_back(std::make_unique<ControlId>(entry->id, "", type));
- ControlId *controlId = controlIds_.back().get();
- (*localIdMap)[entry->id] = controlId;
+
+ /* If we're using a local id map, populate it. */
+ if (localIdMap) {
+ /**
+ * \todo Find a way to preserve the control name for
+ * debugging purpose.
+ */
+ controlIds_.emplace_back(std::make_unique<ControlId>(entry->id,
+ "", type));
+ (*localIdMap)[entry->id] = controlIds_.back().get();
+ }
+
+ const ControlId *controlId = idMap->at(entry->id);
+ ASSERT(controlId);
if (entry->offset != values.offset()) {
LOG(Serializer, Error)
@@ -413,7 +455,7 @@ ControlInfoMap ControlSerializer::deserialize<ControlInfoMap>(ByteStreamBuffer &
* Create the ControlInfoMap in the cache, and store the map to handle
* association.
*/
- infoMaps_[hdr->handle] = ControlInfoMap(std::move(ctrls), *localIdMap);
+ infoMaps_[hdr->handle] = ControlInfoMap(std::move(ctrls), *idMap);
ControlInfoMap &map = infoMaps_[hdr->handle];
infoMapHandles_[&map] = hdr->handle;