[{"id":35703,"web_url":"https://patchwork.libcamera.org/comment/35703/","msgid":"<175706897640.1787083.9189914118137381397@neptunite.rasen.tech>","date":"2025-09-05T10:42:56","subject":"Re: [PATCH v3 10/19] ipa: rkisp1: agc: Add correction for exposure\n\tquantization","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"Quoting Stefan Klug (2025-08-15 19:29:30)\n> There are several occations where quantization can lead to visible\n> effects.\n> \n> In WDR mode it can happen that exposure times get set to very low values\n> (Sometimes 2-3 lines). This intentionally introduced underexposure is\n> corrected by the GWDR module. As exposure time is quantized by lines,\n> the smallest possible change in exposure time now results in a quite\n> visible change in perceived brightness.\n> \n> Sometimes the possible gain steps are also quite large leading to\n> visible jumps if e.g. if the exposure time is fixed.\n> \n> Mitigate that by applying a global gain to account for the error\n> introduced by the exposure quantization.\n> \n> ToDo: This needs perfect frame synchronous control of the sensor to work\n> properly which is not guaranteed in all cases. It still improves the\n> behavior with the current regulation and can easily be skipped, when\n> there is no compress algorithm.\n> \n> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>\n\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n\n> \n> ---\n> \n> Changes in v3:\n> - Collected tags\n> ---\n>  src/ipa/rkisp1/algorithms/agc.cpp | 24 +++++++++++++++++++++---\n>  src/ipa/rkisp1/ipa_context.h      |  2 ++\n>  2 files changed, 23 insertions(+), 3 deletions(-)\n> \n> diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp\n> index 0a29326841fb..d34c041f9fe1 100644\n> --- a/src/ipa/rkisp1/algorithms/agc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/agc.cpp\n> @@ -199,6 +199,9 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)\n>         context.configuration.agc.measureWindow.h_size = configInfo.outputSize.width;\n>         context.configuration.agc.measureWindow.v_size = configInfo.outputSize.height;\n>  \n> +       AgcMeanLuminance::configure(context.configuration.sensor.lineDuration,\n> +                                   context.camHelper.get());\n> +\n>         setLimits(context.configuration.sensor.minExposureTime,\n>                   context.configuration.sensor.maxExposureTime,\n>                   context.configuration.sensor.minAnalogueGain,\n> @@ -283,6 +286,10 @@ void Agc::queueRequest(IPAContext &context,\n>         if (!frameContext.agc.autoGainEnabled)\n>                 frameContext.agc.gain = agc.manual.gain;\n>  \n> +       if (!frameContext.agc.autoExposureEnabled &&\n> +           !frameContext.agc.autoGainEnabled)\n> +               frameContext.agc.quantizationGain = 1.0;\n> +\n>         const auto &meteringMode = controls.get(controls::AeMeteringMode);\n>         if (meteringMode) {\n>                 frameContext.agc.updateMetering = agc.meteringMode != *meteringMode;\n> @@ -336,12 +343,17 @@ void Agc::prepare(IPAContext &context, const uint32_t frame,\n>  {\n>         uint32_t activeAutoExposure = context.activeState.agc.automatic.exposure;\n>         double activeAutoGain = context.activeState.agc.automatic.gain;\n> +       double activeAutoQGain = context.activeState.agc.automatic.quantizationGain;\n>  \n>         /* Populate exposure and gain in auto mode */\n> -       if (frameContext.agc.autoExposureEnabled)\n> +       if (frameContext.agc.autoExposureEnabled) {\n>                 frameContext.agc.exposure = activeAutoExposure;\n> -       if (frameContext.agc.autoGainEnabled)\n> +               frameContext.agc.quantizationGain = activeAutoQGain;\n> +       }\n> +       if (frameContext.agc.autoGainEnabled) {\n>                 frameContext.agc.gain = activeAutoGain;\n> +               frameContext.agc.quantizationGain = activeAutoQGain;\n> +       }\n>  \n>         /*\n>          * Populate manual exposure and gain from the active auto values when\n> @@ -354,6 +366,12 @@ void Agc::prepare(IPAContext &context, const uint32_t frame,\n>         if (!frameContext.agc.autoGainEnabled && frameContext.agc.autoGainModeChange) {\n>                 context.activeState.agc.manual.gain = activeAutoGain;\n>                 frameContext.agc.gain = activeAutoGain;\n> +               frameContext.agc.quantizationGain = activeAutoQGain;\n> +       }\n> +\n> +       if (context.activeState.compress.supported) {\n> +               frameContext.compress.enable = true;\n> +               frameContext.compress.gain = frameContext.agc.quantizationGain;\n>         }\n>  \n>         if (frame > 0 && !frameContext.agc.updateMetering)\n> @@ -582,7 +600,7 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,\n>         /* Update the estimated exposure and gain. */\n>         activeState.agc.automatic.exposure = newExposureTime / lineDuration;\n>         activeState.agc.automatic.gain = aGain;\n> -\n> +       activeState.agc.automatic.quantizationGain = qGain;\n>         /*\n>          * Expand the target frame duration so that we do not run faster than\n>          * the minimum frame duration when we have short exposures.\n> diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h\n> index 37a74215ce19..362ab2fda5fe 100644\n> --- a/src/ipa/rkisp1/ipa_context.h\n> +++ b/src/ipa/rkisp1/ipa_context.h\n> @@ -77,6 +77,7 @@ struct IPAActiveState {\n>                 struct {\n>                         uint32_t exposure;\n>                         double gain;\n> +                       double quantizationGain;\n>                 } automatic;\n>  \n>                 bool autoExposureEnabled;\n> @@ -135,6 +136,7 @@ struct IPAFrameContext : public FrameContext {\n>                 uint32_t exposure;\n>                 double gain;\n>                 double exposureValue;\n> +               double quantizationGain;\n>                 uint32_t vblank;\n>                 bool autoExposureEnabled;\n>                 bool autoGainEnabled;\n> -- \n> 2.48.1\n>","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 17F1FC328C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri,  5 Sep 2025 10:43:03 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5A19769357;\n\tFri,  5 Sep 2025 12:43:03 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6D3A569337\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  5 Sep 2025 12:43:02 +0200 (CEST)","from neptunite.rasen.tech (unknown\n\t[IPv6:2404:7a81:160:2100:dbfb:387c:7405:52bc])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id D722A1129; \n\tFri,  5 Sep 2025 12:41:51 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"PEPacOBN\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1757068912;\n\tbh=aQIVDJjS7h6pLG53QgzroOX2BHyL64b1onrIe+4PXRU=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=PEPacOBNGAGC9Nv2J6e2umhyYL3JXXWEWIDxNaPU4cI7qpAjGQDHgH2j43T7/YNom\n\tg6Es51fG7o0mEDT4ktprw5hhvXEovuO/SExPsRq+uyoz6dU2sbIjwxspjoA2JPDwG+\n\tCREUYpVCVPFWLJpC2/XPdVtwjppAsh33lCOtERRY=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20250815102945.1602071-11-stefan.klug@ideasonboard.com>","References":"<20250815102945.1602071-1-stefan.klug@ideasonboard.com>\n\t<20250815102945.1602071-11-stefan.klug@ideasonboard.com>","Subject":"Re: [PATCH v3 10/19] ipa: rkisp1: agc: Add correction for exposure\n\tquantization","From":"Paul Elder <paul.elder@ideasonboard.com>","Cc":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>,\n\tDaniel Scally <dan.scally@ideasonboard.com>","To":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Fri, 05 Sep 2025 19:42:56 +0900","Message-ID":"<175706897640.1787083.9189914118137381397@neptunite.rasen.tech>","User-Agent":"alot/0.0.0","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>"}}]