From patchwork Fri Oct 24 08:50:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 24798 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 37722BE080 for ; Fri, 24 Oct 2025 08:53:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EF71960963; Fri, 24 Oct 2025 10:53:16 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="V6xCDXc7"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 069A460938 for ; Fri, 24 Oct 2025 10:53:16 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:7edc:62f4:c118:1549]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 6978A4B21; Fri, 24 Oct 2025 10:51:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761295890; bh=I0b9uqNMOZGYBj1FqNrnQcqrUz1g8S0QfRsDzYkpU/M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=V6xCDXc7MK8pTxyZ7Q5+BgPsu5Kds/CAX5iyJNCzg+wUK5QEFfZoacX92ChzD9psM hfVqR1YXEi0VJwd6ERkzPdIDkPyvR38CHyAL/6CreH9vH4IdehF+GISH0K7OB2asyy VKdLqU3XKgbwLe4tRm4cu0WP95RA6MiSniNz9HRU= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v1 32/35] WIP: rkisp1: agc: Add digital gain Date: Fri, 24 Oct 2025 10:50:56 +0200 Message-ID: <20251024085130.995967-33-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20251024085130.995967-1-stefan.klug@ideasonboard.com> References: <20251024085130.995967-1-stefan.klug@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" Add a manual only digital gain control. Signed-off-by: Stefan Klug --- src/ipa/rkisp1/algorithms/agc.cpp | 22 ++++++++++++++++++++-- src/ipa/rkisp1/ipa_context.h | 2 ++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp index 7629066b9876..71ad3a01d90c 100644 --- a/src/ipa/rkisp1/algorithms/agc.cpp +++ b/src/ipa/rkisp1/algorithms/agc.cpp @@ -158,6 +158,7 @@ int Agc::init(IPAContext &context, const YamlObject &tuningData) /* \todo Move this to the Camera class */ context.ctrlMap[&controls::AeEnable] = ControlInfo(false, true, true); context.ctrlMap[&controls::ExposureValue] = ControlInfo(-8.0f, 8.0f, 0.0f); + context.ctrlMap[&controls::DigitalGain] = ControlInfo(1.0f, 64.0f, 1.0f); context.ctrlMap.merge(controls()); return 0; @@ -179,6 +180,7 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo) context.activeState.agc.automatic.quantizationGain = 1.0; context.activeState.agc.manual.gain = context.activeState.agc.automatic.gain; context.activeState.agc.manual.exposure = context.activeState.agc.automatic.exposure; + context.activeState.agc.manual.digitalGain = 1.0; context.activeState.agc.autoExposureEnabled = !context.configuration.raw; context.activeState.agc.autoGainEnabled = !context.configuration.raw; context.activeState.agc.exposureValue = 0.0; @@ -281,6 +283,15 @@ void Agc::queueRequest(IPAContext &context, LOG(RkISP1Agc, Debug) << "Set gain to " << agc.manual.gain; } + const auto &digitalGain = controls.get(controls::DigitalGain); + if (digitalGain) { + agc.manual.digitalGain = *digitalGain; + + LOG(RkISP1Agc, Debug) << "Set digital gain to " << agc.manual.digitalGain; + } + + frameContext.agc.digitalGain = agc.manual.digitalGain; + frameContext.agc.autoExposureEnabled = agc.autoExposureEnabled; frameContext.agc.autoGainEnabled = agc.autoGainEnabled; @@ -381,7 +392,7 @@ void Agc::prepare(IPAContext &context, const uint32_t frame, if (context.configuration.compress.supported) { frameContext.compress.enable = true; - frameContext.compress.gain = frameContext.agc.quantizationGain; + frameContext.compress.gain = frameContext.agc.quantizationGain * frameContext.agc.digitalGain; } frameContext.agc.yTarget = context.activeState.agc.automatic.yTarget; @@ -469,7 +480,14 @@ void Agc::fillMetadata(IPAContext &context, IPAFrameContext &frameContext, metadata.set(controls::AeConstraintMode, frameContext.agc.constraintMode); metadata.set(controls::ExposureValue, frameContext.agc.exposureValue); - metadata.set(controls::DigitalGain, frameContext.agc.quantizationGain); + /* + * \todo Add the quantization gain to the digital gain metadata, so that + * we don't apply any hidden gains. This might however create issues + * with applications trying to match a digital gain control with the + * metadata. + */ + metadata.set(controls::DigitalGain, + frameContext.agc.quantizationGain * frameContext.agc.digitalGain); } /** diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index 185951fb8286..ba320b9e3e92 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -79,6 +79,7 @@ struct IPAActiveState { struct { uint32_t exposure; double gain; + double digitalGain; } manual; struct { uint32_t exposure; @@ -160,6 +161,7 @@ struct IPAFrameContext : public FrameContext { bool updateMetering; bool autoExposureModeChange; bool autoGainModeChange; + double digitalGain; } agc; struct {