Show a patch.

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

{
    "id": 24107,
    "url": "https://patchwork.libcamera.org/api/patches/24107/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/24107/",
    "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": "<20250815072426.3516-1-david.plowman@raspberrypi.com>",
    "date": "2025-08-15T07:24:26",
    "name": "[v2] ipa: rpi:: denoise: Implement TDN back-off for CDN deviation",
    "commit_ref": "524fb970843108340bd118ce00feb54ebe8863aa",
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "4539585050a9e0c7c596384e3cc5349139a11b10",
    "submitter": {
        "id": 42,
        "url": "https://patchwork.libcamera.org/api/people/42/?format=api",
        "name": "David Plowman",
        "email": "david.plowman@raspberrypi.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/24107/mbox/",
    "series": [
        {
            "id": 5379,
            "url": "https://patchwork.libcamera.org/api/series/5379/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5379",
            "date": "2025-08-15T07:24:26",
            "name": "[v2] ipa: rpi:: denoise: Implement TDN back-off for CDN deviation",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/5379/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/24107/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/24107/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 791BDBDCC1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 15 Aug 2025 07:24:33 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 47CCA69251;\n\tFri, 15 Aug 2025 09:24:32 +0200 (CEST)",
            "from mail-wr1-x434.google.com (mail-wr1-x434.google.com\n\t[IPv6:2a00:1450:4864:20::434])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 139F969244\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 15 Aug 2025 09:24:30 +0200 (CEST)",
            "by mail-wr1-x434.google.com with SMTP id\n\tffacd0b85a97d-3b9d41c1964so948654f8f.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 15 Aug 2025 00:24:30 -0700 (PDT)",
            "from localhost.localdomain ([2a06:61c0:f337:0:de3:cf36:d6b2:e6cc])\n\tby smtp.gmail.com with ESMTPSA id\n\tffacd0b85a97d-3bb676c9426sm922630f8f.33.2025.08.15.00.24.28\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tFri, 15 Aug 2025 00:24:28 -0700 (PDT)"
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"dxArgR+N\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google; t=1755242669; x=1755847469;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:mime-version:message-id:date:subject:cc\n\t:to:from:from:to:cc:subject:date:message-id:reply-to;\n\tbh=Sg7PYm/EdXoa3/igcHWNrfTeF14qnakdPi7ZAGj/nOM=;\n\tb=dxArgR+NHvXvt57oPyGChiPnDVuKJbk3Ahmabrju+BT0pd71ArdhnX2u41X/1etS5n\n\twzF+GRQFif6BXoDGzep332VdOfE1ezDdXYG1l5DDZ3tQq+5Klndj/pZpukwRPBxiWRYn\n\tnxDFMkYAvRqlcaZbkGRfl0uyv4NKvRWwBI2+zVaBeVRNxHG6NNSzRb+ou2/cRPOJDaNI\n\tZn4bXnRKfnE6YnUb2O3HrQw5kguNjJZl+27Mrq+aPqS8eTn/QsP5AGSQcXgCa+QACgsl\n\ttra1yN4IavQga7e3U4cH+n1rSqOSy9msJeEb0hkbkBmZ7A/kbeRxOfCDqXhBjUE+viUs\n\t4S9w==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1755242669; x=1755847469;\n\th=content-transfer-encoding:mime-version:message-id:date:subject:cc\n\t:to:from:x-gm-message-state:from:to:cc:subject:date:message-id\n\t:reply-to;\n\tbh=Sg7PYm/EdXoa3/igcHWNrfTeF14qnakdPi7ZAGj/nOM=;\n\tb=uYN8S89Y2FyUgiuuQIAhYRGDN014DFOsCiKc8ZCIfH2UWfaU5dp1b4DDq0ij/t0ZHe\n\tArIJlHxPtNZvlKszGCoLqcBTtTHOacebcIKjZ3gOFEpVscvsCUDGJrnmJIZ/GTSemLOQ\n\txqOh4ofUT0PzyrLOaxoNKsnrLdRlLy0DVE8DB3qHFY94S51pKloDuk3AqrvkPNh96fge\n\tS4rc1q/nvrZycMCupY4RULAdsgzKfVT7bDBT8dRvNovk2ZUzIt1JddGMYTob+txq9Qb5\n\tewhW3KnpeX+k6YLqql/BUuI3XAxe54XO/8VPFrBL9oDk/snGQCpCwTQ5x1KZ8QrafPmE\n\txt/w==",
        "X-Gm-Message-State": "AOJu0YwfHwjrUQbTbIpXWkKcaZg6s4BhhIl9kmOQoOq3Op1ql0UviMEb\n\tRuasgrWqzhwtorSdbTQwU7uvia7ycsDglpdu3MnGxSyLl1kDNafy3z51sWv7ysJZcIQuRpKAWMT\n\tk0ShxS1I=",
        "X-Gm-Gg": "ASbGncuuRCoGjNHeRvDBPsKem2T2uLNCjntY2QEKqTFsvlmTWzyL0GAOl5Tuy1vfZ69\n\t47EHi/G3DSmrKN/GuyyzdJqUgKphYodX9r9F+pNRzyRsc6zAL+xzG5TCRXAEnEaLsYkUx+5a1y8\n\txOccfS+TS6msrVsNmvKIfaXsuQPvrXC0Sqm0yYDpF7i83lD85bQzdmgZ9Z5btf5PE8JXWZQS22e\n\t0rB8V98WaMhnQdSQdim1yf5clebj8aRUw1hc5rcIrs76rWcC6qu16nkEbfgP5tyzt6lQ3VR54Oz\n\tPbf86PZ+wfh5S2GLPTePn9MOxHoNnOhi/BzIvYh4uaWZT5+/smVuX0MSMC8O1yZ2mLs6sEeuYgA\n\tum0BkfNHqnpP2mFeiPKmxEe2M4InnMAds+75aKnrkwt3FKYc=",
        "X-Google-Smtp-Source": "AGHT+IH64nv0NuROCkWXWZpZQzpGChfXvRiJJnxMB6wOn3w9K6ayGbVhqmdE0Isfd22CteldNV2y9g==",
        "X-Received": "by 2002:a05:6000:290c:b0:3b7:9c79:32bb with SMTP id\n\tffacd0b85a97d-3bb68fdc946mr653942f8f.44.1755242669204; \n\tFri, 15 Aug 2025 00:24:29 -0700 (PDT)",
        "From": "David Plowman <david.plowman@raspberrypi.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "David Plowman <david.plowman@raspberrypi.com>,\n\tNaushir Patuck <naush@raspberrypi.com>",
        "Subject": "[PATCH v2] ipa: rpi:: denoise: Implement TDN back-off for CDN\n\tdeviation",
        "Date": "Fri, 15 Aug 2025 08:24:26 +0100",
        "Message-Id": "<20250815072426.3516-1-david.plowman@raspberrypi.com>",
        "X-Mailer": "git-send-email 2.39.5",
        "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 CDN (colour denoise) deviation gets gradually reduced frame by\nframe as TDN (temporal denoise) comes in and has more effect. CDN is\nmore harmful to image detail than TDN, so ramping it down in favour of\nTDN is beneficial.\n\nThe tuning file parameters are chosen so that existing tuning files\ndon't have to be updated and will carry on working \"mostly like they\ndid\" (apart from the new back-off).\n\nSigned-off-by: David Plowman <david.plowman@raspberrypi.com>\nReviewed-by: Naushir Patuck <naush@raspberrypi.com>\n---\n src/ipa/rpi/controller/rpi/denoise.cpp | 23 ++++++++++++++++++++---\n src/ipa/rpi/controller/rpi/denoise.h   |  4 +++-\n 2 files changed, 23 insertions(+), 4 deletions(-)",
    "diff": "diff --git a/src/ipa/rpi/controller/rpi/denoise.cpp b/src/ipa/rpi/controller/rpi/denoise.cpp\nindex ba851658..cabe3e2a 100644\n--- a/src/ipa/rpi/controller/rpi/denoise.cpp\n+++ b/src/ipa/rpi/controller/rpi/denoise.cpp\n@@ -37,7 +37,18 @@ int DenoiseConfig::read(const libcamera::YamlObject &params)\n \tcdnEnable = params.contains(\"cdn\");\n \tif (cdnEnable) {\n \t\tauto &cdnParams = params[\"cdn\"];\n-\t\tcdnDeviation = cdnParams[\"deviation\"].get<double>(120);\n+\t\t/*\n+\t\t * For backwards compatibility with existing tuning files, interpret \"deviation\"\n+\t\t * as giving the \"no TDN\" deviation, where present. But \"deviation_no_tdn\" takes\n+\t\t * precedence when that's available.\n+\t\t */\n+\t\tcdnDeviationNoTdn = cdnParams[\"deviation\"].get<double>(150);\n+\t\tcdnDeviationNoTdn = cdnParams[\"deviation_no_tdn\"].get<double>(cdnDeviationNoTdn);\n+\t\t/*\n+\t\t * A third the value of the no TDN deviation is about right for with-TDN, if\n+\t\t * the user hasn't specified otherwise.\n+\t\t */\n+\t\tcdnDeviationWithTdn = cdnParams[\"deviation_with_tdn\"].get<double>(cdnDeviationNoTdn / 3);\n \t\tcdnStrength = cdnParams[\"strength\"].get<double>(0.2);\n \t}\n \n@@ -48,13 +59,14 @@ int DenoiseConfig::read(const libcamera::YamlObject &params)\n \t\ttdnThreshold = tdnParams[\"threshold\"].get<double>(0.75);\n \t} else if (sdnEnable) {\n \t\t/*\n-\t\t * If SDN is enabled but TDN isn't, overwrite all the SDN settings\n+\t\t * If SDN is enabled but TDN isn't, overwrite all the SDN/CDN settings\n \t\t * with the \"no TDN\" versions. This makes it easier to enable or\n \t\t * disable TDN in the tuning file without editing all the other\n \t\t * parameters.\n \t\t */\n \t\tsdnDeviation = sdnDeviation2 = sdnDeviationNoTdn;\n \t\tsdnStrength = sdnStrengthNoTdn;\n+\t\tcdnDeviationWithTdn = cdnDeviationNoTdn;\n \t}\n \n \treturn 0;\n@@ -107,6 +119,7 @@ void Denoise::switchMode([[maybe_unused]] CameraMode const &cameraMode,\n \tcurrentSdnDeviation_ = currentConfig_->sdnDeviationNoTdn;\n \tcurrentSdnStrength_ = currentConfig_->sdnStrengthNoTdn;\n \tcurrentSdnDeviation2_ = currentConfig_->sdnDeviationNoTdn;\n+\tcurrentCdnDeviation_ = currentConfig_->cdnDeviationNoTdn;\n }\n \n void Denoise::prepare(Metadata *imageMetadata)\n@@ -159,8 +172,12 @@ void Denoise::prepare(Metadata *imageMetadata)\n \n \tif (currentConfig_->cdnEnable && mode_ != DenoiseMode::ColourOff) {\n \t\tstruct CdnStatus cdn;\n-\t\tcdn.threshold = currentConfig_->cdnDeviation * noiseStatus.noiseSlope + noiseStatus.noiseConstant;\n+\t\tcdn.threshold = currentCdnDeviation_ * noiseStatus.noiseSlope + noiseStatus.noiseConstant;\n \t\tcdn.strength = currentConfig_->cdnStrength;\n+\t\t/* For the next frame, we back off the CDN deviation as TDN ramps up. */\n+\t\tdouble f = currentConfig_->sdnTdnBackoff;\n+\t\tcurrentCdnDeviation_ = f * currentCdnDeviation_ + (1 - f) * currentConfig_->cdnDeviationWithTdn;\n+\n \t\timageMetadata->set(\"cdn.status\", cdn);\n \t\tLOG(RPiDenoise, Debug)\n \t\t\t<< \"programmed cdn threshold \" << cdn.threshold\ndiff --git a/src/ipa/rpi/controller/rpi/denoise.h b/src/ipa/rpi/controller/rpi/denoise.h\nindex 79946c97..e23a2e8f 100644\n--- a/src/ipa/rpi/controller/rpi/denoise.h\n+++ b/src/ipa/rpi/controller/rpi/denoise.h\n@@ -23,7 +23,8 @@ struct DenoiseConfig {\n \tdouble sdnDeviationNoTdn;\n \tdouble sdnStrengthNoTdn;\n \tdouble sdnTdnBackoff;\n-\tdouble cdnDeviation;\n+\tdouble cdnDeviationNoTdn;\n+\tdouble cdnDeviationWithTdn;\n \tdouble cdnStrength;\n \tdouble tdnDeviation;\n \tdouble tdnThreshold;\n@@ -54,6 +55,7 @@ private:\n \tdouble currentSdnDeviation_;\n \tdouble currentSdnStrength_;\n \tdouble currentSdnDeviation2_;\n+\tdouble currentCdnDeviation_;\n };\n \n } // namespace RPiController\n",
    "prefixes": [
        "v2"
    ]
}