Show a patch.

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

{
    "id": 22619,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/22619/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/22619/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/1.1/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": "<20250123114204.79321-5-stefan.klug@ideasonboard.com>",
    "date": "2025-01-23T11:40:54",
    "name": "[v2,04/17] libipa: awb: Add helper functions for AWB mode support",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "1e88969823a1cbc878327c25494bb3a7c0e5b615",
    "submitter": {
        "id": 184,
        "url": "https://patchwork.libcamera.org/api/1.1/people/184/?format=api",
        "name": "Stefan Klug",
        "email": "stefan.klug@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/22619/mbox/",
    "series": [
        {
            "id": 4966,
            "url": "https://patchwork.libcamera.org/api/1.1/series/4966/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4966",
            "date": "2025-01-23T11:40:50",
            "name": "Add Bayesian AWB algorithm to libipa and rkisp1",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/4966/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/22619/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/22619/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 683A4BDE6B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 23 Jan 2025 11:42:25 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1D60F68568;\n\tThu, 23 Jan 2025 12:42:25 +0100 (CET)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7C41861879\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 23 Jan 2025 12:42:22 +0100 (CET)",
            "from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:c0a:33cd:b453:5d3f])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E92751189;\n\tThu, 23 Jan 2025 12:41:18 +0100 (CET)"
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"ib8TBA9b\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1737632479;\n\tbh=5V/ezk+n02YW9xGEUfyyfwQgB7o03lxD91pLbnvbnWw=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=ib8TBA9b0EAnzeDs96e1dnkjJqUsLiWIEyPIg62kTbwf/7bvZQV6HTiGMfhy6GfCD\n\tgGomUHmoJ8Uh0qIVpST7WNn817Wl4RdgN8+EG3JFXKhf3Yo6A4x9DyNCRtlESMU03N\n\tO8mOviRysJZ8zSvdPxmyuHLmLKfGOnIsWHevr27U=",
        "From": "Stefan Klug <stefan.klug@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "Stefan Klug <stefan.klug@ideasonboard.com>,\n\tPaul Elder <paul.elder@ideasonboard.com>,\n\tDaniel Scally <dan.scally@ideasonboard.com>",
        "Subject": "[PATCH v2 04/17] libipa: awb: Add helper functions for AWB mode\n\tsupport",
        "Date": "Thu, 23 Jan 2025 12:40:54 +0100",
        "Message-ID": "<20250123114204.79321-5-stefan.klug@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<20250123114204.79321-1-stefan.klug@ideasonboard.com>",
        "References": "<20250123114204.79321-1-stefan.klug@ideasonboard.com>",
        "MIME-Version": "1.0",
        "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>"
    },
    "content": "The AWB modes are specified in the libcamera core controls. It is\ntherefore quite likely that every AWB algorithm will implement them. Add\nhelper functions for parsing and storing the configured modes in the\nAwbAlgorithm base class.\n\nSigned-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\nReviewed-by: Daniel Scally <dan.scally@ideasonboard.com>\n\n---\n\nChanges in v2:\n- Collected tags\n- Improved documentation\n- Replaced AwbAuto handling with a user supplied default value\n---\n src/ipa/libipa/awb.cpp | 127 +++++++++++++++++++++++++++++++++++++++++\n src/ipa/libipa/awb.h   |  13 +++++\n 2 files changed, 140 insertions(+)",
    "diff": "diff --git a/src/ipa/libipa/awb.cpp b/src/ipa/libipa/awb.cpp\nindex 4db97f6a10fc..62b69dd96238 100644\n--- a/src/ipa/libipa/awb.cpp\n+++ b/src/ipa/libipa/awb.cpp\n@@ -9,6 +9,8 @@\n \n #include <libcamera/base/log.h>\n \n+#include <libcamera/control_ids.h>\n+\n /**\n  * \\file awb.h\n  * \\brief Base classes for AWB algorithms\n@@ -132,6 +134,131 @@ namespace ipa {\n  * \\brief Controls info map for the controls provided by the algorithm\n  */\n \n+/**\n+ * \\var AwbAlgorithm::modes_\n+ * \\brief Map of all configured modes\n+ * \\sa AwbAlgorithm::parseModeConfigs\n+ */\n+\n+/**\n+ * \\class AwbAlgorithm::ModeConfig\n+ * \\brief Holds the configuration of a single AWB mode\n+ *\n+ * Awb modes limit the regulation of the AWB algorithm to a specific range of\n+ * colour temperatures.\n+ */\n+\n+/**\n+ * \\var AwbAlgorithm::ModeConfig::ctLo\n+ * \\brief The lowest valid colour temperature of that mode\n+ */\n+\n+/**\n+ * \\var AwbAlgorithm::ModeConfig::ctHi\n+ * \\brief The highest valid colour temperature of that mode\n+ */\n+\n+/**\n+ * \\brief Parse the mode configurations from the tuning data\n+ * \\param[in] tuningData the YamlObject representing the tuning data\n+ * \\param[in] def The default value for the AwbMode control\n+ *\n+ * Utility function to parse the tuning data for an AwbMode entry and read all\n+ * provided modes. It adds controls::AwbMode to AwbAlgorithm::controls_ and\n+ * populates AwbAlgorithm::modes_. For a list of possible modes see \\ref\n+ * controls::AwbModeEnum.\n+ *\n+ * Each mode entry must contain a \"lo\" and \"hi\" key to specify the lower and\n+ * upper colour temperature of that mode. For example:\n+ *\n+ * \\code{.unparsed}\n+ * algorithms:\n+ *   - Awb:\n+ *     AwbMode:\n+ *       AwbAuto:\n+ *         lo: 2500\n+ *         hi: 8000\n+ *       AwbIncandescent:\n+ *         lo: 2500\n+ *         hi: 3000\n+ *       ...\n+ * \\endcode\n+ *\n+ * If \\a def is supplied but not contained in the the \\a tuningData, -EINVAL is\n+ * returned.\n+ *\n+ * \\sa controls::AwbModeEnum\n+ * \\return Zero on success, negative error code otherwise\n+ */\n+int AwbAlgorithm::parseModeConfigs(const YamlObject &tuningData,\n+\t\t\t\t   const ControlValue &def)\n+{\n+\tstd::vector<ControlValue> availableModes;\n+\n+\tconst YamlObject &yamlModes = tuningData[controls::AwbMode.name()];\n+\tif (!yamlModes.isDictionary()) {\n+\t\tLOG(Awb, Error)\n+\t\t\t<< \"AwbModes must be a dictionary.\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfor (const auto &[modeName, modeDict] : yamlModes.asDict()) {\n+\t\tif (controls::AwbModeNameValueMap.find(modeName) ==\n+\t\t    controls::AwbModeNameValueMap.end()) {\n+\t\t\tLOG(Awb, Warning)\n+\t\t\t\t<< \"Skipping unknown awb mode '\"\n+\t\t\t\t<< modeName << \"'\";\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (!modeDict.isDictionary()) {\n+\t\t\tLOG(Awb, Error)\n+\t\t\t\t<< \"Invalid awb mode '\" << modeName << \"'\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tconst auto &modeValue = static_cast<controls::AwbModeEnum>(\n+\t\t\tcontrols::AwbModeNameValueMap.at(modeName));\n+\n+\t\tModeConfig &config = modes_[modeValue];\n+\n+\t\tauto hi = modeDict[\"hi\"].get<double>();\n+\t\tif (!hi) {\n+\t\t\tLOG(Awb, Error) << \"Failed to read hi param of mode \"\n+\t\t\t\t\t<< modeName;\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tconfig.ctHi = *hi;\n+\n+\t\tauto lo = modeDict[\"lo\"].get<double>();\n+\t\tif (!lo) {\n+\t\t\tLOG(Awb, Error) << \"Failed to read low param of mode \"\n+\t\t\t\t\t<< modeName;\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tconfig.ctLo = *lo;\n+\n+\t\tavailableModes.push_back(modeValue);\n+\t}\n+\n+\tif (modes_.empty()) {\n+\t\tLOG(Awb, Error) << \"No AWB modes configured\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (!def.isNone() &&\n+\t    modes_.find(def.get<controls::AwbModeEnum>()) == modes_.end()) {\n+\t\tconst auto &names = controls::AwbMode.enumerators();\n+\t\tLOG(Awb, Error) << names.at(def.get<controls::AwbModeEnum>())\n+\t\t\t\t<< \" mode is missing in the configuration.\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tcontrols_[&controls::AwbMode] = ControlInfo(availableModes, def);\n+\n+\treturn 0;\n+}\n+\n } /* namespace ipa */\n \n } /* namespace libcamera */\ndiff --git a/src/ipa/libipa/awb.h b/src/ipa/libipa/awb.h\nindex 2dd471606ec4..1f7477c071ac 100644\n--- a/src/ipa/libipa/awb.h\n+++ b/src/ipa/libipa/awb.h\n@@ -7,7 +7,11 @@\n \n #pragma once\n \n+#include <map>\n+\n+#include <libcamera/control_ids.h>\n #include <libcamera/controls.h>\n+\n #include \"libcamera/internal/yaml_parser.h\"\n \n #include \"vector.h\"\n@@ -43,7 +47,16 @@ public:\n \tvirtual void handleControls([[maybe_unused]] const ControlList &controls) {}\n \n protected:\n+\tint parseModeConfigs(const YamlObject &tuningData,\n+\t\t\t     const ControlValue &def = {});\n+\n+\tstruct ModeConfig {\n+\t\tdouble ctHi;\n+\t\tdouble ctLo;\n+\t};\n+\n \tControlInfoMap::Map controls_;\n+\tstd::map<controls::AwbModeEnum, AwbAlgorithm::ModeConfig> modes_;\n };\n \n } /* namespace ipa */\n",
    "prefixes": [
        "v2",
        "04/17"
    ]
}