{"id":26358,"url":"https://patchwork.libcamera.org/api/patches/26358/?format=json","web_url":"https://patchwork.libcamera.org/patch/26358/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/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":"<20260325151416.2114564-17-stefan.klug@ideasonboard.com>","date":"2026-03-25T15:13:48","name":"[v2,16/32] ipa: rkisp1: agc: Process frame duration at the right time","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"e7f4ac76ca6ec011e4644cb6b1069f636d191e73","submitter":{"id":184,"url":"https://patchwork.libcamera.org/api/people/184/?format=json","name":"Stefan Klug","email":"stefan.klug@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/26358/mbox/","series":[{"id":5849,"url":"https://patchwork.libcamera.org/api/series/5849/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=5849","date":"2026-03-25T15:13:32","name":"rkisp1: pipeline rework for PFC","version":2,"mbox":"https://patchwork.libcamera.org/series/5849/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/26358/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/26358/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 CF490C3301\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 25 Mar 2026 15:15:27 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5188162BDE;\n\tWed, 25 Mar 2026 16:15:27 +0100 (CET)","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 165C462B91\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 25 Mar 2026 16:15:26 +0100 (CET)","from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:b16a:5ed9:4ada:a95a])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 22B271AFB; \n\tWed, 25 Mar 2026 16:14:08 +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=\"M0/DvBoK\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1774451648;\n\tbh=oAi/9LLTASwPFAIPya7rkzLto5JItlOEGT7r+u/Ulgk=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=M0/DvBoKzdTZnsG9wTYfejBBrjN3UuzRjviN/QyW8BePmzd+bA2o5l7W0/folNx/8\n\t462bhuRcmgXIKfwogqR23/eKI51hky4CUFzjZccZ5sU54j5FPHJ2HV2fzMe1FI0yaE\n\tZpOq2cx+eOuVIEY1vNyFtsMaE8g859yTsPxhe7rs=","From":"Stefan Klug <stefan.klug@ideasonboard.com>","To":"libcamera-devel@lists.libcamera.org","Cc":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tPaul Elder <paul.elder@ideasonboard.com>","Subject":"[PATCH v2 16/32] ipa: rkisp1: agc: Process frame duration at the\n\tright time","Date":"Wed, 25 Mar 2026 16:13:48 +0100","Message-ID":"<20260325151416.2114564-17-stefan.klug@ideasonboard.com>","X-Mailer":"git-send-email 2.51.0","In-Reply-To":"<20260325151416.2114564-1-stefan.klug@ideasonboard.com>","References":"<20260325151416.2114564-1-stefan.klug@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":"The frame duration and vblank should not be calculated during process()\nbut within prepare(), where the data for that frame get's computed.\n\nIn raw mode, process is not called, so also update it in queueRequest().\n\nSigned-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n\n---\n\nChanges in v2:\n- Squashed with next patch\n- Collected tag\n---\n src/ipa/rkisp1/algorithms/agc.cpp | 23 +++++++++++++----------\n src/ipa/rkisp1/algorithms/agc.h   |  3 +--\n 2 files changed, 14 insertions(+), 12 deletions(-)","diff":"diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp\nindex fd227e2129ed..4a7b8988221d 100644\n--- a/src/ipa/rkisp1/algorithms/agc.cpp\n+++ b/src/ipa/rkisp1/algorithms/agc.cpp\n@@ -340,6 +340,9 @@ void Agc::queueRequest(IPAContext &context,\n \t}\n \tframeContext.agc.minFrameDuration = agc.minFrameDuration;\n \tframeContext.agc.maxFrameDuration = agc.maxFrameDuration;\n+\n+\t/* V-blank needs to be valid for the start controls handling. Update it. */\n+\tprocessFrameDuration(context, frameContext);\n }\n \n /**\n@@ -383,6 +386,12 @@ void Agc::prepare(IPAContext &context, const uint32_t frame,\n \n \tframeContext.agc.yTarget = context.activeState.agc.automatic.yTarget;\n \n+\t/*\n+\t * Expand the target frame duration so that we do not run faster than\n+\t * the minimum frame duration when we have short exposures.\n+\t */\n+\tprocessFrameDuration(context, frameContext);\n+\n \tif (frame > 0 && !frameContext.agc.updateMetering)\n \t\treturn;\n \n@@ -511,11 +520,13 @@ double Agc::estimateLuminance(double gain) const\n  * Compute and populate vblank from the target frame duration.\n  */\n void Agc::processFrameDuration(IPAContext &context,\n-\t\t\t       IPAFrameContext &frameContext,\n-\t\t\t       utils::Duration frameDuration)\n+\t\t\t       IPAFrameContext &frameContext)\n {\n \tIPACameraSensorInfo &sensorInfo = context.sensorInfo;\n \tutils::Duration lineDuration = context.configuration.sensor.lineDuration;\n+\tutils::Duration frameDuration = frameContext.agc.exposure * lineDuration;\n+\n+\tframeDuration = std::max(frameDuration, frameContext.agc.minFrameDuration);\n \n \tframeContext.agc.vblank = (frameDuration / lineDuration) - sensorInfo.outputSize.height;\n \n@@ -539,8 +550,6 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,\n \t\t  ControlList &metadata)\n {\n \tif (!stats) {\n-\t\tprocessFrameDuration(context, frameContext,\n-\t\t\t\t     frameContext.agc.minFrameDuration);\n \t\tfillMetadata(context, frameContext, metadata);\n \t\treturn;\n \t}\n@@ -642,12 +651,6 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,\n \tactiveState.agc.automatic.gain = aGain;\n \tactiveState.agc.automatic.quantizationGain = qGain;\n \tactiveState.agc.automatic.yTarget = effectiveYTarget();\n-\t/*\n-\t * Expand the target frame duration so that we do not run faster than\n-\t * the minimum frame duration when we have short exposures.\n-\t */\n-\tprocessFrameDuration(context, frameContext,\n-\t\t\t     std::max(frameContext.agc.minFrameDuration, newExposureTime));\n \n \tfillMetadata(context, frameContext, metadata);\n \texpMeans_ = {};\ndiff --git a/src/ipa/rkisp1/algorithms/agc.h b/src/ipa/rkisp1/algorithms/agc.h\nindex 7867eed9c4e3..4432711f43af 100644\n--- a/src/ipa/rkisp1/algorithms/agc.h\n+++ b/src/ipa/rkisp1/algorithms/agc.h\n@@ -51,8 +51,7 @@ private:\n \t\t\t  ControlList &metadata);\n \tdouble estimateLuminance(double gain) const override;\n \tvoid processFrameDuration(IPAContext &context,\n-\t\t\t\t  IPAFrameContext &frameContext,\n-\t\t\t\t  utils::Duration frameDuration);\n+\t\t\t\t  IPAFrameContext &frameContext);\n \n \tSpan<const uint8_t> expMeans_;\n \tSpan<const uint8_t> weights_;\n","prefixes":["v2","16/32"]}