Show a patch.

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

{
    "id": 22542,
    "url": "https://patchwork.libcamera.org/api/patches/22542/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/22542/",
    "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": "<20250113135108.13924-7-mzamazal@redhat.com>",
    "date": "2025-01-13T13:51:03",
    "name": "[v4,6/9] libcamera: software_isp: Add CCM algorithm",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "e9cf77a4dca083ebaac48d3898b9a350c37abe53",
    "submitter": {
        "id": 177,
        "url": "https://patchwork.libcamera.org/api/people/177/?format=api",
        "name": "Milan Zamazal",
        "email": "mzamazal@redhat.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/22542/mbox/",
    "series": [
        {
            "id": 4946,
            "url": "https://patchwork.libcamera.org/api/series/4946/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4946",
            "date": "2025-01-13T13:50:57",
            "name": "Software ISP support for CCM",
            "version": 4,
            "mbox": "https://patchwork.libcamera.org/series/4946/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/22542/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/22542/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 7EEB3C3302\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 13 Jan 2025 13:51:44 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 208F36854D;\n\tMon, 13 Jan 2025 14:51:44 +0100 (CET)",
            "from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.133.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B47776854A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 13 Jan 2025 14:51:41 +0100 (CET)",
            "from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com\n\t(ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63])\n\tby relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n\tcipher=TLS_AES_256_GCM_SHA384) id us-mta-318-j6EDIHypOIWqzxI6bb_OBw-1;\n\tMon, 13 Jan 2025 08:51:36 -0500",
            "from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n\t(mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n\t[10.30.177.17])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\tkey-exchange X25519 server-signature RSA-PSS (2048 bits)\n\tserver-digest SHA256) (No client certificate requested)\n\tby mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTPS id 6AC411955DCC; Mon, 13 Jan 2025 13:51:35 +0000 (UTC)",
            "from mzamazal-thinkpadp1gen3.tpbc.com (unknown [10.45.224.6])\n\tby mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTP id 3173B1955BE3; Mon, 13 Jan 2025 13:51:32 +0000 (UTC)"
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"BhApVKs/\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1736776300;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tcontent-transfer-encoding:content-transfer-encoding:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=pomRdzGX5QZl8kRHCDHGyODvuT2feY78MpIK+hPrMaU=;\n\tb=BhApVKs/zH0vXU/dpmwh8JVkaMJaBYyO8thM6/DT08HYCeeiR7ZptEdQ+cgQGzx/xPMUjY\n\t/Yj5w3fpifcDN5ZolV5UPVA6hjMgiRXEu8zuys6bbEK7kuA+2PfW7oWn8jjDGTNnikxkRr\n\tBcBMNZhfijdtwK0TW3vyneCfe2uYQqw=",
        "X-MC-Unique": "j6EDIHypOIWqzxI6bb_OBw-1",
        "X-Mimecast-MFC-AGG-ID": "j6EDIHypOIWqzxI6bb_OBw",
        "From": "Milan Zamazal <mzamazal@redhat.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "Milan Zamazal <mzamazal@redhat.com>,\n\tRobert Mader <robert.mader@collabora.com>,\n\tHans de Goede <hdegoede@redhat.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>",
        "Subject": "[PATCH v4 6/9] libcamera: software_isp: Add CCM algorithm",
        "Date": "Mon, 13 Jan 2025 14:51:03 +0100",
        "Message-ID": "<20250113135108.13924-7-mzamazal@redhat.com>",
        "In-Reply-To": "<20250113135108.13924-1-mzamazal@redhat.com>",
        "References": "<20250113135108.13924-1-mzamazal@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.17",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-MFC-PROC-ID": "SllGPZCoE-Y98biWOjfZrfcpV_y6l8GY3kcDqaDO058_1736776295",
        "X-Mimecast-Originator": "redhat.com",
        "Content-Transfer-Encoding": "8bit",
        "content-type": "text/plain; charset=\"US-ASCII\"; x-default=true",
        "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": "This patch adds color correction matrix (CCM) algorithm to software ISP.\nIt is based on the corresponding algorithm in rkisp1.\n\nThe primary difference against hardware pipelines is that applying the\nCCM is optional.  Applying CCM causes a significant slowdown, time\nneeded to process a frame raises by 40-90% on tested platforms.  If CCM\nis really needed, it can be applied, if not, it's better to stick\nwithout it.  This can be configured by presence or omission of Ccm\nalgorithm in the tuning file.\n\nCCM is changed only if the determined temperature changes by at least\n100 K (an arbitrarily selected value), to avoid recomputing the matrices\nand lookup tables all the time.\n\nThe outputs of the algorithm are not used yet, they will be enabled in\nfollowup patches.\n\nSigned-off-by: Milan Zamazal <mzamazal@redhat.com>\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n---\n src/ipa/simple/algorithms/ccm.cpp     | 88 +++++++++++++++++++++++++++\n src/ipa/simple/algorithms/ccm.h       | 45 ++++++++++++++\n src/ipa/simple/algorithms/meson.build |  1 +\n src/ipa/simple/ipa_context.h          | 13 ++++\n 4 files changed, 147 insertions(+)\n create mode 100644 src/ipa/simple/algorithms/ccm.cpp\n create mode 100644 src/ipa/simple/algorithms/ccm.h",
    "diff": "diff --git a/src/ipa/simple/algorithms/ccm.cpp b/src/ipa/simple/algorithms/ccm.cpp\nnew file mode 100644\nindex 00000000..3c7fca2d\n--- /dev/null\n+++ b/src/ipa/simple/algorithms/ccm.cpp\n@@ -0,0 +1,88 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2024, Ideas On Board\n+ * Copyright (C) 2024, Red Hat Inc.\n+ *\n+ * Color correction matrix\n+ */\n+\n+#include \"ccm.h\"\n+\n+#include <stdlib.h>\n+\n+#include <libcamera/base/log.h>\n+#include <libcamera/base/utils.h>\n+\n+#include <libcamera/control_ids.h>\n+\n+namespace libcamera {\n+\n+namespace ipa::soft::algorithms {\n+\n+LOG_DEFINE_CATEGORY(IPASoftCcm)\n+\n+unsigned int Ccm::kTemperatureThreshold = 100;\n+\n+int Ccm::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData)\n+{\n+\tint ret = ccm_.readYaml(tuningData[\"ccms\"], \"ct\", \"ccm\");\n+\tif (ret < 0) {\n+\t\tLOG(IPASoftCcm, Warning)\n+\t\t\t<< \"Failed to parse 'ccm' \"\n+\t\t\t<< \"parameter from tuning file; falling back to unit matrix\";\n+\t\tccmEnabled_ = false;\n+\t} else {\n+\t\tccmEnabled_ = true;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+void Ccm::prepare(IPAContext &context, const uint32_t frame,\n+\t\t  IPAFrameContext &frameContext, [[maybe_unused]] DebayerParams *params)\n+{\n+\tcontext.activeState.ccm.enabled = ccmEnabled_;\n+\n+\tif (!ccmEnabled_)\n+\t\treturn;\n+\n+\tunsigned int ct = context.activeState.awb.temperatureK;\n+\n+\t/* Change CCM only on bigger temperature changes. */\n+\tif (frame > 0 &&\n+\t    utils::abs_diff(ct, ct_) < kTemperatureThreshold) {\n+\t\tframeContext.ccm.ccm = context.activeState.ccm.ccm;\n+\t\tcontext.activeState.ccm.changed = false;\n+\t\treturn;\n+\t}\n+\n+\tct_ = ct;\n+\tMatrix<double, 3, 3> ccm = ccm_.getInterpolated(ct);\n+\n+\tcontext.activeState.ccm.ccm = ccm;\n+\tframeContext.ccm.ccm = ccm;\n+\tcontext.activeState.ccm.changed = true;\n+}\n+\n+void Ccm::process([[maybe_unused]] IPAContext &context,\n+\t\t  [[maybe_unused]] const uint32_t frame,\n+\t\t  IPAFrameContext &frameContext,\n+\t\t  [[maybe_unused]] const SwIspStats *stats,\n+\t\t  ControlList &metadata)\n+{\n+\tif (!ccmEnabled_)\n+\t\treturn;\n+\n+\tfloat m[9];\n+\tfor (unsigned int i = 0; i < 3; i++) {\n+\t\tfor (unsigned int j = 0; j < 3; j++)\n+\t\t\tm[i * 3 + j] = frameContext.ccm.ccm[i][j];\n+\t}\n+\tmetadata.set(controls::ColourCorrectionMatrix, m);\n+}\n+\n+REGISTER_IPA_ALGORITHM(Ccm, \"Ccm\")\n+\n+} /* namespace ipa::soft::algorithms */\n+\n+} /* namespace libcamera */\ndiff --git a/src/ipa/simple/algorithms/ccm.h b/src/ipa/simple/algorithms/ccm.h\nnew file mode 100644\nindex 00000000..23481a08\n--- /dev/null\n+++ b/src/ipa/simple/algorithms/ccm.h\n@@ -0,0 +1,45 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2024, Red Hat Inc.\n+ *\n+ * Color correction matrix\n+ */\n+\n+#pragma once\n+\n+#include \"libcamera/internal/matrix.h\"\n+\n+#include <libipa/interpolator.h>\n+\n+#include \"algorithm.h\"\n+\n+namespace libcamera {\n+\n+namespace ipa::soft::algorithms {\n+\n+class Ccm : public Algorithm\n+{\n+public:\n+\tCcm() = default;\n+\t~Ccm() = default;\n+\n+\tint init(IPAContext &context, const YamlObject &tuningData) override;\n+\tvoid prepare(IPAContext &context,\n+\t\t     const uint32_t frame,\n+\t\t     IPAFrameContext &frameContext,\n+\t\t     DebayerParams *params) override;\n+\tvoid process(IPAContext &context, const uint32_t frame,\n+\t\t     IPAFrameContext &frameContext,\n+\t\t     const SwIspStats *stats,\n+\t\t     ControlList &metadata) override;\n+\n+private:\n+\tstatic unsigned int kTemperatureThreshold;\n+\tunsigned int ct_;\n+\tbool ccmEnabled_;\n+\tInterpolator<Matrix<double, 3, 3>> ccm_;\n+};\n+\n+} /* namespace ipa::soft::algorithms */\n+\n+} /* namespace libcamera */\ndiff --git a/src/ipa/simple/algorithms/meson.build b/src/ipa/simple/algorithms/meson.build\nindex 37a2eb53..2d0adb05 100644\n--- a/src/ipa/simple/algorithms/meson.build\n+++ b/src/ipa/simple/algorithms/meson.build\n@@ -4,5 +4,6 @@ soft_simple_ipa_algorithms = files([\n     'awb.cpp',\n     'agc.cpp',\n     'blc.cpp',\n+    'ccm.cpp',\n     'lut.cpp',\n ])\ndiff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h\nindex 607af45a..0def3eef 100644\n--- a/src/ipa/simple/ipa_context.h\n+++ b/src/ipa/simple/ipa_context.h\n@@ -13,6 +13,8 @@\n \n #include <libcamera/controls.h>\n \n+#include \"libcamera/internal/matrix.h\"\n+\n #include <libipa/fc_queue.h>\n \n namespace libcamera {\n@@ -50,6 +52,13 @@ struct IPAActiveState {\n \t\tuint8_t blackLevel;\n \t\tdouble contrast;\n \t} gamma;\n+\n+\tstruct {\n+\t\tMatrix<double, 3, 3> ccm;\n+\t\tbool enabled;\n+\t\tbool changed;\n+\t} ccm;\n+\n \tstruct {\n \t\t/* 0..2 range, 1.0 = normal */\n \t\tstd::optional<double> contrast;\n@@ -57,6 +66,10 @@ struct IPAActiveState {\n };\n \n struct IPAFrameContext : public FrameContext {\n+\tstruct {\n+\t\tMatrix<double, 3, 3> ccm;\n+\t} ccm;\n+\n \tstruct {\n \t\tint32_t exposure;\n \t\tdouble gain;\n",
    "prefixes": [
        "v4",
        "6/9"
    ]
}