[{"id":33126,"web_url":"https://patchwork.libcamera.org/comment/33126/","msgid":"<20250121171546.GA573@pendragon.ideasonboard.com>","date":"2025-01-21T17:15:46","subject":"Re: [PATCH 3/3] ipa: libipa: Add flicker controls to\n\tAgcMeanLuminance","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Dan,\n\nThank you for the patch.\n\nOn Fri, Jan 17, 2025 at 02:34:10PM +0000, Daniel Scally wrote:\n> Add controls for AeFlickerMode and AeFlickerPeriod to the\n> AgcMeanLuminance class. The controls passed to an algorithm's\n> queueRequest() are forwarded to AgcMeanLuminance through a new\n> function, and the values then passed to the ExposureModeHelper to be\n> used in calculating the new exposure time.\n> \n> Take the opportunity to call the new parseControls() function in each\n> of the derived class' queueRequest() function.\n> \n> Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n> ---\n>  src/ipa/ipu3/algorithms/agc.cpp       |  3 +-\n>  src/ipa/libipa/agc_mean_luminance.cpp | 47 ++++++++++++++++++++++++++-\n>  src/ipa/libipa/agc_mean_luminance.h   |  5 +++\n>  src/ipa/mali-c55/algorithms/agc.cpp   |  2 ++\n>  src/ipa/rkisp1/algorithms/agc.cpp     |  2 ++\n>  5 files changed, 57 insertions(+), 2 deletions(-)\n> \n> diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp\n> index 383b046c..b993aaa7 100644\n> --- a/src/ipa/ipu3/algorithms/agc.cpp\n> +++ b/src/ipa/ipu3/algorithms/agc.cpp\n> @@ -129,8 +129,9 @@ int Agc::configure(IPAContext &context,\n>  void Agc::queueRequest([[maybe_unused]] typename Module::Context &context,\n>  \t\t       [[maybe_unused]] const uint32_t frame,\n>  \t\t       [[maybe_unused]] typename Module::FrameContext &frameContext,\n> -\t\t       [[maybe_unused]] const ControlList &controls)\n> +\t\t       const ControlList &controls)\n>  {\n> +\tparseControls(controls);\n>  }\n>  \n>  Histogram Agc::parseStatistics(const ipu3_uapi_stats_3a *stats,\n> diff --git a/src/ipa/libipa/agc_mean_luminance.cpp b/src/ipa/libipa/agc_mean_luminance.cpp\n> index b5e6afe3..4acf7b55 100644\n> --- a/src/ipa/libipa/agc_mean_luminance.cpp\n> +++ b/src/ipa/libipa/agc_mean_luminance.cpp\n> @@ -136,6 +136,10 @@ static constexpr double kDefaultRelativeLuminanceTarget = 0.16;\n>  AgcMeanLuminance::AgcMeanLuminance()\n>  \t: frameCount_(0), filteredExposure_(0s), relativeLuminanceTarget_(0)\n>  {\n> +\tcontrols_[&controls::AeFlickerMode] = ControlInfo(static_cast<int>(controls::FlickerOff),\n> +\t\t\t\t\t\t\t  static_cast<int>(controls::FlickerManual),\n> +\t\t\t\t\t\t\t  static_cast<int>(controls::FlickerOff));\n> +\tcontrols_[&controls::AeFlickerPeriod] = ControlInfo(100, 1000000);\n>  }\n>  \n>  AgcMeanLuminance::~AgcMeanLuminance() = default;\n> @@ -479,6 +483,39 @@ double AgcMeanLuminance::constraintClampGain(uint32_t constraintModeIndex,\n>  \treturn gain;\n>  }\n>  \n> +/**\n> + * \\brief Parse the controls passed to an algorithm for the ones we need\n> + * \\param[in] controls the ControlList passed to an algorithm by the IPA\n> + *\n> + * This function must be called by a derived class in its queueRequest()\n> + * function so that we can extract the controls needed by this base class.\n> + */\n> +void AgcMeanLuminance::parseControls(const ControlList &controls)\n> +{\n> +\tconst auto &flickerMode = controls.get(controls::AeFlickerMode);\n> +\tif (flickerMode) {\n> +\t\tswitch (*flickerMode) {\n> +\t\tcase controls::AeFlickerModeEnum::FlickerOff:\n> +\t\tcase controls::AeFlickerModeEnum::FlickerManual:\n> +\t\t\tflickerMode_ = static_cast<controls::AeFlickerModeEnum>(*flickerMode);\n> +\t\t\tbreak;\n> +\t\tdefault:\n> +\t\t\tLOG(AgcMeanLuminance, Error)\n> +\t\t\t\t<< \"Flicker mode \" << *flickerMode << \" is not supported\";\n> +\t\t\tbreak;\n> +\t\t}\n> +\t}\n> +\n> +\tconst auto &flickerPeriod = controls.get(controls::AeFlickerPeriod);\n> +\tif (flickerPeriod) {\n> +\t\t/*\n> +\t\t * If at some future point we support automatic flicker\n> +\t\t * mitigation then this will need revision.\n> +\t\t */\n> +\t\tflickerPeriod_ = *flickerPeriod * 1.0us;\n> +\t}\n> +}\n> +\n>  /**\n>   * \\brief Apply a filter on the exposure value to limit the speed of changes\n>   * \\param[in] exposureValue The target exposure from the AGC algorithm\n> @@ -560,7 +597,15 @@ AgcMeanLuminance::calculateNewEv(uint32_t constraintModeIndex,\n>  \tnewExposureValue = filterExposure(newExposureValue);\n>  \n>  \tframeCount_++;\n> -\treturn exposureModeHelper->splitExposure(newExposureValue, 0us);\n> +\n> +\tutils::Duration flickerPeriod;\n> +\n> +\tif (flickerMode_ == controls::AeFlickerModeEnum::FlickerManual)\n> +\t\tflickerPeriod = flickerPeriod_;\n> +\telse\n> +\t\tflickerPeriod = 0us;\n> +\n> +\treturn exposureModeHelper->splitExposure(newExposureValue, flickerPeriod);\n>  }\n>  \n>  /**\n> diff --git a/src/ipa/libipa/agc_mean_luminance.h b/src/ipa/libipa/agc_mean_luminance.h\n> index c41391cb..b9b36687 100644\n> --- a/src/ipa/libipa/agc_mean_luminance.h\n> +++ b/src/ipa/libipa/agc_mean_luminance.h\n> @@ -14,6 +14,7 @@\n>  \n>  #include <libcamera/base/utils.h>\n>  \n> +#include <libcamera/control_ids.h>\n>  #include <libcamera/controls.h>\n>  \n>  #include \"libcamera/internal/yaml_parser.h\"\n> @@ -71,6 +72,8 @@ public:\n>  \t\tframeCount_ = 0;\n>  \t}\n>  \n> +\tvoid parseControls(const ControlList &controls);\n> +\n>  private:\n>  \tvirtual double estimateLuminance(const double gain) const = 0;\n>  \n> @@ -87,6 +90,8 @@ private:\n>  \tuint64_t frameCount_;\n>  \tutils::Duration filteredExposure_;\n>  \tdouble relativeLuminanceTarget_;\n> +\tutils::Duration flickerPeriod_;\n> +\tcontrols::AeFlickerModeEnum flickerMode_;\n\nThese can probably be replaced by a\n\n\tstd::optional<utils::Duration> flickerPeriod_;\n\ntoo.\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n>  \n>  \tstd::map<int32_t, std::vector<AgcConstraint>> constraintModes_;\n>  \tstd::map<int32_t, std::shared_ptr<ExposureModeHelper>> exposureModeHelpers_;\n> diff --git a/src/ipa/mali-c55/algorithms/agc.cpp b/src/ipa/mali-c55/algorithms/agc.cpp\n> index 70667db3..6a80c44f 100644\n> --- a/src/ipa/mali-c55/algorithms/agc.cpp\n> +++ b/src/ipa/mali-c55/algorithms/agc.cpp\n> @@ -238,6 +238,8 @@ void Agc::queueRequest(IPAContext &context, const uint32_t frame,\n>  \t\t\t<< \"Digital gain set to \" << agc.manual.ispGain\n>  \t\t\t<< \" on request sequence \" << frame;\n>  \t}\n> +\n> +\tparseControls(controls);\n>  }\n>  \n>  size_t Agc::fillGainParamBlock(IPAContext &context, IPAFrameContext &frameContext,\n> diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp\n> index 40e5a8f4..7b1763a2 100644\n> --- a/src/ipa/rkisp1/algorithms/agc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/agc.cpp\n> @@ -275,6 +275,8 @@ void Agc::queueRequest(IPAContext &context,\n>  \t\tagc.maxFrameDuration = maxFrameDuration;\n>  \t}\n>  \tframeContext.agc.maxFrameDuration = agc.maxFrameDuration;\n> +\n> +\tparseControls(controls);\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 036E7BD16B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 21 Jan 2025 17:15:57 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 08AAC68550;\n\tTue, 21 Jan 2025 18:15:57 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C94F368503\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 21 Jan 2025 18:15:55 +0100 (CET)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id BFB0E788;\n\tTue, 21 Jan 2025 18:14:52 +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=\"Mgc6sdwi\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1737479693;\n\tbh=BsRK/U4IKYxD4WsbVOygGvVFSKAhGXoPUGyYmMw6lHM=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Mgc6sdwiRWHfEY3mJYMCZm3ZlaWvXarSmAIGWU+X75MNCgXs964MiHaU2hIPWZ9Yl\n\tI3LxGQbpcQry/NHrwhlwFS1PJKdZrG6WQL8mZw2JIFVjKdULZJG52pHycUeYEBcS6g\n\t9CH+ZDFHa8Xk28v7Yy2I2HvpBOc8TPtX3YtbklIM=","Date":"Tue, 21 Jan 2025 19:15:46 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Daniel Scally <dan.scally@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH 3/3] ipa: libipa: Add flicker controls to\n\tAgcMeanLuminance","Message-ID":"<20250121171546.GA573@pendragon.ideasonboard.com>","References":"<20250117143410.20363-1-dan.scally@ideasonboard.com>\n\t<20250117143410.20363-4-dan.scally@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20250117143410.20363-4-dan.scally@ideasonboard.com>","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>"}}]