Show a patch.

GET /api/patches/26926/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 26926,
    "url": "https://patchwork.libcamera.org/api/patches/26926/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/26926/",
    "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": "<20260618-rppx1-ipa-v1-11-32337264cfcd@ideasonboard.com>",
    "date": "2026-06-18T10:18:50",
    "name": "[11/14] ipa: rppx1: Add RPP-X1 IPA skeleton",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "2bf4677b94630846aa2f1ce56e4bc3ec6d1b2406",
    "submitter": {
        "id": 143,
        "url": "https://patchwork.libcamera.org/api/people/143/?format=api",
        "name": "Jacopo Mondi",
        "email": "jacopo.mondi@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/26926/mbox/",
    "series": [
        {
            "id": 6003,
            "url": "https://patchwork.libcamera.org/api/series/6003/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=6003",
            "date": "2026-06-18T10:18:39",
            "name": "libcamera: Add support for R-Car Gen4 and RPP-X1 ISP",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/6003/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/26926/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/26926/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 06E76C3308\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 18 Jun 2026 10:19:11 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B0C5562B2E;\n\tThu, 18 Jun 2026 12:19:10 +0200 (CEST)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CCCD1629E1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 18 Jun 2026 12:19:00 +0200 (CEST)",
            "from [192.168.125.177] (mob-109-113-4-199.net.vodafone.it\n\t[109.113.4.199])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 34B242908;\n\tThu, 18 Jun 2026 12:18:25 +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=\"GdyoZiod\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1781777905;\n\tbh=FuZvmNCSrt8DCEum16FJpPu5QVKLW50Nfcxw0/qrA5M=;\n\th=From:Date:Subject:References:In-Reply-To:To:Cc:From;\n\tb=GdyoZiodwUkP6lTWld0g0Zj3GsF6UTt6h3QWfFoAnJbReDMbnj+ifFYrrH7DgwVeR\n\tF/8w6Z7hi4wwjKEQtYd9QHf/kqDScmarK1fDhj+NzUKZqSqJfvWtTCEIIaYjk0+X76\n\tAfaQvbqnJO8Fij032iBfoBRPT/vw45ubu9K0xKCY=",
        "From": "Jacopo Mondi <jacopo.mondi@ideasonboard.com>",
        "Date": "Thu, 18 Jun 2026 12:18:50 +0200",
        "Subject": "[PATCH 11/14] ipa: rppx1: Add RPP-X1 IPA skeleton",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "7bit",
        "Message-Id": "<20260618-rppx1-ipa-v1-11-32337264cfcd@ideasonboard.com>",
        "References": "<20260618-rppx1-ipa-v1-0-32337264cfcd@ideasonboard.com>",
        "In-Reply-To": "<20260618-rppx1-ipa-v1-0-32337264cfcd@ideasonboard.com>",
        "To": "=?utf-8?q?Niklas_S=C3=B6derlund?=\n\t<niklas.soderlund+renesas@ragnatech.se>, \n\tlibcamera-devel@lists.libcamera.org",
        "Cc": "Jacopo Mondi <jacopo.mondi@ideasonboard.com>",
        "X-Mailer": "b4 0.14.3",
        "X-Developer-Signature": "v=1; a=openpgp-sha256; l=17071;\n\ti=jacopo.mondi@ideasonboard.com; h=from:subject:message-id;\n\tbh=FuZvmNCSrt8DCEum16FJpPu5QVKLW50Nfcxw0/qrA5M=;\n\tb=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBqM8YKnIYD382Xq+EpMicwe0ueol0wfpqrFE8AO\n\tfZtXe14XsyJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCajPGCgAKCRByNAaPFqFW\n\tPHGfD/9GoZDbW/Flyyq+HhMYKzyja8MzKdrCi/iPbW3HWkL9eF4ecwZDMo7PKmISFUsG2vVIwSD\n\tPx8gxViN2flKJ0np3Ose1Q7Ktd0vT8bZf47TDyrHTAilbEcsDkcscIMDr3TNhR+4Ej2bUWoMGqd\n\tEcpCakVCJZb/Wx0q1+E3A9WL+ZKI1WnxQdyWFZ1x95Hhmrfcky3qJYmzUudn05IFBdmYcYwvehz\n\tm/ceig2wU4/iLqS9qWG7e49imhDWdhM5b1Pcni9PcSlQ75h5Ufji1+0rbuHvUkuPuLALWTGS9QM\n\tA6qZ6uLNEV9jC/vOO81GglcMBMYW5vTdDI2/i9nBehcmcEf2JZ+piCxYJcgetU3EQwVg10Kdpy7\n\taYY5jO1SvFjNyc3RXDbZoL60mfRWN4kGxS50wTaCwvORKqU9t3hlcIJOkRFNkxucAeH6zhYvgh+\n\tmsTbDB6TQJ5kKkHcOD1dSrUYyntb59pM8TkOhvU1BGWvhLacDy6elULMtt4WZSRViUdVLKDMsyE\n\tTBFtGftMkjDw4RCW4Z8058UpB0i1XOB9EbI3f9V3JQp/ZU4uj6uRy4pJiPCEqrYFVKkfPtgSvYA\n\txLyKLN5yT9L1iGXQW8t13FMHCPqidU9oJw0naq2QnbC4zNIoM3/izCRHps9IqJuI09QqXs6Hczt\n\t8P7bKQEMy0g5cqg==",
        "X-Developer-Key": "i=jacopo.mondi@ideasonboard.com; a=openpgp;\n\tfpr=72392EDC88144A65C701EA9BA5826A2587AD026B",
        "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": "Add the infrastructure for the RPP-X1 without any registered algorithm\nbut with the definition of the IPA module interface and the IPA context.\n\nSigned-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n---\n Documentation/Doxyfile-common.in  |   1 +\n include/libcamera/ipa/meson.build |   1 +\n include/libcamera/ipa/rppx1.mojom |  41 ++++++\n meson_options.txt                 |   4 +-\n src/ipa/meson.build               |   1 +\n src/ipa/rppx1/ipa_context.cpp     |  63 +++++++++\n src/ipa/rppx1/ipa_context.h       |  55 ++++++++\n src/ipa/rppx1/meson.build         |  26 ++++\n src/ipa/rppx1/module.h            |  27 ++++\n src/ipa/rppx1/rppx1.cpp           | 280 ++++++++++++++++++++++++++++++++++++++\n 10 files changed, 497 insertions(+), 2 deletions(-)",
    "diff": "diff --git a/Documentation/Doxyfile-common.in b/Documentation/Doxyfile-common.in\nindex f11ec593d5ae..131fdcc6083f 100644\n--- a/Documentation/Doxyfile-common.in\n+++ b/Documentation/Doxyfile-common.in\n@@ -37,6 +37,7 @@ EXCLUDE_PATTERNS       = @TOP_BUILDDIR@/include/libcamera/ipa/*_serializer.h \\\n                          @TOP_BUILDDIR@/include/libcamera/ipa/mali-c55_*.h \\\n                          @TOP_BUILDDIR@/include/libcamera/ipa/raspberrypi_*.h \\\n                          @TOP_BUILDDIR@/include/libcamera/ipa/rkisp1_*.h \\\n+                         @TOP_BUILDDIR@/include/libcamera/ipa/rppx1_*.h \\\n                          @TOP_BUILDDIR@/include/libcamera/ipa/vimc_*.h\n \n EXCLUDE_SYMBOLS        = libcamera::BoundMethodArgs \\\ndiff --git a/include/libcamera/ipa/meson.build b/include/libcamera/ipa/meson.build\nindex 3ee3ada303c0..9ac15546102f 100644\n--- a/include/libcamera/ipa/meson.build\n+++ b/include/libcamera/ipa/meson.build\n@@ -66,6 +66,7 @@ pipeline_ipa_mojom_mapping = {\n     'ipu3': 'ipu3.mojom',\n     'mali-c55': 'mali-c55.mojom',\n     'rkisp1': 'rkisp1.mojom',\n+    'rcar-gen4': 'rppx1.mojom',\n     'rpi/pisp': 'raspberrypi.mojom',\n     'rpi/vc4': 'raspberrypi.mojom',\n     'simple': 'soft.mojom',\ndiff --git a/include/libcamera/ipa/rppx1.mojom b/include/libcamera/ipa/rppx1.mojom\nnew file mode 100644\nindex 000000000000..4abbebb24f85\n--- /dev/null\n+++ b/include/libcamera/ipa/rppx1.mojom\n@@ -0,0 +1,41 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+\n+/*\n+ * \\todo Document the interface and remove the related EXCLUDE_PATTERNS entry.\n+ */\n+\n+module ipa.rppx1;\n+\n+import \"include/libcamera/ipa/core.mojom\";\n+\n+struct IPAConfigInfo {\n+\tlibcamera.IPACameraSensorInfo sensorInfo;\n+\tlibcamera.ControlInfoMap sensorControls;\n+};\n+\n+interface IPARppX1Interface {\n+\tinit(libcamera.IPASettings settings,\n+\t     libcamera.IPACameraSensorInfo sensorInfo,\n+\t     libcamera.ControlInfoMap sensorControls)\n+\t\t=> (int32 ret, libcamera.ControlInfoMap ipaControls);\n+\tstart() => (int32 ret);\n+\tstop();\n+\n+\tconfigure(IPAConfigInfo configInfo,\n+\t\t  map<uint32, libcamera.IPAStream> streamConfig)\n+\t\t=> (int32 ret, libcamera.ControlInfoMap ipaControls);\n+\n+\tmapBuffers(array<libcamera.IPABuffer> buffers);\n+\tunmapBuffers(array<uint32> ids);\n+\n+\t[async] queueRequest(uint32 frame, libcamera.ControlList reqControls);\n+\t[async] computeParams(uint32 frame, uint32 bufferId);\n+\t[async] processStats(uint32 frame, uint32 bufferId,\n+\t\t\t     libcamera.ControlList sensorControls);\n+};\n+\n+interface IPARppX1EventInterface {\n+\tparamsComputed(uint32 frame, uint32 bytesused);\n+\tsetSensorControls(uint32 frame, libcamera.ControlList sensorControls);\n+\tmetadataReady(uint32 frame, libcamera.ControlList metadata);\n+};\ndiff --git a/meson_options.txt b/meson_options.txt\nindex 20baacc4fc65..0aa3aef24edd 100644\n--- a/meson_options.txt\n+++ b/meson_options.txt\n@@ -48,8 +48,8 @@ option('gstreamer',\n \n option('ipas',\n         type : 'array',\n-        choices : ['ipu3', 'mali-c55', 'rkisp1', 'rpi/pisp', 'rpi/vc4', 'simple',\n-                   'vimc'],\n+        choices : ['ipu3', 'mali-c55', 'rkisp1', 'rppx1', 'rpi/pisp', 'rpi/vc4',\n+                   'simple', 'vimc'],\n         description : 'Select which IPA modules to build')\n \n option('lc-compliance',\ndiff --git a/src/ipa/meson.build b/src/ipa/meson.build\nindex c583c7efdd35..411d043021f8 100644\n--- a/src/ipa/meson.build\n+++ b/src/ipa/meson.build\n@@ -27,6 +27,7 @@ ipa_sign = files('ipa-sign.sh')\n supported_ipas = {\n     'ipu3':       'ipu3',\n     'mali-c55':   'mali-c55',\n+    'rcar-gen4':  'rppx1',\n     'rkisp1':     'rkisp1',\n     'rpi/pisp':   'rpi/pisp',\n     'rpi/vc4':    'rpi/vc4',\ndiff --git a/src/ipa/rppx1/ipa_context.cpp b/src/ipa/rppx1/ipa_context.cpp\nnew file mode 100644\nindex 000000000000..5ac60dfc7bf6\n--- /dev/null\n+++ b/src/ipa/rppx1/ipa_context.cpp\n@@ -0,0 +1,63 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2026 Renesas Electronics Corp.\n+ * Copyright (C) 2026 Ideas on Board Oy\n+ * Copyright (C) 2026 Ragnatech AB\n+ *\n+ * RPP-X1 IPA Context\n+ */\n+\n+#include \"ipa_context.h\"\n+\n+/**\n+ * \\file ipa_context.h\n+ * \\brief Context and state information shared between the algorithms\n+ */\n+\n+namespace libcamera::ipa::rppx1 {\n+\n+/**\n+ * \\struct IPASessionConfiguration\n+ * \\brief Session configuration for the IPA module\n+ */\n+\n+/**\n+ * \\struct IPAActiveState\n+ * \\brief Active state for algorithms\n+ */\n+\n+/**\n+ * \\struct IPAFrameContext\n+ * \\brief Per-frame context for algorithms\n+ */\n+\n+/**\n+ * \\struct IPAContext\n+ * \\brief Global IPA context data shared between all algorithms\n+ *\n+ * \\var IPAContext::sensorInfo\n+ * \\brief The IPA session sensorInfo, immutable during the session\n+ *\n+ * \\var IPAContext::configuration\n+ * \\brief The IPA session configuration, immutable during the session\n+ *\n+ * \\var IPAContext::activeState\n+ * \\brief The IPA active state, storing the latest state for all algorithms\n+ *\n+ * \\var IPAContext::frameContexts\n+ * \\brief Ring buffer of per-frame contexts\n+ *\n+ * \\var IPAContext::ctrlMap\n+ * \\brief The IPA map of controls\n+ *\n+ * \\var IPAContext::camHelper\n+ * \\brief The IPA camera helper\n+ */\n+\n+/**\n+ * \\fn IPAContext::IPAContext\n+ * \\brief Construct the IPA context\n+ * \\param[in] frameContextSize Size of the frame context queue\n+ */\n+\n+} /* namespace libcamera::ipa::rppx1 */\ndiff --git a/src/ipa/rppx1/ipa_context.h b/src/ipa/rppx1/ipa_context.h\nnew file mode 100644\nindex 000000000000..f268a35081bc\n--- /dev/null\n+++ b/src/ipa/rppx1/ipa_context.h\n@@ -0,0 +1,55 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2026 Renesas Electronics Corp.\n+ * Copyright (C) 2026 Ideas on Board Oy\n+ * Copyright (C) 2026 Ragnatech AB\n+ *\n+ * RPP-X1 IPA Context\n+ */\n+\n+#pragma once\n+\n+#include <memory>\n+\n+#include <linux/media/dreamchip/rppx1-config.h>\n+\n+#include <libcamera/controls.h>\n+\n+#include <libcamera/ipa/core_ipa_interface.h>\n+\n+#include <libipa/camera_sensor_helper.h>\n+#include <libipa/fc_queue.h>\n+\n+namespace libcamera {\n+\n+namespace ipa::rppx1 {\n+\n+struct IPASessionConfiguration {\n+};\n+\n+struct IPAActiveState {\n+};\n+\n+struct IPAFrameContext : public FrameContext {\n+};\n+\n+struct IPAContext {\n+\tIPAContext(unsigned int frameContextSize)\n+\t\t: frameContexts(frameContextSize)\n+\t{\n+\t}\n+\n+\tIPACameraSensorInfo sensorInfo;\n+\tIPASessionConfiguration configuration;\n+\tIPAActiveState activeState;\n+\n+\tFCQueue<IPAFrameContext> frameContexts;\n+\n+\tControlInfoMap::Map ctrlMap;\n+\n+\tstd::unique_ptr<CameraSensorHelper> camHelper;\n+};\n+\n+} /* namespace ipa::rppx1 */\n+\n+} /* namespace libcamera*/\ndiff --git a/src/ipa/rppx1/meson.build b/src/ipa/rppx1/meson.build\nnew file mode 100644\nindex 000000000000..8034fe24d241\n--- /dev/null\n+++ b/src/ipa/rppx1/meson.build\n@@ -0,0 +1,26 @@\n+# SPDX-License-Identifier: CC0-1.0\n+\n+ipa_name = 'ipa_rppx1'\n+\n+rppx1_ipa_sources = files([\n+    'ipa_context.cpp',\n+    'rppx1.cpp',\n+])\n+\n+mod = shared_module(ipa_name, rppx1_ipa_sources,\n+                    name_prefix : '',\n+                    include_directories : [ipa_includes],\n+                    dependencies : [libcamera_private, libipa_dep],\n+                    install : true,\n+                    install_dir : ipa_install_dir)\n+\n+if ipa_sign_module\n+    custom_target(ipa_name + '.so.sign',\n+                  input : mod,\n+                  output : ipa_name + '.so.sign',\n+                  command : [ipa_sign, ipa_priv_key, '@INPUT@', '@OUTPUT@'],\n+                  install : false,\n+                  build_by_default : true)\n+endif\n+\n+ipa_names += ipa_name\ndiff --git a/src/ipa/rppx1/module.h b/src/ipa/rppx1/module.h\nnew file mode 100644\nindex 000000000000..0bacff64de8f\n--- /dev/null\n+++ b/src/ipa/rppx1/module.h\n@@ -0,0 +1,27 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2026 Renesas Electronics Corp.\n+ * Copyright (C) 2026 Ideas on Board Oy\n+ * Copyright (C) 2026 Ragnatech AB\n+ *\n+ * RPP-X1 IPA Module\n+ */\n+\n+#pragma once\n+\n+#include <libipa/module.h>\n+\n+#include \"ipa_context.h\"\n+#include \"params.h\"\n+#include \"stats.h\"\n+\n+namespace libcamera {\n+\n+namespace ipa::rppx1 {\n+\n+using Module = ipa::Module<IPAContext, IPAFrameContext, IPACameraSensorInfo,\n+\t\t\t   RppX1Params, RppX1Stats>;\n+\n+} /* namespace ipa::rppx1 */\n+\n+} /* namespace libcamera*/\ndiff --git a/src/ipa/rppx1/rppx1.cpp b/src/ipa/rppx1/rppx1.cpp\nnew file mode 100644\nindex 000000000000..20ca2d292704\n--- /dev/null\n+++ b/src/ipa/rppx1/rppx1.cpp\n@@ -0,0 +1,280 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2026 Renesas Electronics Corp.\n+ * Copyright (C) 2026 Ideas on Board Oy\n+ * Copyright (C) 2026 Ragnatech AB\n+ *\n+ * RPP-X1 Image Processing Algorithms\n+ */\n+\n+#include <algorithm>\n+#include <stdint.h>\n+#include <string.h>\n+\n+#include <libcamera/base/file.h>\n+#include <libcamera/base/log.h>\n+\n+#include <libcamera/controls.h>\n+#include <libcamera/framebuffer.h>\n+\n+#include <libcamera/ipa/ipa_interface.h>\n+#include <libcamera/ipa/ipa_module_info.h>\n+#include <libcamera/ipa/rppx1_ipa_interface.h>\n+\n+#include \"libcamera/internal/formats.h\"\n+#include \"libcamera/internal/mapped_framebuffer.h\"\n+#include \"libcamera/internal/yaml_parser.h\"\n+\n+#include \"algorithms/algorithm.h\"\n+\n+#include \"ipa_context.h\"\n+#include \"params.h\"\n+#include \"stats.h\"\n+\n+namespace libcamera {\n+\n+LOG_DEFINE_CATEGORY(IPARppX1)\n+\n+namespace ipa::rppx1 {\n+\n+/* Maximum number of frame contexts to be held */\n+static constexpr uint32_t kMaxFrameContexts = 16;\n+\n+class IPARppX1 : public IPARppX1Interface, public Module\n+{\n+public:\n+\tIPARppX1();\n+\n+\tint init(const IPASettings &settings,\n+\t\t const IPACameraSensorInfo &sensorInfo,\n+\t\t const ControlInfoMap &sensorControls,\n+\t\t ControlInfoMap *ipaControls) override;\n+\tint start() override;\n+\tvoid stop() override;\n+\n+\tint configure(const IPAConfigInfo &ipaConfig,\n+\t\t      const std::map<uint32_t, IPAStream> &streamConfig,\n+\t\t      ControlInfoMap *ipaControls) override;\n+\tvoid mapBuffers(const std::vector<IPABuffer> &buffers) override;\n+\tvoid unmapBuffers(const std::vector<unsigned int> &ids) override;\n+\n+\tvoid queueRequest(const uint32_t frame, const ControlList &controls) override;\n+\tvoid computeParams(const uint32_t frame, const uint32_t bufferId) override;\n+\tvoid processStats(const uint32_t frame, const uint32_t bufferId,\n+\t\t\t  const ControlList &sensorControls) override;\n+\n+protected:\n+\tstd::string logPrefix() const override;\n+\n+private:\n+\tvoid updateControls(ControlInfoMap *ipaControls);\n+\n+\tstd::map<unsigned int, FrameBuffer> buffers_;\n+\tstd::map<unsigned int, MappedFrameBuffer> mappedBuffers_;\n+\n+\t/* Local parameter storage */\n+\tstruct IPAContext context_;\n+};\n+\n+IPARppX1::IPARppX1()\n+\t: context_(kMaxFrameContexts)\n+{\n+}\n+\n+std::string IPARppX1::logPrefix() const\n+{\n+\treturn \"rppx1\";\n+}\n+\n+void IPARppX1::updateControls(ControlInfoMap *ipaControls)\n+{\n+\tControlInfoMap::Map ctrlMap;\n+\n+\tctrlMap.insert(context_.ctrlMap.begin(), context_.ctrlMap.end());\n+\t*ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls);\n+}\n+\n+int IPARppX1::init(const IPASettings &settings,\n+\t\t   const IPACameraSensorInfo &sensorInfo,\n+\t\t   [[maybe_unused]] const ControlInfoMap &sensorControls,\n+\t\t   [[maybe_unused]] ControlInfoMap *ipaControls)\n+{\n+\tcontext_.sensorInfo = sensorInfo;\n+\n+\tcontext_.camHelper = CameraSensorHelperFactoryBase::create(settings.sensorModel);\n+\tif (!context_.camHelper) {\n+\t\tLOG(IPARppX1, Error)\n+\t\t\t<< \"Failed to create camera sensor helper for \"\n+\t\t\t<< settings.sensorModel;\n+\t\treturn -ENODEV;\n+\t}\n+\n+\t/* Load the tuning data file. */\n+\tFile file(settings.configurationFile);\n+\tif (!file.open(File::OpenModeFlag::ReadOnly)) {\n+\t\tint ret = file.error();\n+\t\tLOG(IPARppX1, Error)\n+\t\t\t<< \"Failed to open configuration file \"\n+\t\t\t<< settings.configurationFile << \": \" << strerror(-ret);\n+\t\treturn ret;\n+\t}\n+\n+\tstd::unique_ptr<libcamera::ValueNode> data = YamlParser::parse(file);\n+\tif (!data)\n+\t\treturn -EINVAL;\n+\n+\tunsigned int version = (*data)[\"version\"].get<uint32_t>(0);\n+\tif (version != 1) {\n+\t\tLOG(IPARppX1, Error)\n+\t\t\t<< \"Invalid tuning file version \" << version;\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!data->contains(\"algorithms\")) {\n+\t\tLOG(IPARppX1, Error)\n+\t\t\t<< \"Tuning file doesn't contain any algorithm\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tint ret = createAlgorithms(context_, (*data)[\"algorithms\"]);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* Initialize controls. */\n+\tupdateControls(ipaControls);\n+\n+\treturn 0;\n+}\n+\n+int IPARppX1::start()\n+{\n+\t/* \\todo Properly handle startup controls. */\n+\treturn 0;\n+}\n+\n+void IPARppX1::stop()\n+{\n+\tcontext_.frameContexts.clear();\n+}\n+\n+int IPARppX1::configure(const IPAConfigInfo &ipaConfig,\n+\t\t\t[[maybe_unused]] const std::map<uint32_t, IPAStream> &streamConfig,\n+\t\t\t[[maybe_unused]] ControlInfoMap *ipaControls)\n+{\n+\t/* Clear the IPA context before the streaming session. */\n+\tcontext_.configuration = {};\n+\tcontext_.activeState = {};\n+\tcontext_.frameContexts.clear();\n+\n+\tconst IPACameraSensorInfo &info = ipaConfig.sensorInfo;\n+\n+\t/* Update the camera controls using the new sensor settings. */\n+\tupdateControls(ipaControls);\n+\n+\tfor (auto const &a : algorithms()) {\n+\t\tAlgorithm *algo = static_cast<Algorithm *>(a.get());\n+\n+\t\tint ret = algo->configure(context_, info);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+void IPARppX1::mapBuffers(const std::vector<IPABuffer> &buffers)\n+{\n+\tfor (const IPABuffer &buffer : buffers) {\n+\t\tauto elem = buffers_.emplace(std::piecewise_construct,\n+\t\t\t\t\t     std::forward_as_tuple(buffer.id),\n+\t\t\t\t\t     std::forward_as_tuple(buffer.planes));\n+\t\tconst FrameBuffer &fb = elem.first->second;\n+\n+\t\tMappedFrameBuffer mappedBuffer(&fb, MappedFrameBuffer::MapFlag::ReadWrite);\n+\t\tif (!mappedBuffer.isValid()) {\n+\t\t\tLOG(IPARppX1, Fatal) << \"Failed to mmap buffer: \"\n+\t\t\t\t\t     << strerror(mappedBuffer.error());\n+\t\t}\n+\n+\t\tmappedBuffers_.emplace(buffer.id, std::move(mappedBuffer));\n+\t}\n+}\n+\n+void IPARppX1::unmapBuffers(const std::vector<unsigned int> &ids)\n+{\n+\tfor (unsigned int id : ids) {\n+\t\tconst auto fb = buffers_.find(id);\n+\t\tif (fb == buffers_.end())\n+\t\t\tcontinue;\n+\n+\t\tmappedBuffers_.erase(id);\n+\t\tbuffers_.erase(id);\n+\t}\n+}\n+\n+void IPARppX1::queueRequest(const uint32_t frame, const ControlList &controls)\n+{\n+\tIPAFrameContext &frameContext = context_.frameContexts.alloc(frame);\n+\n+\tfor (auto const &a : algorithms()) {\n+\t\tAlgorithm *algo = static_cast<Algorithm *>(a.get());\n+\t\tif (algo->disabled_)\n+\t\t\tcontinue;\n+\n+\t\talgo->queueRequest(context_, frame, frameContext, controls);\n+\t}\n+}\n+\n+void IPARppX1::computeParams(const uint32_t frame, const uint32_t bufferId)\n+{\n+\tIPAFrameContext &frameContext = context_.frameContexts.get(frame);\n+\n+\tRppX1Params params(mappedBuffers_.at(bufferId).planes()[0]);\n+\n+\tfor (auto const &algo : algorithms())\n+\t\talgo->prepare(context_, frame, frameContext, &params);\n+\n+\tparamsComputed.emit(frame, params.bytesused());\n+}\n+\n+void IPARppX1::processStats(const uint32_t frame, const uint32_t bufferId,\n+\t\t\t    [[maybe_unused]] const ControlList &sensorControls)\n+{\n+\tIPAFrameContext &frameContext = context_.frameContexts.get(frame);\n+\n+\tControlList metadata(controls::controls);\n+\n+\tauto stats = RppX1Stats(mappedBuffers_.at(bufferId).planes()[0]);\n+\tif (!stats)\n+\t\treturn;\n+\n+\tfor (auto const &a : algorithms()) {\n+\t\tAlgorithm *algo = static_cast<Algorithm *>(a.get());\n+\t\tif (algo->disabled_)\n+\t\t\tcontinue;\n+\t\talgo->process(context_, frame, frameContext, &stats, metadata);\n+\t}\n+\n+\tmetadataReady.emit(frame, metadata);\n+}\n+\n+} /* namespace ipa::rppx1 */\n+\n+/*\n+ * External IPA module interface\n+ */\n+\n+extern \"C\" {\n+const struct IPAModuleInfo ipaModuleInfo = {\n+\tIPA_MODULE_API_VERSION,\n+\t1,\n+\t\"rppx1\",\n+};\n+\n+IPAInterface *ipaCreate()\n+{\n+\treturn new ipa::rppx1::IPARppX1();\n+}\n+}\n+\n+} /* namespace libcamera */\n",
    "prefixes": [
        "11/14"
    ]
}