Patch Detail
Show a patch.
GET /api/patches/9385/?format=api
{ "id": 9385, "url": "https://patchwork.libcamera.org/api/patches/9385/?format=api", "web_url": "https://patchwork.libcamera.org/patch/9385/", "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": "<20200826110926.67192-2-paul.elder@ideasonboard.com>", "date": "2020-08-26T11:09:10", "name": "[libcamera-devel,RFC,01/17] IPA: IPC: raspberrypi: Add data definition and generated header", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "d25c9db38d55a93455aca6f74e0e1845b76e2774", "submitter": { "id": 17, "url": "https://patchwork.libcamera.org/api/people/17/?format=api", "name": "Paul Elder", "email": "paul.elder@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/9385/mbox/", "series": [ { "id": 1243, "url": "https://patchwork.libcamera.org/api/series/1243/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=1243", "date": "2020-08-26T11:09:09", "name": "[libcamera-devel,RFC,01/17] IPA: IPC: raspberrypi: Add data definition and generated header", "version": 1, "mbox": "https://patchwork.libcamera.org/series/1243/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/9385/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/9385/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 5CF69BD87E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 26 Aug 2020 11:09:53 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2872A628BB;\n\tWed, 26 Aug 2020 13:09:53 +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 36715628BB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 26 Aug 2020 13:09:51 +0200 (CEST)", "from pyrite.rasen.tech (unknown\n\t[IPv6:2400:4051:61:600:2c71:1b79:d06d:5032])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 5B2AC9CE;\n\tWed, 26 Aug 2020 13:09:49 +0200 (CEST)" ], "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"TYfwQ0rY\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1598440190;\n\tbh=F5tkcbjIQGxN2c/bWCViW9R213l+wmoPQMh9FZwRSTY=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=TYfwQ0rYP92WjFOrtGD9QOXwpG0geUDokuJ7SIA7XbqNlOATD+2Kn0I3LDfIlJphl\n\tCG3jblHg9SILx3nhOsGQ8r5a/U5aIpKT5GeBQgV7yQ0Xfs+LFAMkcYpzgQowDR4kPa\n\tYhWAwnCma+iaRzwMCT3H7TWMv2/f/+OXINrn57kI=", "From": "Paul Elder <paul.elder@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Wed, 26 Aug 2020 20:09:10 +0900", "Message-Id": "<20200826110926.67192-2-paul.elder@ideasonboard.com>", "X-Mailer": "git-send-email 2.27.0", "In-Reply-To": "<20200826110926.67192-1-paul.elder@ideasonboard.com>", "References": "<20200826110926.67192-1-paul.elder@ideasonboard.com>", "MIME-Version": "1.0", "Subject": "[libcamera-devel] [RFC PATCH 01/17] IPA: IPC: raspberrypi: Add data\n\tdefinition and generated header", "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>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "This patch shows what the data definition for the IPA interface for\nraspberrypi might look like, as well as the corresponding generated\nheader, with the data definition file as the source. This first patch is\nmeant to show what the pipeline/IPA author would have to write/agree\nupon, and what the corresponding generated header would look like.\n\nThe data defition file, as seen in raspberrypi.mojom, uses the mojo\nsyntax [1]. To define the IPA interface, functions must be defined as\nshown in interface RPiIPAInterface. These functions are for the pipeline\nhandler to call. For functions that the IPA calls, via signals, are\ndefined in interface RPiIPACallbackInterface (we'll probably pick up\nwhich interface is for which by magic names and extract the pipeline/IPA\nname).\n\nAny functions and any data structures can be used. Data structures that\nthat are specific to the pipeline/IPA must be defined in the same file\n(eg. RPiConfigureParams, RPiEventParams, RPiActionParams, etc). Any\nother data structures (eg. IPAStream, IPABuffer, ControlInfoMap) must\nhave de/serializers implemented. I have implemented de/serializers for a\nfew data structures that I think are important.\n\nThere are some rules to the interface definition:\n- any functions that the pipeline calls after start() must not return\n anything (eg. processEvent)\n- any functions that the IPA calls, ever, must not return anything (eg.\n queueFrameAction)\n- any input values, if not POD, will have const and reference in the\n generated function prototype\n- if there is only one output and it is a POD, then it will be a simple\n return value. Otherwise the output(s) will be via pointer output\n parameter(s).\n- maps and arrays are allowed (they will be translated to std::map and\n std::vector, respectively)\n\nraspberrypi_wrapper.h shows the generated header. For this RFC, it is\nhand-generated by me, but I'll make a compiler to automatically generate\nit, given the mojo data definition file. I think this generated file is\nfairly straightforward. It contains the structs and enums as defined in\nthe mojo file. This header is meant to be included by pipelines and IPAs\nso that they can know how to access the data structures passed around in\nthe IPA interface. It will also be used by the generated IPA proxy to\nfigure out how to de/serialize the nested structures.\n\nIn raspberrypi.h we first move the enum away into the mojo definition\nand the generated header. The last hunk is meant to be generated by the\ncompiler as well, though I'm not sure how best to fit it in, since the\nrest of this header is hand-written. RPiCMD will be generated based on\nthe IPA interface defined in the mojo file. Note that both the main\nfunctions and the callbacks share the same enumspace. The\nIPARPiInterface, which implements and IPAInterface, is defined as well,\nalso based on the IPA interface defined in the mojo file. It is a\nvirtual class, since both IPAProxyRPi and IPARPi must implement it since\nthat's how the stack will work:\n\npipeline handler -> IPAProxyRPi --thread--> IPARPi\n \\\n \\-> IPAIPC --IPA--> IPAProxyRPiWorker -> IPARPi\n\nSigned-off-by: Paul Elder <paul.elder@ideasonboard.com>\n---\n include/libcamera/ipa/raspberrypi.h | 61 ++++++---\n include/libcamera/ipa/raspberrypi.mojom | 97 ++++++++++++++\n include/libcamera/ipa/raspberrypi_wrapper.h | 136 ++++++++++++++++++++\n 3 files changed, 276 insertions(+), 18 deletions(-)\n create mode 100644 include/libcamera/ipa/raspberrypi.mojom\n create mode 100644 include/libcamera/ipa/raspberrypi_wrapper.h", "diff": "diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h\nindex ca62990e..fa7efdbc 100644\n--- a/include/libcamera/ipa/raspberrypi.h\n+++ b/include/libcamera/ipa/raspberrypi.h\n@@ -9,24 +9,7 @@\n \n #include <libcamera/control_ids.h>\n #include <libcamera/controls.h>\n-\n-enum RPiConfigParameters {\n-\tRPI_IPA_CONFIG_LS_TABLE = (1 << 0),\n-\tRPI_IPA_CONFIG_STAGGERED_WRITE = (1 << 1),\n-\tRPI_IPA_CONFIG_SENSOR = (1 << 2),\n-};\n-\n-enum RPiOperations {\n-\tRPI_IPA_ACTION_V4L2_SET_STAGGERED = 1,\n-\tRPI_IPA_ACTION_V4L2_SET_ISP,\n-\tRPI_IPA_ACTION_STATS_METADATA_COMPLETE,\n-\tRPI_IPA_ACTION_RUN_ISP,\n-\tRPI_IPA_ACTION_RUN_ISP_AND_DROP_FRAME,\n-\tRPI_IPA_ACTION_EMBEDDED_COMPLETE,\n-\tRPI_IPA_EVENT_SIGNAL_STAT_READY,\n-\tRPI_IPA_EVENT_SIGNAL_ISP_PREPARE,\n-\tRPI_IPA_EVENT_QUEUE_REQUEST,\n-};\n+#include <libcamera/ipa/ipa_interface.h>\n \n enum RPiIpaMask {\n \tID\t\t= 0x0ffff,\n@@ -40,6 +23,10 @@ enum RPiIpaMask {\n \n namespace libcamera {\n \n+struct RPiConfigureParams;\n+struct RPiEventParams;\n+struct RPiActionParams;\n+\n /* List of controls handled by the Raspberry Pi IPA */\n static const ControlInfoMap RPiControls = {\n \t{ &controls::AeEnable, ControlInfo(false, true) },\n@@ -59,6 +46,44 @@ static const ControlInfoMap RPiControls = {\n \t{ &controls::ColourCorrectionMatrix, ControlInfo(-16.0f, 16.0f) },\n };\n \n+// TODO this needs to be automatically generated too\n+enum RPiCMD {\n+\tCMD_INIT = 1,\n+\tCMD_EXIT,\n+\tCMD_START,\n+\tCMD_STOP,\n+\tCMD_CONFIGURE,\n+\tCMD_MAPBUFFERS,\n+\tCMD_UNMAPBUFFERS,\n+\tCMD_PROCESSEVENT,\n+\tCMD_QUEUEFRAMEACTION,\n+};\n+\n+// This needs to be here so that the rpi proxy and worker can include it\n+// Still needs to inherit from IPAInterface for IPAModule to work\n+// TODO This needs to be automatically generated... so put in a different\n+// header too, probably\n+class IPARPiInterface : public IPAInterface\n+{\n+public:\n+\tvirtual ~IPARPiInterface() {};\n+\n+\tvirtual int init(const IPASettings &settings) = 0;\n+\tvirtual int start() = 0;\n+\tvirtual void stop() = 0;\n+\n+\tvirtual void configure(const CameraSensorInfo &sensorInfo,\n+\t\t\t const std::map<unsigned int, IPAStream> &streamConfig,\n+\t\t\t const std::map<unsigned int, const ControlInfoMap> &entityControls,\n+\t\t\t const RPiConfigureParams &data,\n+\t\t\t RPiConfigureParams *response) = 0;\n+\tvirtual void mapBuffers(const std::vector<IPABuffer> &buffers) = 0;\n+\tvirtual void unmapBuffers(const std::vector<unsigned int> &ids) = 0;\n+\tvirtual void processEvent(const RPiEventParams &event) = 0;\n+\n+\tSignal<unsigned int, const RPiActionParams &> queueFrameAction;\n+};\n+\n } /* namespace libcamera */\n \n #endif /* __LIBCAMERA_IPA_INTERFACE_RASPBERRYPI_H__ */\ndiff --git a/include/libcamera/ipa/raspberrypi.mojom b/include/libcamera/ipa/raspberrypi.mojom\nnew file mode 100644\nindex 00000000..3baceb37\n--- /dev/null\n+++ b/include/libcamera/ipa/raspberrypi.mojom\n@@ -0,0 +1,97 @@\n+// automatically add const and & to all inputs (that are not primitives)\n+// automatically add pointer to all outputs (that are not primitives)\n+// if return value is single and primitive, then return as ret value\n+// if return value is multiple or non-primitive, then return as output param\n+interface RPiIPAInterface {\n+\tinit(IPASettings settings) => (int32);\n+\tstart() => (int32);\n+\tstop() => ();\n+\n+\tconfigure(CameraSensorInfo sensorInfo,\n+\t\t map<uint32, IPAStream> streamConfig,\n+\t\t map<uint32, ControlInfoMap> entityControls,\n+\t\t RPiConfigureParams ipaConfig)\n+\t\t=> (RPiConfigureParams result);\n+\n+\t// arrays get turned into vectors\n+\tmapBuffers(array<IPABuffer> buffers) => (int32);\n+\tunmapBuffers(array<uint32> ids) => ();\n+\n+\tprocessEvent(RPiEventParams data) => ();\n+}\n+\n+// these shall not return anything\n+interface RPiIPACallbackInterface {\n+\tqueueFrameAction(uint32, RPiActionPayload) => ();\n+}\n+\n+enum RPiConfigParameters {\n+\tRPI_IPA_CONFIG_LS_TABLE,\n+\tRPI_IPA_CONFIG_STAGGERED_WRITE,\n+\tRPI_IPA_CONFIG_SENSOR,\n+\tRPI_IPA_CONFIG_SEND_FD,\n+};\n+\n+enum RPiEvents {\n+\tRPI_IPA_EVENT_SIGNAL_STAT_READY,\n+\tRPI_IPA_EVENT_SIGNAL_ISP_PREPARE,\n+\tRPI_IPA_EVENT_QUEUE_REQUEST,\n+\tRPI_IPA_EVENT_SEND_FD,\n+};\n+\n+enum RPiActions {\n+\tRPI_IPA_ACTION_V4L2_SET_STAGGERED,\n+\tRPI_IPA_ACTION_V4L2_SET_ISP,\n+\tRPI_IPA_ACTION_STATS_METADATA_COMPLETE,\n+\tRPI_IPA_ACTION_RUN_ISP,\n+\tRPI_IPA_ACTION_RUN_ISP_AND_DROP_FRAME,\n+\tRPI_IPA_ACTION_EMBEDDED_COMPLETE,\n+};\n+\n+// Custom Data containers\n+\n+struct RPiStaggeredWritePayload {\n+\tuint32 gainDelay;\n+\tuint32 exposureDelay;\n+\tuint32 sensorMetadata;\n+};\n+\n+struct RPiIspPreparePayload {\n+\tuint32 embeddedbufferId;\n+\tuint32 bayerbufferId;\n+};\n+\n+struct RPiStatsCompletePayload {\n+\tuint32 bufferId;\n+\tControlList controls;\n+};\n+\n+struct RPiConfigurePayload {\n+\tRPiConfigParameters op;\n+\tFileDescriptor lsTableHandle;\n+\tint32 lsTableHandleStatic;\n+\tRPiStaggeredWritePayload staggeredWriteResult;\n+\tControlList controls;\n+\tint32 bufferFd;\n+};\n+\n+// First level payload\n+\n+struct RPiConfigureParams {\n+\tarray<RPiConfigurePayload> payload;\n+};\n+\n+struct RPiEventParams {\n+\tRPiEvents ev;\n+\tuint32 bufferId;\n+\tRPiIspPreparePayload ispPrepare;\n+\tControlList controls;\n+\tint32 bufferFd;\n+};\n+\n+struct RPiActionParams {\n+\tRPiActions op;\n+\tuint32 bufferId;\n+\tRPiStatsCompletePayload statsComplete;\n+\tControlList controls;\n+};\ndiff --git a/include/libcamera/ipa/raspberrypi_wrapper.h b/include/libcamera/ipa/raspberrypi_wrapper.h\nnew file mode 100644\nindex 00000000..ba44526d\n--- /dev/null\n+++ b/include/libcamera/ipa/raspberrypi_wrapper.h\n@@ -0,0 +1,136 @@\n+// automatically generated by custom compiler\n+\n+#ifndef __LIBCAMERA_IPA_INTERFACE_RASPBERRYPI_FB_H__\n+#define __LIBCAMERA_IPA_INTERFACE_RASPBERRYPI_FB_H__\n+\n+#include \"libcamera/internal/byte_stream_buffer.h\"\n+#include \"libcamera/internal/control_serializer.h\"\n+#include \"libcamera/internal/ipa_data_serializer.h\"\n+\n+#include <libcamera/ipa/ipa_interface.h>\n+#include <libcamera/ipa/raspberrypi.h>\n+\n+#include <deque>\n+#include <vector>\n+\n+namespace libcamera {\n+\n+enum RPiConfigParameters {\n+\tRPI_IPA_CONFIG_LS_TABLE = 1,\n+\tRPI_IPA_CONFIG_STAGGERED_WRITE = 2,\n+\tRPI_IPA_CONFIG_SENSOR = 3,\n+\tRPI_IPA_CONFIG_SEND_FD = 4,\n+};\n+\n+enum RPiEvents {\n+\tRPI_IPA_EVENT_SIGNAL_STAT_READY = 1,\n+\tRPI_IPA_EVENT_SIGNAL_ISP_PREPARE = 2,\n+\tRPI_IPA_EVENT_QUEUE_REQUEST = 3,\n+\tRPI_IPA_EVENT_SEND_FD = 4,\n+};\n+\n+enum RPiActions {\n+\tRPI_IPA_ACTION_V4L2_SET_STAGGERED = 1,\n+\tRPI_IPA_ACTION_V4L2_SET_ISP = 2,\n+\tRPI_IPA_ACTION_STATS_METADATA_COMPLETE = 3,\n+\tRPI_IPA_ACTION_RUN_ISP = 4,\n+\tRPI_IPA_ACTION_RUN_ISP_AND_DROP_FRAME = 5,\n+\tRPI_IPA_ACTION_EMBEDDED_COMPLETE = 6,\n+};\n+\n+struct RPiStaggeredWritePayload\n+{\n+public:\n+\tRPiStaggeredWritePayload() : gainDelay_(0), exposureDelay_(0), sensorMetadata_(0) {}\n+\t~RPiStaggeredWritePayload() {}\n+\n+\tRPiStaggeredWritePayload(uint32_t gainDelay, uint32_t exposureDelay, uint32_t sensorMetadata) : gainDelay_(gainDelay), exposureDelay_(exposureDelay), sensorMetadata_(sensorMetadata) {}\n+\n+\tuint32_t gainDelay_;\n+\tuint32_t exposureDelay_;\n+\tuint32_t sensorMetadata_;\n+};\n+\n+struct RPiIspPreparePayload\n+{\n+public:\n+\tRPiIspPreparePayload() : embeddedbufferId_(0), bayerbufferId_(0) {}\n+\t~RPiIspPreparePayload() {}\n+\n+\tRPiIspPreparePayload(uint32_t embeddedbufferId, uint32_t bayerbufferId) : embeddedbufferId_(embeddedbufferId), bayerbufferId_(bayerbufferId) {}\n+\n+\tuint32_t embeddedbufferId_;\n+\tuint32_t bayerbufferId_;\n+};\n+\n+struct RPiStatsCompletePayload\n+{\n+public:\n+\tRPiStatsCompletePayload() : bufferId_(0) {}\n+\t~RPiStatsCompletePayload() {}\n+\n+\tRPiStatsCompletePayload(uint32_t bufferId, ControlList &controls) : bufferId_(bufferId), controls_(controls) {}\n+\n+\tuint32_t bufferId_;\n+\tControlList controls_;\n+};\n+\n+struct RPiConfigurePayload\n+{\n+public:\n+\tRPiConfigurePayload() : op_(static_cast<RPiConfigParameters>(0)), lsTableHandle_(-1), bufferFd_(0) {}\n+\t~RPiConfigurePayload() {}\n+\n+\tRPiConfigurePayload(enum RPiConfigParameters op, uint32_t lsTableHandle, uint32_t lsTableHandleStatic, RPiStaggeredWritePayload staggeredWriteResult, ControlList controls, int32_t bufferFd) : op_(op), lsTableHandle_(lsTableHandle), lsTableHandleStatic_(lsTableHandleStatic), staggeredWriteResult_(staggeredWriteResult), controls_(controls), bufferFd_(bufferFd) {}\n+\n+\tenum RPiConfigParameters op_;\n+\tFileDescriptor lsTableHandle_;\n+\tint32_t lsTableHandleStatic_;\n+\tRPiStaggeredWritePayload staggeredWriteResult_;\n+\tControlList controls_;\n+\tint32_t bufferFd_;\n+};\n+\n+struct RPiConfigureParams\n+{\n+public:\n+\tRPiConfigureParams() {}\n+\t~RPiConfigureParams() {}\n+\n+\tRPiConfigureParams(std::vector<RPiConfigurePayload> payload) : payload_(payload) {}\n+\n+\tstd::vector<RPiConfigurePayload> payload_;\n+};\n+\n+struct RPiEventParams\n+{\n+public:\n+\tRPiEventParams() : ev_(static_cast<RPiEvents>(0)), bufferId_(0), bufferFd_(0) {}\n+\t~RPiEventParams() {}\n+\n+\tRPiEventParams(enum RPiEvents ev, uint32_t bufferId, RPiIspPreparePayload ispPrepare, ControlList controls, int32_t bufferFd) : ev_(ev), bufferId_(bufferId), ispPrepare_(ispPrepare), controls_(controls), bufferFd_(bufferFd) {}\n+\n+\tenum RPiEvents ev_;\n+\tuint32_t bufferId_;\n+\tRPiIspPreparePayload ispPrepare_;\n+\tControlList controls_;\n+\tint32_t bufferFd_;\n+};\n+\n+struct RPiActionParams\n+{\n+public:\n+\tRPiActionParams() : op_(static_cast<RPiActions>(0)), bufferId_(0) {}\n+\t~RPiActionParams() {}\n+\n+\tRPiActionParams(enum RPiActions op, uint32_t bufferId, RPiStatsCompletePayload statsComplete, ControlList controls) : op_(op), bufferId_(bufferId), statsComplete_(statsComplete), controls_(controls) {}\n+\n+\tenum RPiActions op_;\n+\tuint32_t bufferId_;\n+\tRPiStatsCompletePayload statsComplete_;\n+\tControlList controls_;\n+};\n+\n+} /* namespace libcamera */\n+\n+#endif /* __LIBCAMERA_IPA_INTERFACE_RASPBERRYPI_FB_H__ */\n", "prefixes": [ "libcamera-devel", "RFC", "01/17" ] }