{"id":22637,"url":"https://patchwork.libcamera.org/api/1.1/patches/22637/?format=json","web_url":"https://patchwork.libcamera.org/patch/22637/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20250123140727.458567-4-dan.scally@ideasonboard.com>","date":"2025-01-23T14:07:27","name":"[v2,3/3] ipa: libipa: Add flicker controls to AgcMeanLuminance","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"eb408fafd22fcf188f568c5ecb3da9609e44b385","submitter":{"id":156,"url":"https://patchwork.libcamera.org/api/1.1/people/156/?format=json","name":"Dan Scally","email":"dan.scally@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/22637/mbox/","series":[{"id":4968,"url":"https://patchwork.libcamera.org/api/1.1/series/4968/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=4968","date":"2025-01-23T14:07:24","name":"Add flicker mitigation controls to AgcMeanLuminance","version":2,"mbox":"https://patchwork.libcamera.org/series/4968/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/22637/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/22637/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 A37BABDE6B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 23 Jan 2025 14:07:55 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 418B568566;\n\tThu, 23 Jan 2025 15:07:53 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 58EB36855B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 23 Jan 2025 15:07:46 +0100 (CET)","from mail.ideasonboard.com\n\t(cpc141996-chfd3-2-0-cust928.12-3.cable.virginm.net [86.13.91.161])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B0E7A89A;\n\tThu, 23 Jan 2025 15:06:42 +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=\"maqFTaZR\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1737641202;\n\tbh=aRdq7cLKNsCqtN3GGXJJYxx7IUhDmvcDMHJ3PDLWDCs=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=maqFTaZRO4hHWsW9mFLoHjtcUPjbldhVj1EGJWQybjIIYuPdNEJTYdLqcyAIX8wgx\n\t79TRpifEuytFwCEpdrjBJjGLWiyPxPXFmLybjx5vnybBUKXdrZ5LyYcWh1Cqombcks\n\tD3nwrMI3LLujT8gcoIKgVwqnGhXXALjTnZx/+qhE=","From":"Daniel Scally <dan.scally@ideasonboard.com>","To":"libcamera-devel@lists.libcamera.org","Cc":"Daniel Scally <dan.scally@ideasonboard.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tPaul Elder <paul.elder@ideasonboard.com>","Subject":"[PATCH v2 3/3] ipa: libipa: Add flicker controls to AgcMeanLuminance","Date":"Thu, 23 Jan 2025 14:07:27 +0000","Message-Id":"<20250123140727.458567-4-dan.scally@ideasonboard.com>","X-Mailer":"git-send-email 2.34.1","In-Reply-To":"<20250123140727.458567-1-dan.scally@ideasonboard.com>","References":"<20250123140727.458567-1-dan.scally@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":"Add controls for AeFlickerMode and AeFlickerPeriod to the\nAgcMeanLuminance class. The controls passed to an algorithm's\nqueueRequest() are forwarded to AgcMeanLuminance through a new\nfunction, and the values then passed to the ExposureModeHelper to be\nused in calculating the new exposure time.\n\nTake the opportunity to call the new parseControls() function in each\nof the derived class' queueRequest() function.\n\nSigned-off-by: Daniel Scally <dan.scally@ideasonboard.com>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n---\nChanges in v2:\n\n\t- Declared the controls using a span rather than min and max values\n\t- Used a std::optional to pass to the ExposureModeHelper. I didn't use\n\t  it in the IPAContext, because it can't really be modelled as a single\n\t  variable option there.\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(-)","diff":"diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp\nindex 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,\ndiff --git a/src/ipa/libipa/agc_mean_luminance.cpp b/src/ipa/libipa/agc_mean_luminance.cpp\nindex 273ec4e5..65285bf1 100644\n--- a/src/ipa/libipa/agc_mean_luminance.cpp\n+++ b/src/ipa/libipa/agc_mean_luminance.cpp\n@@ -137,6 +137,10 @@ static constexpr double kDefaultRelativeLuminanceTarget = 0.16;\n AgcMeanLuminance::AgcMeanLuminance()\n \t: frameCount_(0), filteredExposure_(0s), relativeLuminanceTarget_(0)\n {\n+\tcontrols_[&controls::AeFlickerMode] = ControlInfo({ { ControlValue(controls::FlickerOff),\n+\t\t\t\t\t\t\t      ControlValue(controls::FlickerManual) } },\n+\t\t\t\t\t\t\t  ControlValue(controls::FlickerOff));\n+\tcontrols_[&controls::AeFlickerPeriod] = ControlInfo(100, 1000000);\n }\n \n AgcMeanLuminance::~AgcMeanLuminance() = default;\n@@ -480,6 +484,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@@ -561,7 +598,15 @@ AgcMeanLuminance::calculateNewEv(uint32_t constraintModeIndex,\n \tnewExposureValue = filterExposure(newExposureValue);\n \n \tframeCount_++;\n-\treturn exposureModeHelper->splitExposure(newExposureValue, std::nullopt);\n+\n+\tstd::optional<utils::Duration> flickerPeriod;\n+\n+\tif (flickerMode_ == controls::AeFlickerModeEnum::FlickerManual)\n+\t\tflickerPeriod = flickerPeriod_;\n+\telse\n+\t\tflickerPeriod = std::nullopt;\n+\n+\treturn exposureModeHelper->splitExposure(newExposureValue, flickerPeriod);\n }\n \n /**\ndiff --git a/src/ipa/libipa/agc_mean_luminance.h b/src/ipa/libipa/agc_mean_luminance.h\nindex 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 \n \tstd::map<int32_t, std::vector<AgcConstraint>> constraintModes_;\n \tstd::map<int32_t, std::shared_ptr<ExposureModeHelper>> exposureModeHelpers_;\ndiff --git a/src/ipa/mali-c55/algorithms/agc.cpp b/src/ipa/mali-c55/algorithms/agc.cpp\nindex 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,\ndiff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp\nindex 1680669c..fd2eda96 100644\n--- a/src/ipa/rkisp1/algorithms/agc.cpp\n+++ b/src/ipa/rkisp1/algorithms/agc.cpp\n@@ -315,6 +315,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 /**\n","prefixes":["v2","3/3"]}