Patch Detail
Show a patch.
GET /api/patches/25892/?format=api
{ "id": 25892, "url": "https://patchwork.libcamera.org/api/patches/25892/?format=api", "web_url": "https://patchwork.libcamera.org/patch/25892/", "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": "<20260120153057.1703714-3-rui.wang@ideasonboard.com>", "date": "2026-01-20T15:30:52", "name": "[v10,2/7] ipa: rkisp1: algorithms: dpf: Implement mode switching", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "9d06db6c7da27675afe5f39e789c1d855bdc33e3", "submitter": { "id": 241, "url": "https://patchwork.libcamera.org/api/people/241/?format=api", "name": "Rui Wang", "email": "rui.wang@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/25892/mbox/", "series": [ { "id": 5725, "url": "https://patchwork.libcamera.org/api/series/5725/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5725", "date": "2026-01-20T15:30:50", "name": "refactor DPF parsing and initialization", "version": 10, "mbox": "https://patchwork.libcamera.org/series/5725/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/25892/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/25892/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 185A5BDCBF\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 20 Jan 2026 15:31:25 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C088661FC9;\n\tTue, 20 Jan 2026 16:31:24 +0100 (CET)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 72A8861FCC\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 20 Jan 2026 16:31:18 +0100 (CET)", "from rui-Precision-7560.local (unknown [209.216.103.65])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 73FFB2147;\n\tTue, 20 Jan 2026 16:30:46 +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=\"EYzUPYCQ\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1768923046;\n\tbh=qMjXqoxxBpwnNP/RS4+CRTqDn6lTBkSSS4ar7XYpP9Y=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=EYzUPYCQvTTyyBqFY6BRIMPWQQU/chULFjVspoPIAlXAT2QT0zP9e0c0apXCdjgRj\n\tDCS2tkW6kG3JdcfX0F4Ogd98RlcuyVZ2dQg4VUv+hIme1MBKSp5l+eqxefZbKAd4UW\n\tT5ZhXL8wfRbu52NXwzWwaFfHoFa2j88LUXwYNxNQ=", "From": "Rui Wang <rui.wang@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Rui Wang <rui.wang@ideasonboard.com>", "Subject": "[PATCH v10 2/7] ipa: rkisp1: algorithms: dpf: Implement mode\n\tswitching", "Date": "Tue, 20 Jan 2026 10:30:52 -0500", "Message-ID": "<20260120153057.1703714-3-rui.wang@ideasonboard.com>", "X-Mailer": "git-send-email 2.43.0", "In-Reply-To": "<20260120153057.1703714-1-rui.wang@ideasonboard.com>", "References": "<20260120153057.1703714-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 support for switching between different noise reduction modes.\nThis allows the DPF algorithm to be configured with different parameters\nbased on the requested noise reduction level (e.g., minimal, fast, high\nquality).\n\nMode configurations are stored in the tuning data as a list of modes,\nwith each mode specifying its 'type' and corresponding DPF parameters.\nAn optional 'ActiveMode' setting allows defining the default mode at\nstartup, defaulting to \"ReductionOff\" if not specified.\n\nThe Dpf class is refactored to store configurations in a vector and\ntrack the current mode using an iterator, which avoids data copying\nduring runtime.\n\nSigned-off-by: Rui Wang <rui.wang@ideasonboard.com>\n\n---\nchangelog since v5:\n - Update log verbos from Info to Debug in loadReductionConfig\n - Update log mode value to string to in loadReductionConfig\n - improving the return value changed like :\n if (ret != 0) -> if (ret)\n\n Reviewed-by tags from v5 are carried over (no function changes).\nchangelog since v6:\n - add { controls::draft::NoiseReductionModeOff, \"off\" }, to fix\n out_of_range issue\n\nchangelog since v7:\n - Delete base config parse from parseConfig\n\nchangelog since v8:\n - remove config_ strengthConfig_ by replacing activeMode_ iterator\n to avoiding data copy during config loading\n - Update kModesMap from std::map<int32_t, std:string>\n std::map<std::string, int32_t> for quick search improvement\n - add ActiveMode as Stefan and Jacopo's review comments\n - update type : auto -> int for ret value\n - name change loadRecuctionConfig -> loadConfig\n - delete parseMode\n\nchangelog since v9: As Stefan's suggestion\n - Update dpf reduction mode config structure format\n from list to dictionary :\n NoiseReductionMode:\n NoiseReductionMinimal:\n ***\n NoiseReductionZSL:\n ***\n---\n src/ipa/rkisp1/algorithms/dpf.cpp | 117 +++++++++++++++++++++++++++---\n src/ipa/rkisp1/algorithms/dpf.h | 12 ++-\n 2 files changed, 116 insertions(+), 13 deletions(-)", "diff": "diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp\nindex dd3effa1..659a1a82 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 <map>\n #include <string>\n #include <vector>\n \n@@ -36,8 +37,32 @@ namespace ipa::rkisp1::algorithms {\n \n LOG_DEFINE_CATEGORY(RkISP1Dpf)\n \n+namespace {\n+\n+const std::map<std::string, int32_t> kModesMap = {\n+\t{ \"ReductionMinimal\", controls::draft::NoiseReductionModeMinimal },\n+\t{ \"ReductionFast\", controls::draft::NoiseReductionModeFast },\n+\t{ \"ReductionHighQuality\", controls::draft::NoiseReductionModeHighQuality },\n+\t{ \"ReductionZSL\", controls::draft::NoiseReductionModeZSL },\n+\t{ \"ReductionOff\", controls::draft::NoiseReductionModeOff },\n+};\n+\n+std::string modeName(int32_t mode)\n+{\n+\tauto it = std::find_if(kModesMap.begin(), kModesMap.end(),\n+\t\t\t [mode](const auto &pair) {\n+\t\t\t\t return pair.second == mode;\n+\t\t\t });\n+\n+\tif (it != kModesMap.end())\n+\t\treturn it->first;\n+\n+\treturn \"ReductionUnknown\";\n+}\n+} /* namespace */\n+\n Dpf::Dpf()\n-\t: config_({}), strengthConfig_({})\n+\t: noiseReductionModes_({}), activeMode_(noiseReductionModes_.end())\n {\n }\n \n@@ -57,10 +82,56 @@ int Dpf::init([[maybe_unused]] IPAContext &context,\n \n int Dpf::parseConfig(const YamlObject &tuningData)\n {\n-\t/* Parse base config. */\n-\tint ret = parseSingleConfig(tuningData, config_, strengthConfig_);\n-\tif (ret)\n-\t\treturn ret;\n+\t/* Parse noise reduction modes. */\n+\tif (!tuningData.contains(\"NoiseReductionModes\")) {\n+\t\tLOG(RkISP1Dpf, Error) << \"Missing modes in DPF tuning data\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tconst YamlObject &modesObject = tuningData[\"NoiseReductionModes\"];\n+\tif (!modesObject.isDictionary()) {\n+\t\tLOG(RkISP1Dpf, Error) << \"NoiseReductionModes must be a dictionary\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tnoiseReductionModes_.clear();\n+\tfor (const auto &[modeName, modeData] : modesObject.asDict()) {\n+\t\tauto it = kModesMap.find(modeName);\n+\t\tif (it == kModesMap.end()) {\n+\t\t\tLOG(RkISP1Dpf, Error) << \"Unknown mode type: \" << modeName;\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tModeConfig mode;\n+\t\tmode.modeValue = it->second;\n+\t\tint ret = parseSingleConfig(modeData, mode.dpf, mode.strength);\n+\t\tif (ret) {\n+\t\t\tLOG(RkISP1Dpf, Error) << \"Failed to parse mode: \" << modeName;\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tnoiseReductionModes_.push_back(mode);\n+\t}\n+\n+\t/*\n+\t * Parse the optional ActiveMode.\n+\t * If not present, default to \"ReductionOff\".\n+\t */\n+\tstd::string activeMode = tuningData[\"ActiveMode\"].get<std::string>().value_or(\"ReductionOff\");\n+\tauto it = kModesMap.find(activeMode);\n+\tif (it == kModesMap.end()) {\n+\t\tLOG(RkISP1Dpf, Warning) << \"Invalid ActiveMode: \" << activeMode;\n+\t\tactiveMode_ = noiseReductionModes_.end();\n+\t\treturn 0;\n+\t}\n+\n+\tif (!loadConfig(it->second)) {\n+\t\t/* If the default \"ReductionOff\" mode is requested but not configured, disable DPF. */\n+\t\tif (it->second == controls::draft::NoiseReductionModeOff)\n+\t\t\tactiveMode_ = noiseReductionModes_.end();\n+\t\telse\n+\t\t\treturn -EINVAL;\n+\t}\n \n \treturn 0;\n }\n@@ -193,6 +264,27 @@ int Dpf::parseSingleConfig(const YamlObject &tuningData,\n \treturn 0;\n }\n \n+bool Dpf::loadConfig(int32_t mode)\n+{\n+\tauto it = std::find_if(noiseReductionModes_.begin(), noiseReductionModes_.end(),\n+\t\t\t [mode](const ModeConfig &m) {\n+\t\t\t\t return m.modeValue == mode;\n+\t\t\t });\n+\tif (it == noiseReductionModes_.end()) {\n+\t\tLOG(RkISP1Dpf, Warning)\n+\t\t\t<< \"No DPF config for reduction mode: \" << modeName(mode);\n+\t\treturn false;\n+\t}\n+\n+\tactiveMode_ = it;\n+\n+\tLOG(RkISP1Dpf, Debug)\n+\t\t<< \"DPF mode=Reduction (config loaded)\"\n+\t\t<< \" mode= \" << modeName(mode);\n+\n+\treturn true;\n+}\n+\n /**\n * \\copydoc libcamera::ipa::Algorithm::queueRequest\n */\n@@ -206,8 +298,6 @@ void Dpf::queueRequest(IPAContext &context,\n \n \tconst auto &denoise = controls.get(controls::draft::NoiseReductionMode);\n \tif (denoise) {\n-\t\tLOG(RkISP1Dpf, Debug) << \"Set denoise to \" << *denoise;\n-\n \t\tswitch (*denoise) {\n \t\tcase controls::draft::NoiseReductionModeOff:\n \t\t\tif (dpf.denoise) {\n@@ -218,9 +308,10 @@ void Dpf::queueRequest(IPAContext &context,\n \t\tcase controls::draft::NoiseReductionModeMinimal:\n \t\tcase controls::draft::NoiseReductionModeHighQuality:\n \t\tcase controls::draft::NoiseReductionModeFast:\n-\t\t\tif (!dpf.denoise) {\n-\t\t\t\tdpf.denoise = true;\n+\t\tcase controls::draft::NoiseReductionModeZSL:\n+\t\t\tif (loadConfig(*denoise)) {\n \t\t\t\tupdate = true;\n+\t\t\t\tdpf.denoise = true;\n \t\t\t}\n \t\t\tbreak;\n \t\tdefault:\n@@ -229,6 +320,8 @@ void Dpf::queueRequest(IPAContext &context,\n \t\t\t\t<< *denoise;\n \t\t\tbreak;\n \t\t}\n+\t\tif (update)\n+\t\t\tLOG(RkISP1Dpf, Debug) << \"Set denoise to \" << modeName(*denoise);\n \t}\n \n \tframeContext.dpf.denoise = dpf.denoise;\n@@ -251,8 +344,10 @@ void Dpf::prepare(IPAContext &context, const uint32_t frame,\n \tstrengthConfig.setEnabled(frameContext.dpf.denoise);\n \n \tif (frameContext.dpf.denoise) {\n-\t\t*config = config_;\n-\t\t*strengthConfig = strengthConfig_;\n+\t\tconst ModeConfig &modeConfig = *activeMode_;\n+\n+\t\t*config = modeConfig.dpf;\n+\t\t*strengthConfig = modeConfig.strength;\n \n \t\tconst auto &awb = context.configuration.awb;\n \t\tconst auto &lsc = context.configuration.lsc;\ndiff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h\nindex 39186c55..11fc88e4 100644\n--- a/src/ipa/rkisp1/algorithms/dpf.h\n+++ b/src/ipa/rkisp1/algorithms/dpf.h\n@@ -30,13 +30,21 @@ public:\n \t\t RkISP1Params *params) override;\n \n private:\n+\tstruct ModeConfig {\n+\t\tint32_t modeValue;\n+\t\trkisp1_cif_isp_dpf_config dpf;\n+\t\trkisp1_cif_isp_dpf_strength_config strength;\n+\t};\n+\n \tint parseConfig(const YamlObject &tuningData);\n \tint parseSingleConfig(const YamlObject &tuningData,\n \t\t\t rkisp1_cif_isp_dpf_config &config,\n \t\t\t rkisp1_cif_isp_dpf_strength_config &strengthConfig);\n \n-\tstruct rkisp1_cif_isp_dpf_config config_;\n-\tstruct rkisp1_cif_isp_dpf_strength_config strengthConfig_;\n+\tbool loadConfig(int32_t mode);\n+\n+\tstd::vector<ModeConfig> noiseReductionModes_;\n+\tstd::vector<ModeConfig>::const_iterator activeMode_;\n };\n \n } /* namespace ipa::rkisp1::algorithms */\n", "prefixes": [ "v10", "2/7" ] }