[{"id":35872,"web_url":"https://patchwork.libcamera.org/comment/35872/","msgid":"<175818471884.2127323.11718397074252430395@neptunite.rasen.tech>","date":"2025-09-18T08:38:38","subject":"Re: [RFC PATCH v2 09/22] libcamera: ipa_data_serializer: Support\n\t`MetadataListPlan`","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"Hi Barnabás,\n\nThanks for the patch.\n\nQuoting Barnabás Pőcze (2025-07-21 19:46:09)\n> Define the type in `core.mojom` with external (de)serialization, and\n> add the necessary `IPADataSerializer` template specialization.\n> \n> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> ---\n>  include/libcamera/ipa/core.mojom              |  1 +\n>  src/libcamera/ipa_data_serializer.cpp         | 91 +++++++++++++++++++\n>  .../core_ipa_interface.h.tmpl                 |  1 +\n>  3 files changed, 93 insertions(+)\n> \n> diff --git a/include/libcamera/ipa/core.mojom b/include/libcamera/ipa/core.mojom\n> index bce797245..754e4065c 100644\n> --- a/include/libcamera/ipa/core.mojom\n> +++ b/include/libcamera/ipa/core.mojom\n> @@ -83,6 +83,7 @@ module libcamera;\n>  [skipSerdes, skipHeader] struct ControlInfoMap {};\n>  [skipSerdes, skipHeader] struct ControlList {};\n>  [skipSerdes, skipHeader] struct SharedFD {};\n> +[skipSerdes, skipHeader] struct MetadataListPlan {};\n>  \n>  [skipHeader] struct Point {\n>         int32 x;\n> diff --git a/src/libcamera/ipa_data_serializer.cpp b/src/libcamera/ipa_data_serializer.cpp\n> index 0537f785b..26090f658 100644\n> --- a/src/libcamera/ipa_data_serializer.cpp\n> +++ b/src/libcamera/ipa_data_serializer.cpp\n> @@ -11,6 +11,8 @@\n>  \n>  #include <libcamera/base/log.h>\n>  \n> +#include <libcamera/metadata_list_plan.h>\n> +\n>  #include \"libcamera/internal/byte_stream_buffer.h\"\n>  \n>  /**\n> @@ -620,6 +622,95 @@ IPADataSerializer<FrameBuffer::Plane>::deserialize(const std::vector<uint8_t> &d\n>         return deserialize(data.cbegin(), data.end(), fds.cbegin(), fds.end(), cs);\n>  }\n>  \n> +template<>\n> +std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>\n> +IPADataSerializer<MetadataListPlan>::serialize(const MetadataListPlan &data,\n> +                                              [[maybe_unused]] ControlSerializer *cs)\n> +{\n> +       std::vector<uint8_t> dataVec;\n> +\n> +       appendPOD<uint32_t>(dataVec, data.size());\n> +\n> +       for (const auto &[tag, e] : data) {\n> +               appendPOD<uint32_t>(dataVec, tag);\n> +               appendPOD<uint32_t>(dataVec, e.size);\n> +               appendPOD<uint32_t>(dataVec, e.alignment);\n> +               appendPOD<uint32_t>(dataVec, e.numElements);\n> +               appendPOD<uint32_t>(dataVec, e.type);\n> +               appendPOD<uint8_t>(dataVec, e.isArray);\n> +       }\n> +\n> +       return { dataVec, {} };\n> +}\n> +\n> +template<>\n> +MetadataListPlan\n> +IPADataSerializer<MetadataListPlan>::deserialize(std::vector<uint8_t>::const_iterator dataBegin,\n> +                                                std::vector<uint8_t>::const_iterator dataEnd,\n> +                                                [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsBegin,\n> +                                                [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd,\n> +                                                [[maybe_unused]] ControlSerializer *cs)\n> +{\n> +       MetadataListPlan ret;\n> +       std::size_t offset = 0;\n> +\n> +       auto n = readPOD<uint32_t>(dataBegin, 0, dataEnd);\n> +       offset += sizeof(n);\n> +\n> +       while (n--) {\n> +               auto tag = readPOD<uint32_t>(dataBegin, offset, dataEnd);\n> +               offset += sizeof(tag);\n> +\n> +               auto size = readPOD<uint32_t>(dataBegin, offset, dataEnd);\n> +               offset += sizeof(size);\n> +\n> +               auto alignment = readPOD<uint32_t>(dataBegin, offset, dataEnd);\n> +               offset += sizeof(alignment);\n> +\n> +               auto numElements = readPOD<uint32_t>(dataBegin, offset, dataEnd);\n> +               offset += sizeof(numElements);\n> +\n> +               auto type = readPOD<uint32_t>(dataBegin, offset, dataEnd);\n> +               offset += sizeof(type);\n> +\n> +               auto isArray = readPOD<uint8_t>(dataBegin, offset, dataEnd);\n> +               offset += sizeof(isArray);\n> +\n> +               [[maybe_unused]] bool ok = ret.set(tag,\n> +                                                  size, alignment,\n> +                                                  numElements, static_cast<ControlType>(type), isArray);\n> +               ASSERT(ok);\n\nThe other deserializers return empty data instead of loudly crashing\neverything. Should we make the other deserializers loudly crash everything as\nwell or is it better to return an empty object?\n\n\nThanks,\n\nPaul\n\n> +       }\n> +\n> +       return ret;\n> +}\n> +\n> +template<>\n> +MetadataListPlan\n> +IPADataSerializer<MetadataListPlan>::deserialize(std::vector<uint8_t>::const_iterator dataBegin,\n> +                                                std::vector<uint8_t>::const_iterator dataEnd,\n> +                                                ControlSerializer *cs)\n> +{\n> +       return deserialize(dataBegin, dataEnd, {}, {}, cs);\n> +}\n> +\n> +template<>\n> +MetadataListPlan\n> +IPADataSerializer<MetadataListPlan>::deserialize(const std::vector<uint8_t> &data,\n> +                                                ControlSerializer *cs)\n> +{\n> +       return deserialize(data.cbegin(), data.end(), cs);\n> +}\n> +\n> +template<>\n> +MetadataListPlan\n> +IPADataSerializer<MetadataListPlan>::deserialize(const std::vector<uint8_t> &data,\n> +                                                const std::vector<SharedFD> &fds,\n> +                                                ControlSerializer *cs)\n> +{\n> +       return deserialize(data.cbegin(), data.end(), fds.cbegin(), fds.end(), cs);\n> +}\n> +\n>  #endif /* __DOXYGEN__ */\n>  \n>  } /* namespace libcamera */\n> diff --git a/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl b/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl\n> index 3942e5708..b3774cd64 100644\n> --- a/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl\n> +++ b/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl\n> @@ -21,6 +21,7 @@\n>  #include <libcamera/controls.h>\n>  #include <libcamera/framebuffer.h>\n>  #include <libcamera/geometry.h>\n> +#include <libcamera/metadata_list_plan.h>\n>  \n>  #include <libcamera/ipa/ipa_interface.h>\n>  \n> -- \n> 2.50.1\n>","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 757E1BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 18 Sep 2025 08:38:51 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2477B69370;\n\tThu, 18 Sep 2025 10:38:50 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B1E6A62C39\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 18 Sep 2025 10:38:47 +0200 (CEST)","from neptunite.rasen.tech (unknown\n\t[IPv6:2404:7a81:160:2100:7cf2:5f58:dd2a:9ec1])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 1BD06C72;\n\tThu, 18 Sep 2025 10:37:26 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"SrMcLUBD\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1758184647;\n\tbh=uDJJTvGUOl6ZoJuaWA7R8En4ScSU1nPBnkZvNLNJs+w=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=SrMcLUBD1GQ4U9ul1iGPLVeEIKdUuJXb1T+8keQDNyTMV52Og+s/Jw9jUwoA9ofr1\n\tTpA/vQ8AZx7UTQBjZ7BI2S6hvYwehz81V5sdUGc+ACQYBGjH2J9VMYRernD4hxG61J\n\taxc4I1zwtm7JcRGXjZkj8cgFAmNxGWPg9m2JOJCc=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20250721104622.1550908-10-barnabas.pocze@ideasonboard.com>","References":"<20250721104622.1550908-1-barnabas.pocze@ideasonboard.com>\n\t<20250721104622.1550908-10-barnabas.pocze@ideasonboard.com>","Subject":"Re: [RFC PATCH v2 09/22] libcamera: ipa_data_serializer: Support\n\t`MetadataListPlan`","From":"Paul Elder <paul.elder@ideasonboard.com>","Cc":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Thu, 18 Sep 2025 17:38:38 +0900","Message-ID":"<175818471884.2127323.11718397074252430395@neptunite.rasen.tech>","User-Agent":"alot/0.0.0","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>"}},{"id":35876,"web_url":"https://patchwork.libcamera.org/comment/35876/","msgid":"<de173aa4-0a11-4eb3-915e-124283062255@ideasonboard.com>","date":"2025-09-18T08:51:21","subject":"Re: [RFC PATCH v2 09/22] libcamera: ipa_data_serializer: Support\n\t`MetadataListPlan`","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2025. 09. 18. 10:38 keltezéssel, Paul Elder írta:\n> Hi Barnabás,\n> \n> Thanks for the patch.\n> \n> Quoting Barnabás Pőcze (2025-07-21 19:46:09)\n>> Define the type in `core.mojom` with external (de)serialization, and\n>> add the necessary `IPADataSerializer` template specialization.\n>>\n>> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n>> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n>> ---\n>>   include/libcamera/ipa/core.mojom              |  1 +\n>>   src/libcamera/ipa_data_serializer.cpp         | 91 +++++++++++++++++++\n>>   .../core_ipa_interface.h.tmpl                 |  1 +\n>>   3 files changed, 93 insertions(+)\n>>\n>> diff --git a/include/libcamera/ipa/core.mojom b/include/libcamera/ipa/core.mojom\n>> index bce797245..754e4065c 100644\n>> --- a/include/libcamera/ipa/core.mojom\n>> +++ b/include/libcamera/ipa/core.mojom\n>> @@ -83,6 +83,7 @@ module libcamera;\n>>   [skipSerdes, skipHeader] struct ControlInfoMap {};\n>>   [skipSerdes, skipHeader] struct ControlList {};\n>>   [skipSerdes, skipHeader] struct SharedFD {};\n>> +[skipSerdes, skipHeader] struct MetadataListPlan {};\n>>\n>>   [skipHeader] struct Point {\n>>          int32 x;\n>> diff --git a/src/libcamera/ipa_data_serializer.cpp b/src/libcamera/ipa_data_serializer.cpp\n>> index 0537f785b..26090f658 100644\n>> --- a/src/libcamera/ipa_data_serializer.cpp\n>> +++ b/src/libcamera/ipa_data_serializer.cpp\n>> @@ -11,6 +11,8 @@\n>>\n>>   #include <libcamera/base/log.h>\n>>\n>> +#include <libcamera/metadata_list_plan.h>\n>> +\n>>   #include \"libcamera/internal/byte_stream_buffer.h\"\n>>\n>>   /**\n>> @@ -620,6 +622,95 @@ IPADataSerializer<FrameBuffer::Plane>::deserialize(const std::vector<uint8_t> &d\n>>          return deserialize(data.cbegin(), data.end(), fds.cbegin(), fds.end(), cs);\n>>   }\n>>\n>> +template<>\n>> +std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>\n>> +IPADataSerializer<MetadataListPlan>::serialize(const MetadataListPlan &data,\n>> +                                              [[maybe_unused]] ControlSerializer *cs)\n>> +{\n>> +       std::vector<uint8_t> dataVec;\n>> +\n>> +       appendPOD<uint32_t>(dataVec, data.size());\n>> +\n>> +       for (const auto &[tag, e] : data) {\n>> +               appendPOD<uint32_t>(dataVec, tag);\n>> +               appendPOD<uint32_t>(dataVec, e.size);\n>> +               appendPOD<uint32_t>(dataVec, e.alignment);\n>> +               appendPOD<uint32_t>(dataVec, e.numElements);\n>> +               appendPOD<uint32_t>(dataVec, e.type);\n>> +               appendPOD<uint8_t>(dataVec, e.isArray);\n>> +       }\n>> +\n>> +       return { dataVec, {} };\n>> +}\n>> +\n>> +template<>\n>> +MetadataListPlan\n>> +IPADataSerializer<MetadataListPlan>::deserialize(std::vector<uint8_t>::const_iterator dataBegin,\n>> +                                                std::vector<uint8_t>::const_iterator dataEnd,\n>> +                                                [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsBegin,\n>> +                                                [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd,\n>> +                                                [[maybe_unused]] ControlSerializer *cs)\n>> +{\n>> +       MetadataListPlan ret;\n>> +       std::size_t offset = 0;\n>> +\n>> +       auto n = readPOD<uint32_t>(dataBegin, 0, dataEnd);\n>> +       offset += sizeof(n);\n>> +\n>> +       while (n--) {\n>> +               auto tag = readPOD<uint32_t>(dataBegin, offset, dataEnd);\n>> +               offset += sizeof(tag);\n>> +\n>> +               auto size = readPOD<uint32_t>(dataBegin, offset, dataEnd);\n>> +               offset += sizeof(size);\n>> +\n>> +               auto alignment = readPOD<uint32_t>(dataBegin, offset, dataEnd);\n>> +               offset += sizeof(alignment);\n>> +\n>> +               auto numElements = readPOD<uint32_t>(dataBegin, offset, dataEnd);\n>> +               offset += sizeof(numElements);\n>> +\n>> +               auto type = readPOD<uint32_t>(dataBegin, offset, dataEnd);\n>> +               offset += sizeof(type);\n>> +\n>> +               auto isArray = readPOD<uint8_t>(dataBegin, offset, dataEnd);\n>> +               offset += sizeof(isArray);\n>> +\n>> +               [[maybe_unused]] bool ok = ret.set(tag,\n>> +                                                  size, alignment,\n>> +                                                  numElements, static_cast<ControlType>(type), isArray);\n>> +               ASSERT(ok);\n> \n> The other deserializers return empty data instead of loudly crashing\n> everything. Should we make the other deserializers loudly crash everything as\n> well or is it better to return an empty object?\n\nI think this could be made to return an empty object. I'm hoping that a new version of\nhttps://patchwork.libcamera.org/patch/23373/ will be merged at some point, and then the\nerror handling can be moved out of the deserializers.\n\n\nRegards,\nBarnabás Pőcze\n\n> \n> \n> Thanks,\n> \n> Paul\n> \n>> +       }\n>> +\n>> +       return ret;\n>> +}\n>> +\n>> +template<>\n>> +MetadataListPlan\n>> +IPADataSerializer<MetadataListPlan>::deserialize(std::vector<uint8_t>::const_iterator dataBegin,\n>> +                                                std::vector<uint8_t>::const_iterator dataEnd,\n>> +                                                ControlSerializer *cs)\n>> +{\n>> +       return deserialize(dataBegin, dataEnd, {}, {}, cs);\n>> +}\n>> +\n>> +template<>\n>> +MetadataListPlan\n>> +IPADataSerializer<MetadataListPlan>::deserialize(const std::vector<uint8_t> &data,\n>> +                                                ControlSerializer *cs)\n>> +{\n>> +       return deserialize(data.cbegin(), data.end(), cs);\n>> +}\n>> +\n>> +template<>\n>> +MetadataListPlan\n>> +IPADataSerializer<MetadataListPlan>::deserialize(const std::vector<uint8_t> &data,\n>> +                                                const std::vector<SharedFD> &fds,\n>> +                                                ControlSerializer *cs)\n>> +{\n>> +       return deserialize(data.cbegin(), data.end(), fds.cbegin(), fds.end(), cs);\n>> +}\n>> +\n>>   #endif /* __DOXYGEN__ */\n>>\n>>   } /* namespace libcamera */\n>> diff --git a/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl b/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl\n>> index 3942e5708..b3774cd64 100644\n>> --- a/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl\n>> +++ b/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl\n>> @@ -21,6 +21,7 @@\n>>   #include <libcamera/controls.h>\n>>   #include <libcamera/framebuffer.h>\n>>   #include <libcamera/geometry.h>\n>> +#include <libcamera/metadata_list_plan.h>\n>>\n>>   #include <libcamera/ipa/ipa_interface.h>\n>>\n>> --\n>> 2.50.1\n>>","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 BDDC8BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 18 Sep 2025 08:51:29 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 484E469370;\n\tThu, 18 Sep 2025 10:51:29 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CAED262C39\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 18 Sep 2025 10:51:26 +0200 (CEST)","from [192.168.33.22] (185.221.142.115.nat.pool.zt.hu\n\t[185.221.142.115])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B89DE6DF;\n\tThu, 18 Sep 2025 10:50:06 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"P8VIbaFE\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1758185407;\n\tbh=jDgFUTYVDR9k94zjJ3k2TC3M3X4Qfmup5ly+BMpSJXk=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=P8VIbaFE2sy5PX5DGMaizhDQ7gxpvV/rodPqhWXYvgXvd7YncMO4WeqwIr8YqnZ0b\n\tuJPb6TRsjAzVJ1P8Q+BuOyanGoPzmB+BL0NA0guf7vHuu5Hw/k3ESpTO7CQuYZn81T\n\tRKaMe+aqMJCGIcoBSYedxEQtu28EpqNGWjQ3+AQ4=","Message-ID":"<de173aa4-0a11-4eb3-915e-124283062255@ideasonboard.com>","Date":"Thu, 18 Sep 2025 10:51:21 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [RFC PATCH v2 09/22] libcamera: ipa_data_serializer: Support\n\t`MetadataListPlan`","To":"Paul Elder <paul.elder@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Cc":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","References":"<20250721104622.1550908-1-barnabas.pocze@ideasonboard.com>\n\t<20250721104622.1550908-10-barnabas.pocze@ideasonboard.com>\n\t<Qa027RA4yiPgdVi-0oC94iqNdSQO1Wt8zs2hZWLWO5jqVZD8SvCCKVB4s3FZXDQqawjNKIGvTjC9QmmSQ8dUhw==@protonmail.internalid>\n\t<175818471884.2127323.11718397074252430395@neptunite.rasen.tech>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<175818471884.2127323.11718397074252430395@neptunite.rasen.tech>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","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>"}},{"id":35898,"web_url":"https://patchwork.libcamera.org/comment/35898/","msgid":"<175820151722.2127323.3917639411146082387@neptunite.rasen.tech>","date":"2025-09-18T13:18:37","subject":"Re: [RFC PATCH v2 09/22] libcamera: ipa_data_serializer: Support\n\t`MetadataListPlan`","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"Quoting Barnabás Pőcze (2025-09-18 17:51:21)\n> 2025. 09. 18. 10:38 keltezéssel, Paul Elder írta:\n> > Hi Barnabás,\n> > \n> > Thanks for the patch.\n> > \n> > Quoting Barnabás Pőcze (2025-07-21 19:46:09)\n> >> Define the type in `core.mojom` with external (de)serialization, and\n> >> add the necessary `IPADataSerializer` template specialization.\n> >>\n> >> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> >> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> >> ---\n> >>   include/libcamera/ipa/core.mojom              |  1 +\n> >>   src/libcamera/ipa_data_serializer.cpp         | 91 +++++++++++++++++++\n> >>   .../core_ipa_interface.h.tmpl                 |  1 +\n> >>   3 files changed, 93 insertions(+)\n> >>\n> >> diff --git a/include/libcamera/ipa/core.mojom b/include/libcamera/ipa/core.mojom\n> >> index bce797245..754e4065c 100644\n> >> --- a/include/libcamera/ipa/core.mojom\n> >> +++ b/include/libcamera/ipa/core.mojom\n> >> @@ -83,6 +83,7 @@ module libcamera;\n> >>   [skipSerdes, skipHeader] struct ControlInfoMap {};\n> >>   [skipSerdes, skipHeader] struct ControlList {};\n> >>   [skipSerdes, skipHeader] struct SharedFD {};\n> >> +[skipSerdes, skipHeader] struct MetadataListPlan {};\n> >>\n> >>   [skipHeader] struct Point {\n> >>          int32 x;\n> >> diff --git a/src/libcamera/ipa_data_serializer.cpp b/src/libcamera/ipa_data_serializer.cpp\n> >> index 0537f785b..26090f658 100644\n> >> --- a/src/libcamera/ipa_data_serializer.cpp\n> >> +++ b/src/libcamera/ipa_data_serializer.cpp\n> >> @@ -11,6 +11,8 @@\n> >>\n> >>   #include <libcamera/base/log.h>\n> >>\n> >> +#include <libcamera/metadata_list_plan.h>\n> >> +\n> >>   #include \"libcamera/internal/byte_stream_buffer.h\"\n> >>\n> >>   /**\n> >> @@ -620,6 +622,95 @@ IPADataSerializer<FrameBuffer::Plane>::deserialize(const std::vector<uint8_t> &d\n> >>          return deserialize(data.cbegin(), data.end(), fds.cbegin(), fds.end(), cs);\n> >>   }\n> >>\n> >> +template<>\n> >> +std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>\n> >> +IPADataSerializer<MetadataListPlan>::serialize(const MetadataListPlan &data,\n> >> +                                              [[maybe_unused]] ControlSerializer *cs)\n> >> +{\n> >> +       std::vector<uint8_t> dataVec;\n> >> +\n> >> +       appendPOD<uint32_t>(dataVec, data.size());\n> >> +\n> >> +       for (const auto &[tag, e] : data) {\n> >> +               appendPOD<uint32_t>(dataVec, tag);\n> >> +               appendPOD<uint32_t>(dataVec, e.size);\n> >> +               appendPOD<uint32_t>(dataVec, e.alignment);\n> >> +               appendPOD<uint32_t>(dataVec, e.numElements);\n> >> +               appendPOD<uint32_t>(dataVec, e.type);\n> >> +               appendPOD<uint8_t>(dataVec, e.isArray);\n> >> +       }\n> >> +\n> >> +       return { dataVec, {} };\n> >> +}\n> >> +\n> >> +template<>\n> >> +MetadataListPlan\n> >> +IPADataSerializer<MetadataListPlan>::deserialize(std::vector<uint8_t>::const_iterator dataBegin,\n> >> +                                                std::vector<uint8_t>::const_iterator dataEnd,\n> >> +                                                [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsBegin,\n> >> +                                                [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd,\n> >> +                                                [[maybe_unused]] ControlSerializer *cs)\n> >> +{\n> >> +       MetadataListPlan ret;\n> >> +       std::size_t offset = 0;\n> >> +\n> >> +       auto n = readPOD<uint32_t>(dataBegin, 0, dataEnd);\n> >> +       offset += sizeof(n);\n> >> +\n> >> +       while (n--) {\n> >> +               auto tag = readPOD<uint32_t>(dataBegin, offset, dataEnd);\n> >> +               offset += sizeof(tag);\n> >> +\n> >> +               auto size = readPOD<uint32_t>(dataBegin, offset, dataEnd);\n> >> +               offset += sizeof(size);\n> >> +\n> >> +               auto alignment = readPOD<uint32_t>(dataBegin, offset, dataEnd);\n> >> +               offset += sizeof(alignment);\n> >> +\n> >> +               auto numElements = readPOD<uint32_t>(dataBegin, offset, dataEnd);\n> >> +               offset += sizeof(numElements);\n> >> +\n> >> +               auto type = readPOD<uint32_t>(dataBegin, offset, dataEnd);\n> >> +               offset += sizeof(type);\n> >> +\n> >> +               auto isArray = readPOD<uint8_t>(dataBegin, offset, dataEnd);\n> >> +               offset += sizeof(isArray);\n> >> +\n> >> +               [[maybe_unused]] bool ok = ret.set(tag,\n> >> +                                                  size, alignment,\n> >> +                                                  numElements, static_cast<ControlType>(type), isArray);\n> >> +               ASSERT(ok);\n> > \n> > The other deserializers return empty data instead of loudly crashing\n> > everything. Should we make the other deserializers loudly crash everything as\n> > well or is it better to return an empty object?\n> \n> I think this could be made to return an empty object. I'm hoping that a new version of\n> https://patchwork.libcamera.org/patch/23373/ will be merged at some point, and then the\n> error handling can be moved out of the deserializers.\n\nOh yeah it would be nice to get that in. Until that's in though I'd prefer this\nto return an empty object instead of assert.\n\nWith that changed,\n\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n\n> \n> \n> Regards,\n> Barnabás Pőcze\n> \n> > \n> > \n> > Thanks,\n> > \n> > Paul\n> > \n> >> +       }\n> >> +\n> >> +       return ret;\n> >> +}\n> >> +\n> >> +template<>\n> >> +MetadataListPlan\n> >> +IPADataSerializer<MetadataListPlan>::deserialize(std::vector<uint8_t>::const_iterator dataBegin,\n> >> +                                                std::vector<uint8_t>::const_iterator dataEnd,\n> >> +                                                ControlSerializer *cs)\n> >> +{\n> >> +       return deserialize(dataBegin, dataEnd, {}, {}, cs);\n> >> +}\n> >> +\n> >> +template<>\n> >> +MetadataListPlan\n> >> +IPADataSerializer<MetadataListPlan>::deserialize(const std::vector<uint8_t> &data,\n> >> +                                                ControlSerializer *cs)\n> >> +{\n> >> +       return deserialize(data.cbegin(), data.end(), cs);\n> >> +}\n> >> +\n> >> +template<>\n> >> +MetadataListPlan\n> >> +IPADataSerializer<MetadataListPlan>::deserialize(const std::vector<uint8_t> &data,\n> >> +                                                const std::vector<SharedFD> &fds,\n> >> +                                                ControlSerializer *cs)\n> >> +{\n> >> +       return deserialize(data.cbegin(), data.end(), fds.cbegin(), fds.end(), cs);\n> >> +}\n> >> +\n> >>   #endif /* __DOXYGEN__ */\n> >>\n> >>   } /* namespace libcamera */\n> >> diff --git a/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl b/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl\n> >> index 3942e5708..b3774cd64 100644\n> >> --- a/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl\n> >> +++ b/utils/codegen/ipc/generators/libcamera_templates/core_ipa_interface.h.tmpl\n> >> @@ -21,6 +21,7 @@\n> >>   #include <libcamera/controls.h>\n> >>   #include <libcamera/framebuffer.h>\n> >>   #include <libcamera/geometry.h>\n> >> +#include <libcamera/metadata_list_plan.h>\n> >>\n> >>   #include <libcamera/ipa/ipa_interface.h>\n> >>\n> >> --\n> >> 2.50.1\n> >>\n>","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 7B4C9BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 18 Sep 2025 13:18:47 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 26A7169376;\n\tThu, 18 Sep 2025 15:18:47 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7744262C3B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 18 Sep 2025 15:18:43 +0200 (CEST)","from neptunite.rasen.tech (unknown\n\t[IPv6:2404:7a81:160:2100:7cf2:5f58:dd2a:9ec1])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 6AFAA558;\n\tThu, 18 Sep 2025 15:17:23 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"P0pQd23T\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1758201444;\n\tbh=Y5HLjaX/6cgV4DdoOix8ZGA8n7xHSwPNRIZ8Az0e6Sg=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=P0pQd23Tes6t/ab+oBhscrrAAStlnMYeKj7/txyZo0ypz7OYJsK30zduNZseGq7bM\n\tAqieKvmYIv55G9hHjVk0Lkn+bAPiLqCmys0npSXMtpWsuwFXBHjGTaBZn3RWvvzVWd\n\tYUCTDpaIrkqsNrpYHV0zJEEP/TnHSZRBoFkFXEgc=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<de173aa4-0a11-4eb3-915e-124283062255@ideasonboard.com>","References":"<20250721104622.1550908-1-barnabas.pocze@ideasonboard.com>\n\t<20250721104622.1550908-10-barnabas.pocze@ideasonboard.com>\n\t<Qa027RA4yiPgdVi-0oC94iqNdSQO1Wt8zs2hZWLWO5jqVZD8SvCCKVB4s3FZXDQqawjNKIGvTjC9QmmSQ8dUhw==@protonmail.internalid>\n\t<175818471884.2127323.11718397074252430395@neptunite.rasen.tech>\n\t<de173aa4-0a11-4eb3-915e-124283062255@ideasonboard.com>","Subject":"Re: [RFC PATCH v2 09/22] libcamera: ipa_data_serializer: Support\n\t`MetadataListPlan`","From":"Paul Elder <paul.elder@ideasonboard.com>","Cc":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Thu, 18 Sep 2025 22:18:37 +0900","Message-ID":"<175820151722.2127323.3917639411146082387@neptunite.rasen.tech>","User-Agent":"alot/0.0.0","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>"}}]