From patchwork Mon Aug 3 13:14:34 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27598 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 785B7C3350 for ; Mon, 3 Aug 2026 13:15:27 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 771286811E; Mon, 3 Aug 2026 15:15:25 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Nz9QHrYe"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BF39E68075 for ; Mon, 3 Aug 2026 15:14:49 +0200 (CEST) Received: from pb-laptop.local (185.221.141.208.nat.pool.zt.hu [185.221.141.208]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DDC51512 for ; Mon, 3 Aug 2026 15:13:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1785762820; bh=UQb6u+AzrJyQBlWloxXjUlpt0xqzbCYGmOJsyP74WEg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Nz9QHrYegXgY0btiinIQ61+hP48KZxZhVAuyHYvAbZftH4C4+6irlCCGkBzNxe8WS QkE5DmYHqCS9zpgjO5rTI0ogYcsxYTZ0EpccJAou/MTjQcWwt32kT6+uqIeGHJ6+SQ Agb7DO6+hw+PyPQdgbo7erZ4hh1agqGfCq+z4ABc= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v3 49/50] libcamera: pipeline: Set vblank on more platforms Date: Mon, 3 Aug 2026 15:14:34 +0200 Message-ID: <20260803131435.153927-50-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260803131435.153927-1-barnabas.pocze@ideasonboard.com> References: <20260803131435.153927-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The common `AgcAlgorithm` provides the desired vblank value the given frame, so adjust `agc::prepareControls()` accordingly, and propagate the vblank value to the sensors in the pipeline handlers. Signed-off-by: Barnabás Pőcze --- src/ipa/ipu3/ipu3.cpp | 5 +- src/ipa/libipa/agc.h | 48 +++++++++++--------- src/ipa/mali-c55/mali-c55.cpp | 2 +- src/ipa/rkisp1/rkisp1.cpp | 3 +- src/ipa/simple/soft_simple.cpp | 2 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 1 + src/libcamera/pipeline/mali-c55/mali-c55.cpp | 1 + src/libcamera/pipeline/simple/simple.cpp | 1 + 8 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 0935050a33..7db7270480 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -551,10 +551,7 @@ void IPAIPU3::setControls(unsigned int frame) IPAFrameContext &frameContext = context_.frameContexts.get(frame); ControlList ctrls(context_.sensorControls); - agc::prepareControls( - ctrls, context_.camHelper.get(), - frameContext.agc.exposure, frameContext.agc.gain - ); + agc::prepareControls(ctrls, context_.camHelper.get(), frameContext.agc); ControlList lensCtrls(lensCtrls_); lensCtrls.set(V4L2_CID_FOCUS_ABSOLUTE, diff --git a/src/ipa/libipa/agc.h b/src/ipa/libipa/agc.h index 4f8038ae41..97153541fc 100644 --- a/src/ipa/libipa/agc.h +++ b/src/ipa/libipa/agc.h @@ -29,27 +29,6 @@ namespace ipa { namespace agc { -[[nodiscard]] -inline std::pair -extractControls(const ControlList &controls, const CameraSensorHelper *sensor) -{ - auto exposure = controls.get(V4L2_CID_EXPOSURE).get(); - auto gainCode = controls.get(V4L2_CID_ANALOGUE_GAIN).get(); - - return { - uint32_t(exposure), - sensor ? sensor->gain(gainCode) : gainCode, - }; -} - -inline void -prepareControls(ControlList &controls, const CameraSensorHelper *sensor, - int32_t exposure, double gain) -{ - controls.set(V4L2_CID_EXPOSURE, exposure); - controls.set(V4L2_CID_ANALOGUE_GAIN, int32_t(sensor ? sensor->gainCode(gain) : gain)); -} - struct Session { utils::Duration minExposureTime; utils::Duration maxExposureTime; @@ -108,6 +87,33 @@ struct FrameContext { bool autoGainModeChange; }; + +[[nodiscard]] +inline std::pair +extractControls(const ControlList &controls, const CameraSensorHelper *sensor) +{ + auto exposure = controls.get(V4L2_CID_EXPOSURE).get(); + auto gainCode = controls.get(V4L2_CID_ANALOGUE_GAIN).get(); + + return { + uint32_t(exposure), + sensor ? sensor->gain(gainCode) : gainCode, + }; +} + +inline void +prepareControls(ControlList &controls, const CameraSensorHelper *sensor, + const FrameContext &frameContext) +{ + uint32_t gain = sensor + ? sensor->gainCode(frameContext.gain) + : uint32_t(frameContext.gain); + + controls.set(V4L2_CID_EXPOSURE, int32_t(frameContext.exposure)); + controls.set(V4L2_CID_ANALOGUE_GAIN, int32_t(gain)); + controls.set(V4L2_CID_VBLANK, int32_t(frameContext.vblank)); +} + } /* namespace agc */ class AgcAlgorithm diff --git a/src/ipa/mali-c55/mali-c55.cpp b/src/ipa/mali-c55/mali-c55.cpp index c0c2c83dca..160f7ac88a 100644 --- a/src/ipa/mali-c55/mali-c55.cpp +++ b/src/ipa/mali-c55/mali-c55.cpp @@ -133,7 +133,7 @@ int IPAMaliC55::init(const IPASettings &settings, const IPAConfigInfo &ipaConfig void IPAMaliC55::setControls(const IPAFrameContext &frameContext) { ControlList ctrls(context_.sensorControls); - agc::prepareControls(ctrls, context_.camHelper.get(), frameContext.agc.exposure, frameContext.agc.gain); + agc::prepareControls(ctrls, context_.camHelper.get(), frameContext.agc); setSensorControls.emit(ctrls); } diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 6425d8f1e8..033e69f9f0 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -367,8 +367,7 @@ void IPARkISP1::setControls(unsigned int frame) << ", gain " << frameContext.agc.gain << ", vblank " << vblank; ControlList ctrls(context_.sensorControls); - agc::prepareControls(ctrls, context_.camHelper.get(), exposure, frameContext.agc.gain); - ctrls.set(V4L2_CID_VBLANK, static_cast(vblank)); + agc::prepareControls(ctrls, context_.camHelper.get(), frameContext.agc); setSensorControls.emit(frame, ctrls); } diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp index f35e269deb..5d1e0deb87 100644 --- a/src/ipa/simple/soft_simple.cpp +++ b/src/ipa/simple/soft_simple.cpp @@ -249,7 +249,7 @@ void IPASoftSimple::processStats(const uint32_t frame, metadataReady.emit(frame, metadata); ControlList ctrls(context_.sensorControls); - agc::prepareControls(ctrls, context_.camHelper.get(), frameContext.agc.exposure, frameContext.agc.gain); + agc::prepareControls(ctrls, context_.camHelper.get(), frameContext.agc); setSensorControls.emit(ctrls); } diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 0f3e169d3b..4147f9475a 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -1084,6 +1084,7 @@ int PipelineHandlerIPU3::registerCameras() std::unordered_map params = { { V4L2_CID_ANALOGUE_GAIN, { delays.gainDelay, false } }, { V4L2_CID_EXPOSURE, { delays.exposureDelay, false } }, + { V4L2_CID_VBLANK, { delays.vblankDelay, true } }, }; data->delayedCtrls_ = diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp index 599ff88b59..ef156d421b 100644 --- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp +++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp @@ -1909,6 +1909,7 @@ bool PipelineHandlerMaliC55::registerMemoryInputCamera(MediaLink *link) std::unordered_map params = { { V4L2_CID_ANALOGUE_GAIN, { delays.gainDelay, false } }, { V4L2_CID_EXPOSURE, { delays.exposureDelay, false } }, + { V4L2_CID_VBLANK, { delays.vblankDelay, true } }, }; data->delayedCtrls_ = diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 3917aa897e..968aab6740 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -569,6 +569,7 @@ SimpleCameraData::SimpleCameraData(SimplePipelineHandler *pipe, std::unordered_map params = { { V4L2_CID_ANALOGUE_GAIN, { delays.gainDelay, false } }, { V4L2_CID_EXPOSURE, { delays.exposureDelay, false } }, + { V4L2_CID_VBLANK, { delays.vblankDelay, true } }, }; delayedCtrls_ = std::make_unique(sensor_->device(), params);