Show a patch.

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

{
    "id": 25172,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/25172/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/25172/",
    "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": "<20251125000848.4103786-6-rui.wang@ideasonboard.com>",
    "date": "2025-11-25T00:08:42",
    "name": "[v1,05/11] ipa: rkisp1: algorithms: dpf: collect DPF manual overrides",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "7d6f309b72274cd67282fa5a1d46872334d4591e",
    "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/25172/mbox/",
    "series": [
        {
            "id": 5612,
            "url": "https://patchwork.libcamera.org/api/1.1/series/5612/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5612",
            "date": "2025-11-25T00:08:37",
            "name": "ipa: rkisp1: DPF refactor and tuning improvements",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/5612/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/25172/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/25172/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 0681CC3257\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 25 Nov 2025 00:09:16 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A103860A9E;\n\tTue, 25 Nov 2025 01:09:15 +0100 (CET)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0EC55609D8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 25 Nov 2025 01:09:13 +0100 (CET)",
            "from rui-Precision-7560.local (unknown\n\t[IPv6:2607:fea8:935b:7220:cb34:a7b8:53d:5466])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 4599F1785;\n\tTue, 25 Nov 2025 01:07:04 +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=\"jovDiWaF\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1764029224;\n\tbh=thdNjgp4sS/RLvisnBqyFOT/NN/VVpzP0EaqUwophK0=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=jovDiWaFTj/bq34xj3xNR3C68xtCBIeuhj7bxUilZVOtxazhYIVNyN1Ya+vVhJ/ft\n\tNUazNAH7tJwkj3clRKFc+ajnPW+uKjt5qcx+eR6tdsMWZjuA+kYbtOf3q3u8AJAG6S\n\tr1KeFT5FJ9rVWNAqBJDre1eGktx7t2/7zPrIRy+0=",
        "From": "Rui Wang <rui.wang@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "Rui Wang <rui.wang@ideasonboard.com>",
        "Subject": "[PATCH v1 05/11] ipa: rkisp1: algorithms: dpf: collect DPF manual\n\toverrides",
        "Date": "Mon, 24 Nov 2025 19:08:42 -0500",
        "Message-ID": "<20251125000848.4103786-6-rui.wang@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<20251125000848.4103786-1-rui.wang@ideasonboard.com>",
        "References": "<20251125000848.4103786-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": "Implement collectManualOverrides() to capture strength and developer-mode\noverride arrays from control requests. Extend queueRequest() to collect\noverrides in manual mode and mark frames dirty when strength values differ\nfrom the active configuration.\n\nDeveloper mode controls (spatial coefficients, filter size, NLL tables)\nare only collected when devmode is enabled. The function populates the\noverrides_ structure which will be applied during prepare().\n\nSigned-off-by: Rui Wang <rui.wang@ideasonboard.com>\n---\n src/ipa/rkisp1/algorithms/denoise.h   |  5 +-\n src/ipa/rkisp1/algorithms/dpf.cpp     | 66 +++++++++++++++++++++++++\n src/ipa/rkisp1/algorithms/dpf.h       | 23 +++++++++\n src/libcamera/control_ids_rkisp1.yaml | 71 +++++++++++++++++++++++++++\n 4 files changed, 164 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/src/ipa/rkisp1/algorithms/denoise.h b/src/ipa/rkisp1/algorithms/denoise.h\nindex 660f648b..ffe27af8 100644\n--- a/src/ipa/rkisp1/algorithms/denoise.h\n+++ b/src/ipa/rkisp1/algorithms/denoise.h\n@@ -22,6 +22,7 @@ protected:\n \t~DenoiseBaseAlgorithm() = default;\n \tvirtual void setDevMode(bool dev) { devMode_ = dev; }\n \tvirtual bool isDevMode() const { return devMode_; }\n+\n \tvirtual uint32_t computeExposureIndex(const IPAContext &context,\n \t\t\t\t\t      const IPAFrameContext &frameContext) const;\n \ttemplate<typename LevelContainer>\n@@ -31,6 +32,9 @@ protected:\n \t{\n \t\treturn true;\n \t}\n+\tvirtual void collectManualOverrides([[maybe_unused]] const ControlList &controls)\n+\t{\n+\t}\n \tvirtual void handleReductionModeControl([[maybe_unused]] const ControlList &controls,\n \t\t\t\t\t\t[[maybe_unused]] IPAFrameContext &frameContext,\n \t\t\t\t\t\t[[maybe_unused]] IPAContext &context,\n@@ -39,7 +43,6 @@ protected:\n \t}\n \tvirtual int32_t getRunningMode() const { return currentRunMode_; }\n \tvirtual void setRunningMode(int32_t mode) { currentRunMode_ = mode; }\n-\n private:\n \t/**< Developer mode state for advanced controls */\n \tbool devMode_ = false;\ndiff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp\nindex c006fb5c..2d7d6414 100644\n--- a/src/ipa/rkisp1/algorithms/dpf.cpp\n+++ b/src/ipa/rkisp1/algorithms/dpf.cpp\n@@ -358,6 +358,72 @@ void Dpf::loadReductionModeConfig(IPAFrameContext &frameContext)\n \tstrengthConfig_ = it->strength;\n \tframeContext.dpf.update = true;\n }\n+\n+void Dpf::collectManualOverrides(const ControlList &controls)\n+{\n+\tif (const auto &c = controls.get(controls::rkisp1::DpfChannelStrengths); c) {\n+\t\tif (c->size() == 3) {\n+\t\t\toverrides_.strength = DpfStrengthSettings{\n+\t\t\t\tstatic_cast<uint16_t>((*c)[0]),\n+\t\t\t\tstatic_cast<uint16_t>((*c)[1]),\n+\t\t\t\tstatic_cast<uint16_t>((*c)[2])\n+\t\t\t};\n+\t\t}\n+\t}\n+\tif (!isDevMode())\n+\t\treturn;\n+\n+\tif (const auto &c = controls.get(controls::rkisp1::DpfGreenSpatialCoefficients); c) {\n+\t\tif (c->size() == RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS) {\n+\t\t\tDpfSpatialGreenSettings green;\n+\t\t\tstd::copy_n(c->begin(), RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS,\n+\t\t\t\t    green.coeffs.begin());\n+\t\t\toverrides_.spatialGreen = green;\n+\t\t}\n+\t}\n+\tif (const auto &c =\n+\t\t    controls.get(controls::rkisp1::DpfRedBlueSpatialCoefficients);\n+\t    c) {\n+\t\tif (c->size() == RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS) {\n+\t\t\tDpfSpatialRbSettings rb;\n+\t\t\tstd::copy_n(c->begin(), RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS,\n+\t\t\t\t    rb.coeffs.begin());\n+\t\t\trb.size = (config_.rb_flt.fltsize ==\n+\t\t\t\t   RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9)\n+\t\t\t\t\t  ? 1\n+\t\t\t\t\t  : 0;\n+\t\t\toverrides_.spatialRb = rb;\n+\t\t}\n+\t}\n+\tif (const auto &c = controls.get(controls::rkisp1::DpfRbFilterSize); c) {\n+\t\toverrides_.rbSize = *c ? 1 : 0;\n+\t}\n+\tif (const auto &c = controls.get(controls::rkisp1::DpfNoiseLevelLookupCoefficients); c) {\n+\t\tif (c->size() == RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS) {\n+\t\t\tDpfNllSettings nll;\n+\t\t\tstd::copy_n(c->begin(), RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS,\n+\t\t\t\t    nll.coeffs.begin());\n+\t\t\tnll.scaleMode = (config_.nll.scale_mode ==\n+\t\t\t\t\t RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC)\n+\t\t\t\t\t\t? 1\n+\t\t\t\t\t\t: 0;\n+\t\t\toverrides_.nll = nll;\n+\t\t}\n+\t}\n+\tif (const auto &c = controls.get(controls::rkisp1::DpfNoiseLevelLookupScaleMode); c) {\n+\t\tif (overrides_.nll) {\n+\t\t\toverrides_.nll->scaleMode = *c ? 1 : 0;\n+\t\t} else {\n+\t\t\tDpfNllSettings nll;\n+\t\t\tstd::copy_n(std::begin(config_.nll.coeff),\n+\t\t\t\t    RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS,\n+\t\t\t\t    nll.coeffs.begin());\n+\t\t\tnll.scaleMode = *c ? 1 : 0;\n+\t\t\toverrides_.nll = nll;\n+\t\t}\n+\t}\n+}\n+\n /**\n  * \\copydoc libcamera::ipa::Algorithm::queueRequest\n  */\ndiff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h\nindex 928e79d9..4cbd7414 100644\n--- a/src/ipa/rkisp1/algorithms/dpf.h\n+++ b/src/ipa/rkisp1/algorithms/dpf.h\n@@ -35,6 +35,20 @@ private:\n \tstruct rkisp1_cif_isp_dpf_strength_config strengthConfig_;\n \tstruct rkisp1_cif_isp_dpf_config baseConfig_;\n \tstruct rkisp1_cif_isp_dpf_strength_config baseStrengthConfig_;\n+\tstruct DpfStrengthSettings {\n+\t\tuint16_t r, g, b;\n+\t};\n+\tstruct DpfSpatialGreenSettings {\n+\t\tstd::array<uint8_t, RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS> coeffs;\n+\t};\n+\tstruct DpfSpatialRbSettings {\n+\t\tstd::array<uint8_t, RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS> coeffs;\n+\t\tuint8_t size; /* 0=9x9, 1=13x9 */\n+\t};\n+\tstruct DpfNllSettings {\n+\t\tstd::array<uint16_t, RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS> coeffs;\n+\t\tuint8_t scaleMode; /* 0 linear, 1 log */\n+\t};\n \tstruct ExposureIndexLevelConfig {\n \t\tuint32_t maxExposureIndex; /* inclusive upper bound */\n \t\tstruct rkisp1_cif_isp_dpf_config dpf;\n@@ -45,6 +59,14 @@ private:\n \t\tstruct rkisp1_cif_isp_dpf_config dpf;\n \t\tstruct rkisp1_cif_isp_dpf_strength_config strength;\n \t};\n+\tstruct Overrides {\n+\t\tstd::optional<DpfStrengthSettings> strength;\n+\t\tstd::optional<DpfSpatialGreenSettings> spatialGreen;\n+\t\tstd::optional<DpfSpatialRbSettings> spatialRb;\n+\t\tstd::optional<uint8_t> rbSize;\n+\t\tstd::optional<DpfNllSettings> nll;\n+\t\tvoid clear() { *this = Overrides{}; }\n+\t} overrides_;\n \n \tstd::vector<ExposureIndexLevelConfig> exposureIndexLevels_;\n \tstd::vector<ModeConfig> modes_;\n@@ -56,6 +78,7 @@ private:\n \t\t\t\t\tIPAContext &context,\n \t\t\t\t\tuint32_t frame) override;\n \tvoid loadReductionModeConfig(IPAFrameContext &frameContext);\n+\tvoid collectManualOverrides(const ControlList &controls) override;\n \tbool parseConfig(const YamlObject &tuningData) override;\n \tbool parseSingleConfig(const YamlObject &tuningData,\n \t\t\t       rkisp1_cif_isp_dpf_config &config,\ndiff --git a/src/libcamera/control_ids_rkisp1.yaml b/src/libcamera/control_ids_rkisp1.yaml\nindex 3e008ee4..bfd59925 100644\n--- a/src/libcamera/control_ids_rkisp1.yaml\n+++ b/src/libcamera/control_ids_rkisp1.yaml\n@@ -70,4 +70,75 @@ controls:\n           value: 3\n           description: |\n             Reduction mode - uses predefined noise reduction settings from tuning data.\n+  \n+  - DpfChannelStrengths:\n+      type: int32_t\n+      direction: inout\n+      description: |\n+        Override filter strength for R,G,B channels. Values map to hardware\n+        strength registers (0..255 typical). Size must be exactly 3 when set.\n+        Order: R,G,B. If unset the tuning / exposure index level derived strengths apply.\n+      size: [3]\n+\n+  - DpfGreenSpatialCoefficients:\n+      type: int32_t\n+      direction: inout\n+      description: |\n+        Override 9x9 green spatial kernel coefficients (6 values). Order must\n+        follow tuning file convention. Each value 0..63 typical. All 6 required\n+        when provided; otherwise ignored.\n+      size: [6]\n+\n+  - DpfRedBlueSpatialCoefficients:\n+      type: int32_t\n+      direction: inout\n+      description: |\n+        Override Red/Blue spatial kernel coefficients (6 values). Applies to\n+        either 9x9 or 13x9 depending on DpfRbFilterSize. For 9x9 the last\n+        column pair is dropped in hardware. Values 0..63 typical.\n+      size: [6]\n+\n+  - DpfRbFilterSize:\n+      type: int32_t\n+      direction: inout\n+      description: |\n+        Override RB spatial filter size selection.\n+      enum:\n+        - name: DpfRbFilterSize9x9\n+          value: 0\n+          description: Use 9x9 RB domain filter.\n+        - name: DpfRbFilterSize13x9\n+          value: 1\n+          description: Use 13x9 RB domain filter (if coefficients valid).\n+\n+  - DpfNoiseLevelLookupCoefficients:\n+      type: int32_t\n+      direction: inout\n+      description: |\n+        Override Noise Level Lookup (NLL) piecewise-linear coefficients\n+        (17 values). Must supply full set when used or override is ignored.\n+      size: [17]\n+\n+  - DpfNoiseLevelLookupScaleMode:\n+      type: int32_t\n+      direction: inout\n+      description: |\n+        Override NLL scale mode (0=linear,1=logarithmic). Matches hardware\n+        RKISP1_CIF_ISP_NLL_SCALE_* constants.\n+      enum:\n+        - name: DpfNoiseLevelLookupScaleLinear\n+          value: 0\n+          description: Linear scale.\n+        - name: DpfNoiseLevelLookupScaleLogarithmic\n+          value: 1\n+          description: Logarithmic scale.\n+\n+  - ExposureGainIndex:\n+      type: int32_t\n+      direction: out\n+      description: |\n+        Estimated scene exposure gain index used for Denoise tuning selection. Derived\n+        from analogue gain (approx index = gain * 100). Provided each frame\n+        for client awareness and debugging. Range 0..409600.\n+\n ...\n",
    "prefixes": [
        "v1",
        "05/11"
    ]
}