[{"id":20373,"web_url":"https://patchwork.libcamera.org/comment/20373/","msgid":"<YXI9zFLoxui2exMN@pendragon.ideasonboard.com>","date":"2021-10-22T04:27:56","subject":"Re: [libcamera-devel] [PATCH v3 12/14] ipa: ipu3: agc: Refactor\n\tcondition on exposure correction","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jean-Michel,\n\nOn Thu, Oct 21, 2021 at 06:43:59PM +0200, Jean-Michel Hautbois wrote:\n> Until now, we can't know when the exposure and gains applied in the\n> IPAIPU3::setControls() are really applied (it can be several frames). We\n> don't want to use the values calculated as if they are already applied,\n> and this is done by testing the frame number.\n> \n> When the exposure is estimated, we verify if it changed enough for\n> exposure and gain to be updated.\n> \n> Keep the indentation level removal and simply return when the change is\n> so small there is no need to apply the newly calculated value.\n\nThe first two paragraph seems unrelated to the version of this patch,\nand the \"keep\" in the third paragraph refers to how this has changed\ncompared to v2. Please rewrite the commit message to correspond to the\ncode changes.\n\n> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  src/ipa/ipu3/algorithms/agc.cpp | 91 ++++++++++++++++-----------------\n>  1 file changed, 45 insertions(+), 46 deletions(-)\n> \n> diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp\n> index 43ef89df..7ff3029b 100644\n> --- a/src/ipa/ipu3/algorithms/agc.cpp\n> +++ b/src/ipa/ipu3/algorithms/agc.cpp\n> @@ -138,60 +138,59 @@ void Agc::lockExposureGain(uint32_t &exposure, double &analogueGain)\n>  \tif ((frameCount_ < kInitialFrameMinAECount) || (frameCount_ - lastFrame_ < kFrameSkipCount))\n>  \t\treturn;\n>  \n> -\t/* Are we correctly exposed ? */\n> -\tif (std::abs(iqMean_ - kEvGainTarget * knumHistogramBins) <= 1) {\n> -\t\tLOG(IPU3Agc, Debug) << \"!!! Good exposure with iqMean = \" << iqMean_;\n> -\t} else {\n> -\t\tdouble evGain = kEvGainTarget * knumHistogramBins / iqMean_;\n> +\tif (std::abs(iqMean_ - kEvGainTarget * knumHistogramBins) <= 1)\n> +\t\treturn;\n>  \n> -\t\t/* extracted from Rpi::Agc::computeTargetExposure */\n> -\t\tutils::Duration currentShutter = exposure * lineDuration_;\n> -\t\tcurrentExposureNoDg_ = currentShutter * analogueGain;\n> -\t\tLOG(IPU3Agc, Debug) << \"Actual total exposure \" << currentExposureNoDg_\n> -\t\t\t\t    << \" Shutter speed \" << currentShutter\n> -\t\t\t\t    << \" Gain \" << analogueGain\n> -\t\t\t\t    << \" Needed ev gain \" << evGain;\n> +\tdouble evGain = kEvGainTarget * knumHistogramBins / iqMean_;\n>  \n> -\t\tcurrentExposure_ = prevExposureValue_ * evGain;\n> -\t\tutils::Duration minShutterSpeed = minExposureLines_ * lineDuration_;\n> -\t\tutils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_;\n> +\t/* extracted from Rpi::Agc::computeTargetExposure */\n> +\tutils::Duration currentShutter = exposure * lineDuration_;\n> +\tcurrentExposureNoDg_ = currentShutter * analogueGain;\n> +\tLOG(IPU3Agc, Debug) << \"Actual total exposure \" << currentExposureNoDg_\n> +\t\t\t    << \" Shutter speed \" << currentShutter\n> +\t\t\t    << \" Gain \" << analogueGain\n> +\t\t\t    << \" Needed ev gain \" << evGain;\n>  \n> -\t\tutils::Duration maxTotalExposure = maxShutterSpeed * kMaxGain;\n> -\t\tcurrentExposure_ = std::min(currentExposure_, maxTotalExposure);\n> -\t\tLOG(IPU3Agc, Debug) << \"Target total exposure \" << currentExposure_\n> -\t\t\t\t    << \", maximum is \" << maxTotalExposure;\n> +\tcurrentExposure_ = prevExposureValue_ * evGain;\n> +\tutils::Duration minShutterSpeed = minExposureLines_ * lineDuration_;\n> +\tutils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_;\n>  \n> -\t\t/* \\todo: estimate if we need to desaturate */\n> -\t\tfilterExposure();\n> +\tutils::Duration maxTotalExposure = maxShutterSpeed * kMaxGain;\n> +\tcurrentExposure_ = std::min(currentExposure_, maxTotalExposure);\n> +\tLOG(IPU3Agc, Debug) << \"Target total exposure \" << currentExposure_\n> +\t\t\t    << \", maximum is \" << maxTotalExposure;\n>  \n> -\t\tutils::Duration exposureValue = filteredExposure_;\n> -\t\tutils::Duration shutterTime = minShutterSpeed;\n> +\t/* \\todo: estimate if we need to desaturate */\n> +\tfilterExposure();\n>  \n> -\t\t/*\n> -\t\t * Push the shutter time up to the maximum first, and only then\n> -\t\t * increase the gain.\n> -\t\t */\n> -\t\tshutterTime = std::clamp<utils::Duration>(exposureValue / kMinGain,\n> -\t\t\t\t\t\t\t  minShutterSpeed, maxShutterSpeed);\n> -\t\tdouble stepGain = std::clamp(exposureValue / shutterTime,\n> -\t\t\t\t\t     kMinGain, kMaxGain);\n> -\t\tLOG(IPU3Agc, Debug) << \"Divided up shutter and gain are \"\n> -\t\t\t\t    << shutterTime << \" and \"\n> -\t\t\t\t    << stepGain;\n> +\tutils::Duration exposureValue = filteredExposure_;\n> +\tutils::Duration shutterTime = minShutterSpeed;\n>  \n> -\t\texposure = shutterTime / lineDuration_;\n> -\t\tanalogueGain = stepGain;\n> +\t/*\n> +\t* Push the shutter time up to the maximum first, and only then\n> +\t* increase the gain.\n> +\t*/\n> +\tshutterTime = std::clamp<utils::Duration>(exposureValue / kMinGain,\n> +\t\t\t\t\t\t  minShutterSpeed, maxShutterSpeed);\n> +\tdouble stepGain = std::clamp(exposureValue / shutterTime,\n> +\t\t\t\t     kMinGain, kMaxGain);\n> +\tLOG(IPU3Agc, Debug) << \"Divided up shutter and gain are \"\n> +\t\t\t    << shutterTime << \" and \"\n> +\t\t\t    << stepGain;\n> +\n> +\texposure = shutterTime / lineDuration_;\n> +\tanalogueGain = stepGain;\n> +\n> +\t/*\n> +\t * Update the exposure value for the next process call.\n> +\t *\n> +\t * \\todo Obtain the values of the exposure time and analog gain\n> +\t * that were actually used by the sensor, either from embedded\n> +\t * data when available, or from the delayed controls\n> +\t * infrastructure in case a slow down caused a mismatch.\n> +\t */\n> +\tprevExposureValue_ = shutterTime * analogueGain;\n>  \n> -\t\t/*\n> -\t\t * Update the exposure value for the next process call.\n> -\t\t *\n> -\t\t * \\todo Obtain the values of the exposure time and analog gain\n> -\t\t * that were actually used by the sensor, either from embedded\n> -\t\t * data when available, or from the delayed controls\n> -\t\t * infrastructure in case a slow down caused a mismatch.\n> -\t\t */\n> -\t\tprevExposureValue_ = shutterTime * analogueGain;\n> -\t}\n>  \tlastFrame_ = frameCount_;\n\nThis is a functional change, with no mention of it (and no explanation\nof why it's correct) in the commit message.\n\n>  }\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 74974BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 22 Oct 2021 04:28:19 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E63A868F59;\n\tFri, 22 Oct 2021 06:28:18 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B9B6260123\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 22 Oct 2021 06:28:16 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 315A151D;\n\tFri, 22 Oct 2021 06:28:16 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"VEBU7JzX\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1634876896;\n\tbh=34SHujuk0pE9D/DkLbk5UvteI0x4P6cgEri8DgGG1nU=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=VEBU7JzXWZZ6tTzbxjO9maE2gu/6RFJC8aiMao6XUCiV6bLlRMirOmTxyUwRE1Vg1\n\tUjk9wUc5rlLeHX+VcfA0E9jQKVBWRkNZgZf35gpu3vDJIXw5hd/ikdUsDngpMJ9/ib\n\tmlp/XRCQAX2I9WhfboPRq2MbDOEuK4N6SlnMq2pw=","Date":"Fri, 22 Oct 2021 07:27:56 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","Message-ID":"<YXI9zFLoxui2exMN@pendragon.ideasonboard.com>","References":"<20211021164401.110033-1-jeanmichel.hautbois@ideasonboard.com>\n\t<20211021164401.110033-13-jeanmichel.hautbois@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20211021164401.110033-13-jeanmichel.hautbois@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v3 12/14] ipa: ipu3: agc: Refactor\n\tcondition on exposure correction","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":20375,"web_url":"https://patchwork.libcamera.org/comment/20375/","msgid":"<1c7162ac-6ff4-147a-ebbe-b9cb04278947@ideasonboard.com>","date":"2021-10-22T05:56:50","subject":"Re: [libcamera-devel] [PATCH v3 12/14] ipa: ipu3: agc: Refactor\n\tcondition on exposure correction","submitter":{"id":75,"url":"https://patchwork.libcamera.org/api/people/75/","name":"Jean-Michel Hautbois","email":"jeanmichel.hautbois@ideasonboard.com"},"content":"Hi Laurent,\n\nOn 22/10/2021 06:27, Laurent Pinchart wrote:\n> Hi Jean-Michel,\n> \n> On Thu, Oct 21, 2021 at 06:43:59PM +0200, Jean-Michel Hautbois wrote:\n>> Until now, we can't know when the exposure and gains applied in the\n>> IPAIPU3::setControls() are really applied (it can be several frames). We\n>> don't want to use the values calculated as if they are already applied,\n>> and this is done by testing the frame number.\n>>\n>> When the exposure is estimated, we verify if it changed enough for\n>> exposure and gain to be updated.\n>>\n>> Keep the indentation level removal and simply return when the change is\n>> so small there is no need to apply the newly calculated value.\n> \n> The first two paragraph seems unrelated to the version of this patch,\n> and the \"keep\" in the third paragraph refers to how this has changed\n> compared to v2. Please rewrite the commit message to correspond to the\n> code changes.\n\nLet's try:\n'''\nEach time we test the brightness with the desired the target, we verify\nif the change is small enough to consider that we are correctly exposed\nor not. Simplify the reading by removing one level of indentation, and\nreturning from the function when the change is too small.\n'''\n\n> \n>> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n>> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n>> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>> ---\n>>   src/ipa/ipu3/algorithms/agc.cpp | 91 ++++++++++++++++-----------------\n>>   1 file changed, 45 insertions(+), 46 deletions(-)\n>>\n>> diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp\n>> index 43ef89df..7ff3029b 100644\n>> --- a/src/ipa/ipu3/algorithms/agc.cpp\n>> +++ b/src/ipa/ipu3/algorithms/agc.cpp\n>> @@ -138,60 +138,59 @@ void Agc::lockExposureGain(uint32_t &exposure, double &analogueGain)\n>>   \tif ((frameCount_ < kInitialFrameMinAECount) || (frameCount_ - lastFrame_ < kFrameSkipCount))\n>>   \t\treturn;\n>>   \n>> -\t/* Are we correctly exposed ? */\n>> -\tif (std::abs(iqMean_ - kEvGainTarget * knumHistogramBins) <= 1) {\n>> -\t\tLOG(IPU3Agc, Debug) << \"!!! Good exposure with iqMean = \" << iqMean_;\n>> -\t} else {\n>> -\t\tdouble evGain = kEvGainTarget * knumHistogramBins / iqMean_;\n>> +\tif (std::abs(iqMean_ - kEvGainTarget * knumHistogramBins) <= 1)\n>> +\t\treturn;\n>>   \n>> -\t\t/* extracted from Rpi::Agc::computeTargetExposure */\n>> -\t\tutils::Duration currentShutter = exposure * lineDuration_;\n>> -\t\tcurrentExposureNoDg_ = currentShutter * analogueGain;\n>> -\t\tLOG(IPU3Agc, Debug) << \"Actual total exposure \" << currentExposureNoDg_\n>> -\t\t\t\t    << \" Shutter speed \" << currentShutter\n>> -\t\t\t\t    << \" Gain \" << analogueGain\n>> -\t\t\t\t    << \" Needed ev gain \" << evGain;\n>> +\tdouble evGain = kEvGainTarget * knumHistogramBins / iqMean_;\n>>   \n>> -\t\tcurrentExposure_ = prevExposureValue_ * evGain;\n>> -\t\tutils::Duration minShutterSpeed = minExposureLines_ * lineDuration_;\n>> -\t\tutils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_;\n>> +\t/* extracted from Rpi::Agc::computeTargetExposure */\n>> +\tutils::Duration currentShutter = exposure * lineDuration_;\n>> +\tcurrentExposureNoDg_ = currentShutter * analogueGain;\n>> +\tLOG(IPU3Agc, Debug) << \"Actual total exposure \" << currentExposureNoDg_\n>> +\t\t\t    << \" Shutter speed \" << currentShutter\n>> +\t\t\t    << \" Gain \" << analogueGain\n>> +\t\t\t    << \" Needed ev gain \" << evGain;\n>>   \n>> -\t\tutils::Duration maxTotalExposure = maxShutterSpeed * kMaxGain;\n>> -\t\tcurrentExposure_ = std::min(currentExposure_, maxTotalExposure);\n>> -\t\tLOG(IPU3Agc, Debug) << \"Target total exposure \" << currentExposure_\n>> -\t\t\t\t    << \", maximum is \" << maxTotalExposure;\n>> +\tcurrentExposure_ = prevExposureValue_ * evGain;\n>> +\tutils::Duration minShutterSpeed = minExposureLines_ * lineDuration_;\n>> +\tutils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_;\n>>   \n>> -\t\t/* \\todo: estimate if we need to desaturate */\n>> -\t\tfilterExposure();\n>> +\tutils::Duration maxTotalExposure = maxShutterSpeed * kMaxGain;\n>> +\tcurrentExposure_ = std::min(currentExposure_, maxTotalExposure);\n>> +\tLOG(IPU3Agc, Debug) << \"Target total exposure \" << currentExposure_\n>> +\t\t\t    << \", maximum is \" << maxTotalExposure;\n>>   \n>> -\t\tutils::Duration exposureValue = filteredExposure_;\n>> -\t\tutils::Duration shutterTime = minShutterSpeed;\n>> +\t/* \\todo: estimate if we need to desaturate */\n>> +\tfilterExposure();\n>>   \n>> -\t\t/*\n>> -\t\t * Push the shutter time up to the maximum first, and only then\n>> -\t\t * increase the gain.\n>> -\t\t */\n>> -\t\tshutterTime = std::clamp<utils::Duration>(exposureValue / kMinGain,\n>> -\t\t\t\t\t\t\t  minShutterSpeed, maxShutterSpeed);\n>> -\t\tdouble stepGain = std::clamp(exposureValue / shutterTime,\n>> -\t\t\t\t\t     kMinGain, kMaxGain);\n>> -\t\tLOG(IPU3Agc, Debug) << \"Divided up shutter and gain are \"\n>> -\t\t\t\t    << shutterTime << \" and \"\n>> -\t\t\t\t    << stepGain;\n>> +\tutils::Duration exposureValue = filteredExposure_;\n>> +\tutils::Duration shutterTime = minShutterSpeed;\n>>   \n>> -\t\texposure = shutterTime / lineDuration_;\n>> -\t\tanalogueGain = stepGain;\n>> +\t/*\n>> +\t* Push the shutter time up to the maximum first, and only then\n>> +\t* increase the gain.\n>> +\t*/\n>> +\tshutterTime = std::clamp<utils::Duration>(exposureValue / kMinGain,\n>> +\t\t\t\t\t\t  minShutterSpeed, maxShutterSpeed);\n>> +\tdouble stepGain = std::clamp(exposureValue / shutterTime,\n>> +\t\t\t\t     kMinGain, kMaxGain);\n>> +\tLOG(IPU3Agc, Debug) << \"Divided up shutter and gain are \"\n>> +\t\t\t    << shutterTime << \" and \"\n>> +\t\t\t    << stepGain;\n>> +\n>> +\texposure = shutterTime / lineDuration_;\n>> +\tanalogueGain = stepGain;\n>> +\n>> +\t/*\n>> +\t * Update the exposure value for the next process call.\n>> +\t *\n>> +\t * \\todo Obtain the values of the exposure time and analog gain\n>> +\t * that were actually used by the sensor, either from embedded\n>> +\t * data when available, or from the delayed controls\n>> +\t * infrastructure in case a slow down caused a mismatch.\n>> +\t */\n>> +\tprevExposureValue_ = shutterTime * analogueGain;\n>>   \n>> -\t\t/*\n>> -\t\t * Update the exposure value for the next process call.\n>> -\t\t *\n>> -\t\t * \\todo Obtain the values of the exposure time and analog gain\n>> -\t\t * that were actually used by the sensor, either from embedded\n>> -\t\t * data when available, or from the delayed controls\n>> -\t\t * infrastructure in case a slow down caused a mismatch.\n>> -\t\t */\n>> -\t\tprevExposureValue_ = shutterTime * analogueGain;\n>> -\t}\n>>   \tlastFrame_ = frameCount_;\n> \n> This is a functional change, with no mention of it (and no explanation\n> of why it's correct) in the commit message.\n\nMmmh, if is \"just\" about removing one else and a LOG() message... I 'm \nfailing to see the functional change here...\n\n> \n>>   }\n>>   \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 DDDF9BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 22 Oct 2021 05:56:55 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2645268F59;\n\tFri, 22 Oct 2021 07:56:55 +0200 (CEST)","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 69F5460123\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 22 Oct 2021 07:56:53 +0200 (CEST)","from [IPV6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367] (unknown\n\t[IPv6:2a01:e0a:169:7140:22cc:3af6:5ccb:8367])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id F136651D;\n\tFri, 22 Oct 2021 07:56:52 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"ps5TQjxU\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1634882213;\n\tbh=8vBvxzMmrjf3CiEoGwz0Z0vNPJ1C0/NkOkknXt8fkFI=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=ps5TQjxULsZzRQIZhRcMcPv7SiRgbWd/m34y17zVYxZS6eeWsU4Nnm3KnU1iNVDwC\n\tdGRvk90tlmoz0p7QMu3aZVLDAj8jRqd48C6H20D879MQc3XEoFes1f29A1Kh8ljWB9\n\t5QSxa25/hmMYbx1+TTr2HIB09G3z9O+aNbcDGp6A=","Message-ID":"<1c7162ac-6ff4-147a-ebbe-b9cb04278947@ideasonboard.com>","Date":"Fri, 22 Oct 2021 07:56:50 +0200","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.1.2","Content-Language":"en-US","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20211021164401.110033-1-jeanmichel.hautbois@ideasonboard.com>\n\t<20211021164401.110033-13-jeanmichel.hautbois@ideasonboard.com>\n\t<YXI9zFLoxui2exMN@pendragon.ideasonboard.com>","From":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","In-Reply-To":"<YXI9zFLoxui2exMN@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH v3 12/14] ipa: ipu3: agc: Refactor\n\tcondition on exposure correction","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":20376,"web_url":"https://patchwork.libcamera.org/comment/20376/","msgid":"<YXJU+TzGATzH1sDm@pendragon.ideasonboard.com>","date":"2021-10-22T06:06:49","subject":"Re: [libcamera-devel] [PATCH v3 12/14] ipa: ipu3: agc: Refactor\n\tcondition on exposure correction","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jean-Michel,\n\nOn Fri, Oct 22, 2021 at 07:56:50AM +0200, Jean-Michel Hautbois wrote:\n> On 22/10/2021 06:27, Laurent Pinchart wrote:\n> > On Thu, Oct 21, 2021 at 06:43:59PM +0200, Jean-Michel Hautbois wrote:\n> >> Until now, we can't know when the exposure and gains applied in the\n> >> IPAIPU3::setControls() are really applied (it can be several frames). We\n> >> don't want to use the values calculated as if they are already applied,\n> >> and this is done by testing the frame number.\n> >>\n> >> When the exposure is estimated, we verify if it changed enough for\n> >> exposure and gain to be updated.\n> >>\n> >> Keep the indentation level removal and simply return when the change is\n> >> so small there is no need to apply the newly calculated value.\n> > \n> > The first two paragraph seems unrelated to the version of this patch,\n> > and the \"keep\" in the third paragraph refers to how this has changed\n> > compared to v2. Please rewrite the commit message to correspond to the\n> > code changes.\n> \n> Let's try:\n> '''\n> Each time we test the brightness with the desired the target, we verify\n> if the change is small enough to consider that we are correctly exposed\n> or not. Simplify the reading by removing one level of indentation, and\n> returning from the function when the change is too small.\n> '''\n\nHow is the first sentence even relevant ? If you want to lower\nindentation by returning early, just say so, there's no need to explain\nwhat the code does.\n\n> >> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n> >> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> >> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> >> ---\n> >>   src/ipa/ipu3/algorithms/agc.cpp | 91 ++++++++++++++++-----------------\n> >>   1 file changed, 45 insertions(+), 46 deletions(-)\n> >>\n> >> diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp\n> >> index 43ef89df..7ff3029b 100644\n> >> --- a/src/ipa/ipu3/algorithms/agc.cpp\n> >> +++ b/src/ipa/ipu3/algorithms/agc.cpp\n> >> @@ -138,60 +138,59 @@ void Agc::lockExposureGain(uint32_t &exposure, double &analogueGain)\n> >>   \tif ((frameCount_ < kInitialFrameMinAECount) || (frameCount_ - lastFrame_ < kFrameSkipCount))\n> >>   \t\treturn;\n> >>   \n> >> -\t/* Are we correctly exposed ? */\n\nI haven't noticed before, the comment could be kept.\n\n> >> -\tif (std::abs(iqMean_ - kEvGainTarget * knumHistogramBins) <= 1) {\n> >> -\t\tLOG(IPU3Agc, Debug) << \"!!! Good exposure with iqMean = \" << iqMean_;\n\nAnd is there a particular reason to remove the log message ?\n\nPlease do *not* hide changes in a commit whose log message only mentions\nindentation changes.\n\n> >> -\t} else {\n> >> -\t\tdouble evGain = kEvGainTarget * knumHistogramBins / iqMean_;\n> >> +\tif (std::abs(iqMean_ - kEvGainTarget * knumHistogramBins) <= 1)\n> >> +\t\treturn;\n> >>   \n> >> -\t\t/* extracted from Rpi::Agc::computeTargetExposure */\n> >> -\t\tutils::Duration currentShutter = exposure * lineDuration_;\n> >> -\t\tcurrentExposureNoDg_ = currentShutter * analogueGain;\n> >> -\t\tLOG(IPU3Agc, Debug) << \"Actual total exposure \" << currentExposureNoDg_\n> >> -\t\t\t\t    << \" Shutter speed \" << currentShutter\n> >> -\t\t\t\t    << \" Gain \" << analogueGain\n> >> -\t\t\t\t    << \" Needed ev gain \" << evGain;\n> >> +\tdouble evGain = kEvGainTarget * knumHistogramBins / iqMean_;\n> >>   \n> >> -\t\tcurrentExposure_ = prevExposureValue_ * evGain;\n> >> -\t\tutils::Duration minShutterSpeed = minExposureLines_ * lineDuration_;\n> >> -\t\tutils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_;\n> >> +\t/* extracted from Rpi::Agc::computeTargetExposure */\n> >> +\tutils::Duration currentShutter = exposure * lineDuration_;\n> >> +\tcurrentExposureNoDg_ = currentShutter * analogueGain;\n> >> +\tLOG(IPU3Agc, Debug) << \"Actual total exposure \" << currentExposureNoDg_\n> >> +\t\t\t    << \" Shutter speed \" << currentShutter\n> >> +\t\t\t    << \" Gain \" << analogueGain\n> >> +\t\t\t    << \" Needed ev gain \" << evGain;\n> >>   \n> >> -\t\tutils::Duration maxTotalExposure = maxShutterSpeed * kMaxGain;\n> >> -\t\tcurrentExposure_ = std::min(currentExposure_, maxTotalExposure);\n> >> -\t\tLOG(IPU3Agc, Debug) << \"Target total exposure \" << currentExposure_\n> >> -\t\t\t\t    << \", maximum is \" << maxTotalExposure;\n> >> +\tcurrentExposure_ = prevExposureValue_ * evGain;\n> >> +\tutils::Duration minShutterSpeed = minExposureLines_ * lineDuration_;\n> >> +\tutils::Duration maxShutterSpeed = maxExposureLines_ * lineDuration_;\n> >>   \n> >> -\t\t/* \\todo: estimate if we need to desaturate */\n> >> -\t\tfilterExposure();\n> >> +\tutils::Duration maxTotalExposure = maxShutterSpeed * kMaxGain;\n> >> +\tcurrentExposure_ = std::min(currentExposure_, maxTotalExposure);\n> >> +\tLOG(IPU3Agc, Debug) << \"Target total exposure \" << currentExposure_\n> >> +\t\t\t    << \", maximum is \" << maxTotalExposure;\n> >>   \n> >> -\t\tutils::Duration exposureValue = filteredExposure_;\n> >> -\t\tutils::Duration shutterTime = minShutterSpeed;\n> >> +\t/* \\todo: estimate if we need to desaturate */\n> >> +\tfilterExposure();\n> >>   \n> >> -\t\t/*\n> >> -\t\t * Push the shutter time up to the maximum first, and only then\n> >> -\t\t * increase the gain.\n> >> -\t\t */\n> >> -\t\tshutterTime = std::clamp<utils::Duration>(exposureValue / kMinGain,\n> >> -\t\t\t\t\t\t\t  minShutterSpeed, maxShutterSpeed);\n> >> -\t\tdouble stepGain = std::clamp(exposureValue / shutterTime,\n> >> -\t\t\t\t\t     kMinGain, kMaxGain);\n> >> -\t\tLOG(IPU3Agc, Debug) << \"Divided up shutter and gain are \"\n> >> -\t\t\t\t    << shutterTime << \" and \"\n> >> -\t\t\t\t    << stepGain;\n> >> +\tutils::Duration exposureValue = filteredExposure_;\n> >> +\tutils::Duration shutterTime = minShutterSpeed;\n> >>   \n> >> -\t\texposure = shutterTime / lineDuration_;\n> >> -\t\tanalogueGain = stepGain;\n> >> +\t/*\n> >> +\t* Push the shutter time up to the maximum first, and only then\n> >> +\t* increase the gain.\n> >> +\t*/\n> >> +\tshutterTime = std::clamp<utils::Duration>(exposureValue / kMinGain,\n> >> +\t\t\t\t\t\t  minShutterSpeed, maxShutterSpeed);\n> >> +\tdouble stepGain = std::clamp(exposureValue / shutterTime,\n> >> +\t\t\t\t     kMinGain, kMaxGain);\n> >> +\tLOG(IPU3Agc, Debug) << \"Divided up shutter and gain are \"\n> >> +\t\t\t    << shutterTime << \" and \"\n> >> +\t\t\t    << stepGain;\n> >> +\n> >> +\texposure = shutterTime / lineDuration_;\n> >> +\tanalogueGain = stepGain;\n> >> +\n> >> +\t/*\n> >> +\t * Update the exposure value for the next process call.\n> >> +\t *\n> >> +\t * \\todo Obtain the values of the exposure time and analog gain\n> >> +\t * that were actually used by the sensor, either from embedded\n> >> +\t * data when available, or from the delayed controls\n> >> +\t * infrastructure in case a slow down caused a mismatch.\n> >> +\t */\n> >> +\tprevExposureValue_ = shutterTime * analogueGain;\n> >>   \n> >> -\t\t/*\n> >> -\t\t * Update the exposure value for the next process call.\n> >> -\t\t *\n> >> -\t\t * \\todo Obtain the values of the exposure time and analog gain\n> >> -\t\t * that were actually used by the sensor, either from embedded\n> >> -\t\t * data when available, or from the delayed controls\n> >> -\t\t * infrastructure in case a slow down caused a mismatch.\n> >> -\t\t */\n> >> -\t\tprevExposureValue_ = shutterTime * analogueGain;\n> >> -\t}\n> >>   \tlastFrame_ = frameCount_;\n> > \n> > This is a functional change, with no mention of it (and no explanation\n> > of why it's correct) in the commit message.\n> \n> Mmmh, if is \"just\" about removing one else and a LOG() message... I 'm \n> failing to see the functional change here...\n\nBefore this patch, lastFrame_ was set for both branches. With this\npatch, as you return early, lastFrame_ doesn't get set when the change\nis small.\n\n> >>   }\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 84CFABDB1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 22 Oct 2021 06:07:11 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A8D9C68F5B;\n\tFri, 22 Oct 2021 08:07:10 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 080DF60123\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 22 Oct 2021 08:07:09 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 70AD351D;\n\tFri, 22 Oct 2021 08:07:08 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"azRAOZiB\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1634882828;\n\tbh=dgjKH0mT+KAfohK/z52vkyiH70oRNZ3ih5jgm7qGMvM=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=azRAOZiBBZz3poH8uZlWSjiR5/wbyI60/ZmXieiF2Qzcp672WUv7mb1geTyl4ARqG\n\tpXENon/BQTnZhZn8eRDT9ZAnmEewSvaCY2uhZv7ogJyGAe1qawE3/hHtI/b6EEW07r\n\t88zzLkmZESYaQgHFRPkOgMbOdM5sPl2YGA/LdJa8=","Date":"Fri, 22 Oct 2021 09:06:49 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","Message-ID":"<YXJU+TzGATzH1sDm@pendragon.ideasonboard.com>","References":"<20211021164401.110033-1-jeanmichel.hautbois@ideasonboard.com>\n\t<20211021164401.110033-13-jeanmichel.hautbois@ideasonboard.com>\n\t<YXI9zFLoxui2exMN@pendragon.ideasonboard.com>\n\t<1c7162ac-6ff4-147a-ebbe-b9cb04278947@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<1c7162ac-6ff4-147a-ebbe-b9cb04278947@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v3 12/14] ipa: ipu3: agc: Refactor\n\tcondition on exposure correction","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]