Show a patch.

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

{
    "id": 24859,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/24859/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/24859/",
    "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": "<20251028170847.2673396-7-rui.wang@ideasonboard.com>",
    "date": "2025-10-28T17:08:36",
    "name": "[v1,07/16] ipa: rkisp1: algorithms: dpf: refactor Dpf init for tuning",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "0aedb6125f30212ca1846fca05b00133c04e4f03",
    "submitter": {
        "id": 241,
        "url": "https://patchwork.libcamera.org/api/1.1/people/241/?format=api",
        "name": "Rui Wang",
        "email": "rui.wang@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/24859/mbox/",
    "series": [
        {
            "id": 5539,
            "url": "https://patchwork.libcamera.org/api/1.1/series/5539/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5539",
            "date": "2025-10-28T17:08:30",
            "name": "[v1,01/16] ipa: rkisp1: algorithms: add Denoise base class shell",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/5539/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/24859/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/24859/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 40F08BE080\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 28 Oct 2025 17:09:18 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C492360841;\n\tTue, 28 Oct 2025 18:09:17 +0100 (CET)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 008A46082B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Oct 2025 18:09:14 +0100 (CET)",
            "from rui-Precision-7560.local (unknown [209.216.122.90])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 1032116CD;\n\tTue, 28 Oct 2025 18:07:24 +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=\"oquti6Uy\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1761671245;\n\tbh=FSFjx2+KBC3XX1PCsgKL4Mp1WBBisM+Ozsd5gNs4tsw=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=oquti6UyYtkkmA1vWz1S7gaAw2naDfOaB9lTT/G6qB6Z8SXVUeSJYwe/F+qE5fiYS\n\tsm+HhM/OT3S7HydAx62SizfvTOlKhl+htrC1nsYzGYBzpmKNtsc+LaTscL+rheHzi6\n\twV8NN2BN7i+iG6OS49mx/dX9X5pKwtAV9X9iB+n0=",
        "From": "Rui Wang <rui.wang@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "Rui Wang <rui.wang@ideasonboard.com>",
        "Subject": "[PATCH v1 07/16] ipa: rkisp1: algorithms: dpf: refactor Dpf init for\n\ttuning",
        "Date": "Tue, 28 Oct 2025 13:08:36 -0400",
        "Message-ID": "<20251028170847.2673396-7-rui.wang@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<20251028170847.2673396-1-rui.wang@ideasonboard.com>",
        "References": "<20251028170847.2673396-1-rui.wang@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": "Replace the inline parsing in init() with a call to parseConfig(). This\nsimplifies init() and allows the parsing logic to be reused. The refactor\nalso adds logging of the parsed base tuning and preserves the base config\nfor manual mode restoration.\n\nThe init method now:\n- Calls parseConfig() to load tuning data\n- Logs the parsed base configuration\n- Caches base config for manual mode restore\n- Logs ISO level count if present\n- Registers controls via getControlMap()\n\nSigned-off-by: Rui Wang <rui.wang@ideasonboard.com>\n---\n src/ipa/rkisp1/algorithms/dpf.cpp | 141 +++++-------------------------\n 1 file changed, 24 insertions(+), 117 deletions(-)",
    "diff": "diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp\nindex d1b89691..a5059741 100644\n--- a/src/ipa/rkisp1/algorithms/dpf.cpp\n+++ b/src/ipa/rkisp1/algorithms/dpf.cpp\n@@ -8,6 +8,7 @@\n #include \"dpf.h\"\n \n #include <algorithm>\n+#include <array>\n #include <string>\n #include <vector>\n \n@@ -47,127 +48,33 @@ Dpf::Dpf()\n int Dpf::init([[maybe_unused]] IPAContext &context,\n \t      const YamlObject &tuningData)\n {\n-\tstd::vector<uint8_t> values;\n-\n-\t/*\n-\t * The domain kernel is configured with a 9x9 kernel for the green\n-\t * pixels, and a 13x9 or 9x9 kernel for red and blue pixels.\n-\t */\n-\tconst YamlObject &dFObject = tuningData[\"DomainFilter\"];\n-\n-\t/*\n-\t * For the green component, we have the 9x9 kernel specified\n-\t * as 6 coefficients:\n-\t *    Y\n-\t *    ^\n-\t *  4 | 6   5   4   5   6\n-\t *  3 |   5   3   3   5\n-\t *  2 | 5   3   2   3   5\n-\t *  1 |   3   1   1   3\n-\t *  0 - 4   2   0   2   4\n-\t * -1 |   3   1   1   3\n-\t * -2 | 5   3   2   3   5\n-\t * -3 |   5   3   3   5\n-\t * -4 | 6   5   4   5   6\n-\t *    +---------|--------> X\n-\t *     -4....-1 0 1 2 3 4\n-\t */\n-\tvalues = dFObject[\"g\"].getList<uint8_t>().value_or(std::vector<uint8_t>{});\n-\tif (values.size() != RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS) {\n-\t\tLOG(RkISP1Dpf, Error)\n-\t\t\t<< \"Invalid 'DomainFilter:g': expected \"\n-\t\t\t<< RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS\n-\t\t\t<< \" elements, got \" << values.size();\n+\t/* Parse tuning block */\n+\tif (!parseConfig(tuningData))\n \t\treturn -EINVAL;\n-\t}\n \n-\tstd::copy_n(values.begin(), values.size(),\n-\t\t    std::begin(config_.g_flt.spatial_coeff));\n-\n-\tconfig_.g_flt.gr_enable = true;\n-\tconfig_.g_flt.gb_enable = true;\n-\n-\t/*\n-\t * For the red and blue components, we have the 13x9 kernel specified\n-\t * as 6 coefficients:\n-\t *\n-\t *    Y\n-\t *    ^\n-\t *  4 | 6   5   4   3   4   5   6\n-\t *    |\n-\t *  2 | 5   4   2   1   2   4   5\n-\t *    |\n-\t *  0 - 5   3   1   0   1   3   5\n-\t *    |\n-\t * -2 | 5   4   2   1   2   4   5\n-\t *    |\n-\t * -4 | 6   5   4   3   4   5   6\n-\t *    +-------------|------------> X\n-\t *     -6  -4  -2   0   2   4   6\n-\t *\n-\t * For a 9x9 kernel, columns -6 and 6 are dropped, so coefficient\n-\t * number 6 is not used.\n-\t */\n-\tvalues = dFObject[\"rb\"].getList<uint8_t>().value_or(std::vector<uint8_t>{});\n-\tif (values.size() != RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS &&\n-\t    values.size() != RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS - 1) {\n-\t\tLOG(RkISP1Dpf, Error)\n-\t\t\t<< \"Invalid 'DomainFilter:rb': expected \"\n-\t\t\t<< RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS - 1\n-\t\t\t<< \" or \" << RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS\n-\t\t\t<< \" elements, got \" << values.size();\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tconfig_.rb_flt.fltsize = values.size() == RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS\n-\t\t\t       ? RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9\n-\t\t\t       : RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9;\n-\n-\tstd::copy_n(values.begin(), values.size(),\n-\t\t    std::begin(config_.rb_flt.spatial_coeff));\n-\n-\tconfig_.rb_flt.r_enable = true;\n-\tconfig_.rb_flt.b_enable = true;\n-\n-\t/*\n-\t * The range kernel is configured with a noise level lookup table (NLL)\n-\t * which stores a piecewise linear function that characterizes the\n-\t * sensor noise profile as a noise level function curve (NLF).\n-\t */\n-\tconst YamlObject &rFObject = tuningData[\"NoiseLevelFunction\"];\n-\n-\tstd::vector<uint16_t> nllValues;\n-\tnllValues = rFObject[\"coeff\"].getList<uint16_t>().value_or(std::vector<uint16_t>{});\n-\tif (nllValues.size() != RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS) {\n-\t\tLOG(RkISP1Dpf, Error)\n-\t\t\t<< \"Invalid 'RangeFilter:coeff': expected \"\n-\t\t\t<< RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS\n-\t\t\t<< \" elements, got \" << nllValues.size();\n-\t\treturn -EINVAL;\n-\t}\n+\t/* Log parsed base tuning (counts are always full-sized for base). */\n+\tLOG(RkISP1Dpf, Info)\n+\t\t<< \"DPF init: base tuning parsed, G coeffs=\"\n+\t\t<< RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS\n+\t\t<< \", RB fltsize=\"\n+\t\t<< (config_.rb_flt.fltsize == RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9 ? \"13x9\" : \"9x9\")\n+\t\t<< \", NLL coeffs=\" << RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS\n+\t\t<< \", NLL scale=\"\n+\t\t<< (config_.nll.scale_mode == RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC ? \"log\" : \"linear\")\n+\t\t<< \", Strength (r,g,b)=\"\n+\t\t<< (int)strengthConfig_.r << \",\" << (int)strengthConfig_.g\n+\t\t<< \",\" << (int)strengthConfig_.b;\n+\n+\t/* Preserve base (non-ISO) YAML configuration for restoration after manual mode. */\n+\tbaseConfig_ = config_;\n+\tbaseStrengthConfig_ = strengthConfig_;\n \n-\tstd::copy_n(nllValues.begin(), nllValues.size(),\n-\t\t    std::begin(config_.nll.coeff));\n-\n-\tstd::string scaleMode = rFObject[\"scale-mode\"].get<std::string>(\"\");\n-\tif (scaleMode == \"linear\") {\n-\t\tconfig_.nll.scale_mode = RKISP1_CIF_ISP_NLL_SCALE_LINEAR;\n-\t} else if (scaleMode == \"logarithmic\") {\n-\t\tconfig_.nll.scale_mode = RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC;\n-\t} else {\n-\t\tLOG(RkISP1Dpf, Error)\n-\t\t\t<< \"Invalid 'RangeFilter:scale-mode': expected \"\n-\t\t\t<< \"'linear' or 'logarithmic' value, got \"\n-\t\t\t<< scaleMode;\n-\t\treturn -EINVAL;\n+\t/* Optional ISO-banded tuning */\n+\tif (useIsoLevels_) {\n+\t\tLOG(RkISP1Dpf, Info)\n+\t\t\t<< \"DPF init: loaded \" << isoLevels_.size()\n+\t\t\t<< \" ISO level(s) from tuning\";\n \t}\n-\n-\tconst YamlObject &fSObject = tuningData[\"FilterStrength\"];\n-\n-\tstrengthConfig_.r = fSObject[\"r\"].get<uint16_t>(64);\n-\tstrengthConfig_.g = fSObject[\"g\"].get<uint16_t>(64);\n-\tstrengthConfig_.b = fSObject[\"b\"].get<uint16_t>(64);\n-\n \treturn 0;\n }\n \n",
    "prefixes": [
        "v1",
        "07/16"
    ]
}