From patchwork Mon Oct 14 15:47:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 21621 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 8D6F4C32F4 for ; Mon, 14 Oct 2024 15:47:57 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 425FF6537E; Mon, 14 Oct 2024 17:47:55 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="BJEdn5HW"; 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 94D1465369 for ; Mon, 14 Oct 2024 17:47:51 +0200 (CEST) Received: from Monstersaurus.lgs-net.com (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7EDFB96C; Mon, 14 Oct 2024 17:46:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1728920770; bh=l7aBtW6B8/jw4kmSGSQUraVQF3wy1M4OCs95YqoDPH8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BJEdn5HWjCEoS32sheKb0pnBBjUtK2sey12M1gLWRmdz+xf4mJqX3eKeB00mCYra0 g22C93vGlk3CM5aR7HPgwxOs2IlFzEoip/OnTVfuYpzxwT+26H9T5sIDMDLNII/gII sOW1ucqQ6OjxrEkrtZ+4PzPsaf/7E2Xp+L2AzOkQ= From: Kieran Bingham To: libcamera devel Cc: Kieran Bingham Subject: [PATCH 1/3] ipa: rkisp1: Initialise AGC from FrameDurationLimits controls Date: Mon, 14 Oct 2024 16:47:45 +0100 Message-Id: <20241014154747.2295253-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241014154747.2295253-1-kieran.bingham@ideasonboard.com> References: <20241014154747.2295253-1-kieran.bingham@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 IPA calculates and reports the FrameDurationLimits to applications by configuring the ControlInfo accordingly during IPARkISP1::updateControls() We later need to know these limits during Agc::configure() for initialising the ActiveState of the AGC implementation with the limits. Store the FrameDurationLimits ControlInfo in the ControlInfoMap which is now present in the IPAContext so that it is commonly available for the AGC algorithm, removing the 'todo' accordingly. Signed-off-by: Kieran Bingham Reviewed-by: Umang Jain Reviewed-by: Daniel Scally Reviewed-by: Jacopo Mondi Reviewed-by: Paul Elder --- src/ipa/rkisp1/algorithms/agc.cpp | 9 +++------ src/ipa/rkisp1/rkisp1.cpp | 5 ++--- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp index 17d074d9c03e..33f902862c4a 100644 --- a/src/ipa/rkisp1/algorithms/agc.cpp +++ b/src/ipa/rkisp1/algorithms/agc.cpp @@ -178,12 +178,9 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo) context.activeState.agc.meteringMode = static_cast(meteringModes_.begin()->first); - /* - * \todo This should probably come from FrameDurationLimits instead, - * except it's computed in the IPA and not here so we'd have to - * recompute it. - */ - context.activeState.agc.maxFrameDuration = context.configuration.sensor.maxShutterSpeed; + /* Limit the frame duration to match current initialisation */ + ControlInfo &frameDurationLimits = context.ctrlMap[&controls::FrameDurationLimits]; + context.activeState.agc.maxFrameDuration = std::chrono::microseconds(frameDurationLimits.max().get()); /* * Define the measurement window for AGC as a centered rectangle diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 9e161cabdea4..47777ece783f 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -432,9 +432,8 @@ void IPARkISP1::updateControls(const IPACameraSensorInfo &sensorInfo, frameDurations[i] = frameSize / (sensorInfo.pixelRate / 1000000U); } - ctrlMap[&controls::FrameDurationLimits] = ControlInfo(frameDurations[0], - frameDurations[1], - frameDurations[2]); + context_.ctrlMap[&controls::FrameDurationLimits] = + ControlInfo(frameDurations[0], frameDurations[1], frameDurations[2]); ctrlMap.insert(context_.ctrlMap.begin(), context_.ctrlMap.end()); *ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls); From patchwork Mon Oct 14 15:47:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 21622 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 B61A1C32F8 for ; Mon, 14 Oct 2024 15:47:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 223946537F; Mon, 14 Oct 2024 17:47:56 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="dsan8NkE"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AB9986537C for ; Mon, 14 Oct 2024 17:47:51 +0200 (CEST) Received: from Monstersaurus.lgs-net.com (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B521C1A7D; Mon, 14 Oct 2024 17:46:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1728920770; bh=vRUR7g/TSz4JQ2oCCbcODkPCd4KnGcL78O40biOmxdI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dsan8NkErtUzixJtJ+wNrS4WfLLu+KFYWjJQAdYbnV71yHHSOXO/Sh2w2mNkJ4n+/ 1diuvcueBme5Z8tR+AtYS9Ml3g+KYIeBCqnBpEVSEL+CJh8UhyFbkSGuXVWdw3uh5r FlwS5L9RaRhnWYIRfe1bU4T4GQgMb91MS7KcgO28= From: Kieran Bingham To: libcamera devel Cc: Kieran Bingham Subject: [PATCH 2/3] ipa: rkisp1: Alias lineDuration Date: Mon, 14 Oct 2024 16:47:46 +0100 Message-Id: <20241014154747.2295253-3-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241014154747.2295253-1-kieran.bingham@ideasonboard.com> References: <20241014154747.2295253-1-kieran.bingham@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 configured line duration of the sensor is used frequently throughout the AGC implementation. It's available in the IPA context through the rather long: context.configuration.sensor.lineDuration Take a copy of the lineDuration early in the call and replace the two current usages of the reference with the shorter copy to manage line length and ease readibility. Signed-off-by: Kieran Bingham Reviewed-by: Umang Jain Reviewed-by: Daniel Scally Reviewed-by: Laurent Pinchart Reviewed-by: Paul Elder --- src/ipa/rkisp1/algorithms/agc.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp index 33f902862c4a..e23ab120b3e2 100644 --- a/src/ipa/rkisp1/algorithms/agc.cpp +++ b/src/ipa/rkisp1/algorithms/agc.cpp @@ -400,6 +400,8 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame, return; } + utils::Duration lineDuration = context.configuration.sensor.lineDuration; + /* * \todo Verify that the exposure and gain applied by the sensor for * this frame match what has been requested. This isn't a hard @@ -429,8 +431,7 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame, * The Agc algorithm needs to know the effective exposure value that was * applied to the sensor when the statistics were collected. */ - utils::Duration exposureTime = context.configuration.sensor.lineDuration - * frameContext.sensor.exposure; + utils::Duration exposureTime = lineDuration * frameContext.sensor.exposure; double analogueGain = frameContext.sensor.gain; utils::Duration effectiveExposureValue = exposureTime * analogueGain; @@ -447,7 +448,7 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame, IPAActiveState &activeState = context.activeState; /* Update the estimated exposure and gain. */ - activeState.agc.automatic.exposure = shutterTime / context.configuration.sensor.lineDuration; + activeState.agc.automatic.exposure = shutterTime / lineDuration; activeState.agc.automatic.gain = aGain; fillMetadata(context, frameContext, metadata); From patchwork Mon Oct 14 15:47:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 21623 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 81FE3C32F4 for ; Mon, 14 Oct 2024 15:47:59 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A663D6537C; Mon, 14 Oct 2024 17:47:56 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="OgGPz9xY"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DE4646537E for ; Mon, 14 Oct 2024 17:47:51 +0200 (CEST) Received: from Monstersaurus.lgs-net.com (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id EB3FA1BAE; Mon, 14 Oct 2024 17:46:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1728920771; bh=drBSXRzmjMPrQnNbI+yZGFBPw6McSxyxZ7MizNbASiE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OgGPz9xYbMRDM2Uv71/nnVGgzwbRTN9JexRt26qSJsYgidCRa2R6P2SvZiwWJxH3j 4y/HkNwnnoZ+DLykTosZ/3yq++ZSM/03bVXqFB2O5VOqknUQpW1vWFA61hc9HLCDTM DcesLL/iUot2FGfYiw06gsq4eVjT/av7Rp+t9vCI= From: Kieran Bingham To: libcamera devel Cc: Paul Elder , Kieran Bingham Subject: [PATCH 3/3] rkisp1: Honor the FrameDurationLimits control Date: Mon, 14 Oct 2024 16:47:47 +0100 Message-Id: <20241014154747.2295253-4-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241014154747.2295253-1-kieran.bingham@ideasonboard.com> References: <20241014154747.2295253-1-kieran.bingham@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" From: Paul Elder Add support to rkisp1 for controlling the framerate via the FrameDurationLimits control. Signed-off-by: Paul Elder Signed-off-by: Kieran Bingham Reviewed-by: Umang Jain --- src/ipa/rkisp1/algorithms/agc.cpp | 52 ++++++++++++++++++------ src/ipa/rkisp1/ipa_context.cpp | 16 +++++++- src/ipa/rkisp1/ipa_context.h | 4 ++ src/ipa/rkisp1/rkisp1.cpp | 2 + src/libcamera/pipeline/rkisp1/rkisp1.cpp | 7 ++++ 5 files changed, 68 insertions(+), 13 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp index e23ab120b3e2..088ecf42c480 100644 --- a/src/ipa/rkisp1/algorithms/agc.cpp +++ b/src/ipa/rkisp1/algorithms/agc.cpp @@ -180,6 +180,7 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo) /* Limit the frame duration to match current initialisation */ ControlInfo &frameDurationLimits = context.ctrlMap[&controls::FrameDurationLimits]; + context.activeState.agc.minFrameDuration = std::chrono::microseconds(frameDurationLimits.min().get()); context.activeState.agc.maxFrameDuration = std::chrono::microseconds(frameDurationLimits.max().get()); /* @@ -267,10 +268,21 @@ void Agc::queueRequest(IPAContext &context, const auto &frameDurationLimits = controls.get(controls::FrameDurationLimits); if (frameDurationLimits) { - utils::Duration maxFrameDuration = - std::chrono::milliseconds((*frameDurationLimits).back()); - agc.maxFrameDuration = maxFrameDuration; + /* Limit the control value to the limits in ControlInfo */ + ControlInfo &limits = context.ctrlMap[&controls::FrameDurationLimits]; + int64_t minFrameDuration = + std::clamp((*frameDurationLimits).front(), + limits.min().get(), + limits.max().get()); + int64_t maxFrameDuration = + std::clamp((*frameDurationLimits).back(), + limits.min().get(), + limits.max().get()); + + agc.minFrameDuration = std::chrono::microseconds(minFrameDuration); + agc.maxFrameDuration = std::chrono::microseconds(maxFrameDuration); } + frameContext.agc.minFrameDuration = agc.minFrameDuration; frameContext.agc.maxFrameDuration = agc.maxFrameDuration; } @@ -330,15 +342,8 @@ void Agc::fillMetadata(IPAContext &context, IPAFrameContext &frameContext, * frameContext.sensor.exposure; metadata.set(controls::AnalogueGain, frameContext.sensor.gain); metadata.set(controls::ExposureTime, exposureTime.get()); + metadata.set(controls::FrameDuration, frameContext.agc.frameDuration.get()); metadata.set(controls::AeEnable, frameContext.agc.autoEnabled); - - /* \todo Use VBlank value calculated from each frame exposure. */ - uint32_t vTotal = context.configuration.sensor.size.height - + context.configuration.sensor.defVBlank; - utils::Duration frameDuration = context.configuration.sensor.lineDuration - * vTotal; - metadata.set(controls::FrameDuration, frameDuration.get()); - metadata.set(controls::AeMeteringMode, frameContext.agc.meteringMode); metadata.set(controls::AeExposureMode, frameContext.agc.exposureMode); metadata.set(controls::AeConstraintMode, frameContext.agc.constraintMode); @@ -400,6 +405,7 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame, return; } + IPACameraSensorInfo &sensorInfo = context.sensorInfo; utils::Duration lineDuration = context.configuration.sensor.lineDuration; /* @@ -418,11 +424,19 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame, [](uint32_t x) { return x >> 4; }); expMeans_ = { params->ae.exp_mean, context.hw->numAeCells }; + /* + * Limit the allowed shutter speeds for the exposure helper based on + * the frame duration limits. + */ + utils::Duration minShutterSpeed = + std::clamp(frameContext.agc.minFrameDuration, + context.configuration.sensor.minShutterSpeed, + context.configuration.sensor.maxShutterSpeed); utils::Duration maxShutterSpeed = std::clamp(frameContext.agc.maxFrameDuration, context.configuration.sensor.minShutterSpeed, context.configuration.sensor.maxShutterSpeed); - setLimits(context.configuration.sensor.minShutterSpeed, + setLimits(minShutterSpeed, maxShutterSpeed, context.configuration.sensor.minAnalogueGain, context.configuration.sensor.maxAnalogueGain); @@ -451,6 +465,20 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame, activeState.agc.automatic.exposure = shutterTime / lineDuration; activeState.agc.automatic.gain = aGain; + /* + * Determine what our FrameDuration must be and adapt VBLANK to suit + * this if we need to expand the shutter time calculated to fill the + * remaining time so that we do not run faster than the minimum frame + * duration (maximum requested frame rate) when we have short exposures. + */ + utils::Duration frameDuration = std::max(frameContext.agc.minFrameDuration, + shutterTime); + + frameContext.agc.vblank = (frameDuration / lineDuration) - sensorInfo.outputSize.height; + + /* Update accounting for line length quantization. */ + frameContext.agc.frameDuration = (sensorInfo.outputSize.height + frameContext.agc.vblank) * lineDuration; + fillMetadata(context, frameContext, metadata); expMeans_ = {}; } diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp index 14d0c02a2b32..c5eb0d64ec29 100644 --- a/src/ipa/rkisp1/ipa_context.cpp +++ b/src/ipa/rkisp1/ipa_context.cpp @@ -177,6 +177,9 @@ namespace libcamera::ipa::rkisp1 { * \var IPAActiveState::agc.meteringMode * \brief Metering mode as set by the AeMeteringMode control * + * \var IPAActiveState::agc.minFrameDuration + * \brief Minimum frame duration as set by the FrameDurationLimits control + * * \var IPAActiveState::agc.maxFrameDuration * \brief Maximum frame duration as set by the FrameDurationLimits control */ @@ -297,7 +300,9 @@ namespace libcamera::ipa::rkisp1 { * \brief Automatic Gain Control parameters for this frame * * The exposure and gain are provided by the AGC algorithm, and are to be - * applied to the sensor in order to take effect for this frame. + * applied to the sensor in order to take effect for this frame. Additionally + * the vertical blanking period is determined to maintain a consistent frame + * rate matched to the FrameDurationLimits as set by the user. * * \var IPAFrameContext::agc.exposure * \brief Exposure time expressed as a number of lines computed by the algorithm @@ -307,6 +312,9 @@ namespace libcamera::ipa::rkisp1 { * * The gain should be adapted to the sensor specific gain code before applying. * + * \var IPAFrameContext::agc.vblank + * \brief Vertical blanking parameter computed by the algorithm + * * \var IPAFrameContext::agc.autoEnabled * \brief Manual/automatic AGC state as set by the AeEnable control * @@ -319,9 +327,15 @@ namespace libcamera::ipa::rkisp1 { * \var IPAFrameContext::agc.meteringMode * \brief Metering mode as set by the AeMeteringMode control * + * \var IPAFrameContext::agc.minFrameDuration + * \brief Minimum frame duration as set by the FrameDurationLimits control + * * \var IPAFrameContext::agc.maxFrameDuration * \brief Maximum frame duration as set by the FrameDurationLimits control * + * \var IPAFrameContext::agc.frameDuration + * \brief The actual FrameDuration used by the algorithm for the frame + * * \var IPAFrameContext::agc.updateMetering * \brief Indicate if new ISP AGC metering parameters need to be applied */ diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index e274d9b01e1c..60c4d647f1ef 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -79,6 +79,7 @@ struct IPAActiveState { controls::AeConstraintModeEnum constraintMode; controls::AeExposureModeEnum exposureMode; controls::AeMeteringModeEnum meteringMode; + utils::Duration minFrameDuration; utils::Duration maxFrameDuration; } agc; @@ -128,11 +129,14 @@ struct IPAFrameContext : public FrameContext { struct { uint32_t exposure; double gain; + uint32_t vblank; bool autoEnabled; controls::AeConstraintModeEnum constraintMode; controls::AeExposureModeEnum exposureMode; controls::AeMeteringModeEnum meteringMode; + utils::Duration minFrameDuration; utils::Duration maxFrameDuration; + utils::Duration frameDuration; bool updateMetering; } agc; diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 47777ece783f..17d56fb4e901 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -449,10 +449,12 @@ void IPARkISP1::setControls(unsigned int frame) IPAFrameContext &frameContext = context_.frameContexts.get(frame); uint32_t exposure = frameContext.agc.exposure; uint32_t gain = context_.camHelper->gainCode(frameContext.agc.gain); + uint32_t vblank = frameContext.agc.vblank; ControlList ctrls(sensorControls_); ctrls.set(V4L2_CID_EXPOSURE, static_cast(exposure)); ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast(gain)); + ctrls.set(V4L2_CID_VBLANK, static_cast(vblank)); setSensorControls.emit(frame, ctrls); } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 42961c120036..1ec12185bb78 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -394,6 +394,12 @@ void RkISP1CameraData::paramFilled(unsigned int frame, unsigned int bytesused) void RkISP1CameraData::setSensorControls([[maybe_unused]] unsigned int frame, const ControlList &sensorControls) { + if (frame == 0) { + ControlList controls = sensorControls; + sensor_->setControls(&controls); + return; + } + delayedCtrls_->push(sensorControls); } @@ -1138,6 +1144,7 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) std::unordered_map params = { { V4L2_CID_ANALOGUE_GAIN, { 1, false } }, { V4L2_CID_EXPOSURE, { 2, false } }, + { V4L2_CID_VBLANK, { 1, false } }, }; data->delayedCtrls_ =