Patch Detail
Show a patch.
GET /api/patches/13933/?format=api
{ "id": 13933, "url": "https://patchwork.libcamera.org/api/patches/13933/?format=api", "web_url": "https://patchwork.libcamera.org/patch/13933/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20210924172525.160482-4-jacopo@jmondi.org>", "date": "2021-09-24T17:25:23", "name": "[libcamera-devel,v3,3/5] libcamera: control_serializer: Use the right idmap", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "47faf05740467ae7980959810454b6cdaef9149a", "submitter": { "id": 3, "url": "https://patchwork.libcamera.org/api/people/3/?format=api", "name": "Jacopo Mondi", "email": "jacopo@jmondi.org" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/13933/mbox/", "series": [ { "id": 2567, "url": "https://patchwork.libcamera.org/api/series/2567/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=2567", "date": "2021-09-24T17:25:20", "name": "libcamera: control serializer fixes", "version": 3, "mbox": "https://patchwork.libcamera.org/series/2567/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/13933/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/13933/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 65992BDC71\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 24 Sep 2021 17:24:50 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3748A69192;\n\tFri, 24 Sep 2021 19:24:50 +0200 (CEST)", "from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net\n\t[217.70.183.201])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 86D17687DD\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 24 Sep 2021 19:24:44 +0200 (CEST)", "(Authenticated sender: jacopo@jmondi.org)\n\tby relay8-d.mail.gandi.net (Postfix) with ESMTPSA id C74681BF20A;\n\tFri, 24 Sep 2021 17:24:43 +0000 (UTC)" ], "From": "Jacopo Mondi <jacopo@jmondi.org>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Fri, 24 Sep 2021 19:25:23 +0200", "Message-Id": "<20210924172525.160482-4-jacopo@jmondi.org>", "X-Mailer": "git-send-email 2.32.0", "In-Reply-To": "<20210924172525.160482-1-jacopo@jmondi.org>", "References": "<20210924172525.160482-1-jacopo@jmondi.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH v3 3/5] libcamera: control_serializer: Use\n\tthe right idmap", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "When a ControlList is deserialized, the code searches for a valid\nControlInfoMap in the local cache and use its id map to initialize the\nlist. If no valid ControlInfoMap is found, as it's usually the case\nfor lists transporting libcamera controls and properties, the globally\ndefined controls::controls id map is used unconditionally.\n\nThis breaks the deserialization of libcamera properties, for which a\nwrong idmap is used at construction time.\n\nAs the serialization header now transports an id_map_type field, store\nthe idmap type at serialization time, and re-use it at\ndeserialization time to identify the correct id map.\n\nAlso make the validation stricter by imposing to list of V4L2 controls to\nhave an associated ControlInfoMap available, as there is no globally\ndefined idmap for such controls.\n\nTo be able to retrieve the idmap associated with a ControlList, add an\naccessor function to the ControlList class.\n\nIt might be worth in future using a ControlInfoMap to initialize the\ndeserialized ControlList to implement controls validation against their\nlimit. As such validation is not implemented at the moment, maintain the\ncurrent behaviour and initialize the control list with an idmap.\n\nSigned-off-by: Jacopo Mondi <jacopo@jmondi.org>\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n---\n include/libcamera/controls.h | 1 +\n src/libcamera/control_serializer.cpp | 51 +++++++++++++++++++++++-----\n src/libcamera/controls.cpp | 8 +++++\n 3 files changed, 51 insertions(+), 9 deletions(-)", "diff": "diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h\nindex b3590fdb93ec..af851b4661c8 100644\n--- a/include/libcamera/controls.h\n+++ b/include/libcamera/controls.h\n@@ -407,6 +407,7 @@ public:\n \tvoid set(unsigned int id, const ControlValue &value);\n \n \tconst ControlInfoMap *infoMap() const { return infoMap_; }\n+\tconst ControlIdMap *idMap() const { return idmap_; }\n \n private:\n \tconst ControlValue *find(unsigned int id) const;\ndiff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp\nindex 27360526f9eb..d42840cddecb 100644\n--- a/src/libcamera/control_serializer.cpp\n+++ b/src/libcamera/control_serializer.cpp\n@@ -275,6 +275,15 @@ int ControlSerializer::serialize(const ControlList &list,\n \t\tinfoMapHandle = 0;\n \t}\n \n+\tconst ControlIdMap *idmap = list.idMap();\n+\tenum ipa_controls_id_map_type idMapType;\n+\tif (idmap == &controls::controls)\n+\t\tidMapType = IPA_CONTROL_ID_MAP_CONTROLS;\n+\telse if (idmap == &properties::properties)\n+\t\tidMapType = IPA_CONTROL_ID_MAP_PROPERTIES;\n+\telse\n+\t\tidMapType = IPA_CONTROL_ID_MAP_V4L2;\n+\n \tsize_t entriesSize = list.size() * sizeof(struct ipa_control_value_entry);\n \tsize_t valuesSize = 0;\n \tfor (const auto &ctrl : list)\n@@ -287,6 +296,7 @@ int ControlSerializer::serialize(const ControlList &list,\n \thdr.entries = list.size();\n \thdr.size = sizeof(hdr) + entriesSize + valuesSize;\n \thdr.data_offset = sizeof(hdr) + entriesSize;\n+\thdr.id_map_type = idMapType;\n \n \tbuffer.write(&hdr);\n \n@@ -496,13 +506,15 @@ ControlList ControlSerializer::deserialize<ControlList>(ByteStreamBuffer &buffer\n \t}\n \n \t/*\n-\t * Retrieve the ControlInfoMap associated with the ControlList based on\n-\t * its ID. The mapping between infoMap and ID is set up when serializing\n-\t * or deserializing ControlInfoMap. If no mapping is found (which is\n-\t * currently the case for ControlList related to libcamera controls),\n-\t * use the global control::control idmap.\n+\t * Retrieve the ControlIdMap associated with the ControlList.\n+\t *\n+\t * The idmap is either retrieved from the list's ControlInfoMap when\n+\t * a valid handle has been initialized at serialization time, or by\n+\t * using the header's id_map_type field for lists that refer to the\n+\t * globally defined libcamera controls and properties, for which no\n+\t * ControlInfoMap is available.\n \t */\n-\tconst ControlInfoMap *infoMap;\n+\tconst ControlIdMap *idMap;\n \tif (hdr->handle) {\n \t\tauto iter = std::find_if(infoMapHandles_.begin(), infoMapHandles_.end(),\n \t\t\t\t\t [&](decltype(infoMapHandles_)::value_type &entry) {\n@@ -514,12 +526,33 @@ ControlList ControlSerializer::deserialize<ControlList>(ByteStreamBuffer &buffer\n \t\t\treturn {};\n \t\t}\n \n-\t\tinfoMap = iter->first;\n+\t\tconst ControlInfoMap *infoMap = iter->first;\n+\t\tidMap = &infoMap->idmap();\n+\t\tASSERT(idMap);\n \t} else {\n-\t\tinfoMap = nullptr;\n+\t\tswitch (hdr->id_map_type) {\n+\t\tcase IPA_CONTROL_ID_MAP_CONTROLS:\n+\t\t\tidMap = &controls::controls;\n+\t\t\tbreak;\n+\n+\t\tcase IPA_CONTROL_ID_MAP_PROPERTIES:\n+\t\t\tidMap = &properties::properties;\n+\t\t\tbreak;\n+\n+\t\tcase IPA_CONTROL_ID_MAP_V4L2:\n+\t\t\tLOG(Serializer, Fatal)\n+\t\t\t\t<< \"A list of V4L2 controls requires an ControlInfoMap\";\n+\t\t\treturn {};\n+\t\t}\n \t}\n \n-\tControlList ctrls(infoMap ? infoMap->idmap() : controls::controls);\n+\t/*\n+\t * \\todo When available, initialize the list with the ControlInfoMap\n+\t * so that controls can be validated against their limits.\n+\t * Currently no validation is performed, so it's fine relying on the\n+\t * idmap only.\n+\t */\n+\tControlList ctrls(*idMap);\n \n \tfor (unsigned int i = 0; i < hdr->entries; ++i) {\n \t\tconst struct ipa_control_value_entry *entry =\ndiff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp\nindex 55eec71ffe35..d23eff9e2728 100644\n--- a/src/libcamera/controls.cpp\n+++ b/src/libcamera/controls.cpp\n@@ -1040,6 +1040,14 @@ void ControlList::set(unsigned int id, const ControlValue &value)\n * associated ControlInfoMap, nullptr is returned in that case.\n */\n \n+/**\n+ * \\fn ControlList::idMap()\n+ * \\brief Retrieve the ControlId map used to construct the ControlList\n+ * \\return The ControlId map used to construct the ControlList. ControlsList\n+ * instances constructed with ControlList() have no associated idmap, nullptr is\n+ * returned in that case.\n+ */\n+\n const ControlValue *ControlList::find(unsigned int id) const\n {\n \tconst auto iter = controls_.find(id);\n", "prefixes": [ "libcamera-devel", "v3", "3/5" ] }