From patchwork Fri Jul 28 13:36:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 18899 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 12B78C324E for ; Fri, 28 Jul 2023 13:37:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6FD13627F2; Fri, 28 Jul 2023 15:37:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1690551425; bh=jf0XneDQIHxvSGeB7vZhsr5MqzxjdQTmkwsv3mfzPcA=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=pOqyNjHR3kFqRXBnL544mclW749szywdFaiz/sVCY88inxAHviSwQiYTLqIlIn+jl +oQ21exYRs+H4At9t5OxoyEYKxzzSA3+pr0NM3WAbP2fn7xP7wKQ77okySaW7HkOc4 lsqxDyIYAxzB3GTmBUyNz98+fnTgQk1x9LRKdQOCl2rKt1tX5uWwy0LExOLum7hSC9 bJgRn4e39DgAAoe0gAlhHwegbHl8TFSC1FyQZxrb+RI7zfYW1EiXBYZkY80APGUETw Hx5vtOGf3HuNg4PFnKLeOZq4FFeJ4iCSKDJN3g+K2qdJefIW9kcneIdpAJU+GMGAfT 0vz8UzMWJ04FQ== Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6E3BC627E7 for ; Fri, 28 Jul 2023 15:37:03 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="kv8I9Gsq"; dkim-atps=neutral Received: by mail-wr1-x42a.google.com with SMTP id ffacd0b85a97d-31758eb5db8so2142231f8f.2 for ; Fri, 28 Jul 2023 06:37:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1690551423; x=1691156223; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Tj69fHEclvNZTLPcEmYzqTGANaDAaLoaGmsi0RnW56I=; b=kv8I9GsqZY5bN/wFieQB/fdNwdJwfuqSrLoAg8Dc5PBsFwQVCV9+QBtNCfKIbWDGSm wF920YQZDA4tRLO5TXXrkL/g1aiVFrFQrKohVqDPTKTRpfkHcdU7lXw37M4JYk5Huwx6 P1ZwyBR6DOITE/SjXPoCHMQlB/FOnufNcpj7PppEAUrXQ0ssKhK3OJLKfSXVpTRsAT2C B4XUqTL+68tvWcAx9FbeuMgEjAl5zqoVMmvFh+yqLDBSy5tNIH5q5u1NQ8JZdJEXp5/O OtKlpKlIrW00D6Gy8DLig35mR8FLaHSSvnW2Mihpj/c+QSnRzQikX0228gLHAJf3o+Mp HBPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690551423; x=1691156223; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Tj69fHEclvNZTLPcEmYzqTGANaDAaLoaGmsi0RnW56I=; b=i9Iy4vpdWDOKC25xGwJB+mFynvtvB2VqFQIUuxuodc1PRfBnu7tDCT1978Pr7zTOyS gA8DkAsz9hIXY1ZRDFOvcuowp7jwwYd5oA5xEXhk3UdWEB1ySS4BHWskUKBpnd8JOnj4 dM3rRfxgGz3O0ooXmqug4Vd/o3t2HC6MGQZAwxsR8iY8NzOW77d/r82pJ6oeC2sK6YXx 91fncZ9iM+l87RRcUJpCUu99bnsNIR2xu1P48/FeeakLkyesOqRnAfKD8d+pfP/i0DSS YwgOkulUgDEr8RbuorZOKolS1YbzcupQgcbAs5lduCLt8Im8oIFFQJ1WWNA3LksIOtuF aQdQ== X-Gm-Message-State: ABy/qLaV83DTs79WTU9bRWcUXshwgrU1KcvDiFcHza+Ehe48o/mrvN0q qBlLy/jchH8+kTf0k/z7zSjlt4umsBUfU94S+hk= X-Google-Smtp-Source: APBJJlFZ09uYyRpUzs6+kvEJxCoKTGCTaG5mdmtqtL2bmECSN//MNvhZ49fcZe9AJuGCtODnlOYEtQ== X-Received: by 2002:a5d:60cb:0:b0:313:fbd0:9813 with SMTP id x11-20020a5d60cb000000b00313fbd09813mr1560792wrt.28.1690551422903; Fri, 28 Jul 2023 06:37:02 -0700 (PDT) Received: from pi4-davidp.pitowers.org ([2a00:1098:3142:14:2bce:64d6:1a5c:49a2]) by smtp.gmail.com with ESMTPSA id i15-20020adffdcf000000b003145559a691sm4847758wrs.41.2023.07.28.06.37.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Jul 2023 06:37:02 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Fri, 28 Jul 2023 14:36:58 +0100 Message-Id: <20230728133700.3713-2-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230728133700.3713-1-david.plowman@raspberrypi.com> References: <20230728133700.3713-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/3] ipa: rpi: agc: Fetch AWB status in process method, not prepare 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: , X-Patchwork-Original-From: David Plowman via libcamera-devel From: David Plowman Reply-To: David Plowman Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" prepare() doesn't use the AWB status, so fetching it in process() is probably better. This change is preparatory to other changes, where we may find ourselves calling process() without having called prepare() previously. Signed-off-by: David Plowman Reviewed-by: Naushir Patuck Reviewed-by: Jacopo Mondi --- src/ipa/rpi/controller/rpi/agc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp index ae9ff219..e8526355 100644 --- a/src/ipa/rpi/controller/rpi/agc.cpp +++ b/src/ipa/rpi/controller/rpi/agc.cpp @@ -424,7 +424,6 @@ void Agc::prepare(Metadata *imageMetadata) totalExposureValue = delayedStatus.totalExposureValue; status_.digitalGain = 1.0; - fetchAwbStatus(imageMetadata); /* always fetch it so that Process knows it's been done */ if (status_.totalExposureValue) { /* Process has run, so we have meaningful values. */ @@ -461,6 +460,8 @@ void Agc::process(StatisticsPtr &stats, Metadata *imageMetadata) * configuration, that kind of thing. */ housekeepConfig(); + /* Fetch the AWB status immediately, so that we can assume it's there. */ + fetchAwbStatus(imageMetadata); /* Get the current exposure values for the frame that's just arrived. */ fetchCurrentExposure(imageMetadata); /* Compute the total gain we require relative to the current exposure. */ From patchwork Fri Jul 28 13:36:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 18900 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 CCEA7BDC71 for ; Fri, 28 Jul 2023 13:37:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 87D99627F5; Fri, 28 Jul 2023 15:37:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1690551427; bh=8RgkApAS1nLUlSyfKiNq5++HKh8PdG0ifshngX0bVO4=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=Aa/x+KXaeKlzB95BpDj25YuvAor9P+MxjpLcRkdJVAZB7VdZyq/YG/gXv03DUQVC3 aGffqZP9LjYmNhg/tkRMf45kYaTqohHve1pGJZXcXqrRp0cgpCbwGc1e8yMYyidAUZ r9XUHbVBk0XZ8HwuN0GIdmTSu1XCaun2/MXTGZF0HRYtfToTFYs67/5BLx30L3r90z jxmAKkvI+n+efel80g6FJsWcdMM4ySoiLn7LpWej3TdO5vpsDzeH0S9czEIL9Q60Tw dn6bXSgTQfsbdMpYXALyOggczhw+StWTU9yA4hp9Elnz68NL1sudZOVHWE7+TkJYGp 3ouB/TLTboYOA== Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [IPv6:2a00:1450:4864:20::42e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2376D627E6 for ; Fri, 28 Jul 2023 15:37:04 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="YW/VLF3m"; dkim-atps=neutral Received: by mail-wr1-x42e.google.com with SMTP id ffacd0b85a97d-3178fa77b27so384573f8f.2 for ; Fri, 28 Jul 2023 06:37:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1690551423; x=1691156223; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=cT9tTiTNC+0dc91UzzBi/jG1dsycuMB1SbT8keFJIxg=; b=YW/VLF3mop2QtRl8zu2MDGKo3G0nK9IWVGR+Uy/AdkmszD82mohAnzlfrVm2T4Il2p nz1dGENZ/IkD7XFT1x3x6+LiSgG5KIeGu7jJmFWjblvPjR36WCc05zcRkLCt6snLwCvu EWzkhYMUsAGubuTJ94BIQq/cRa76RnM1GbwA5Nx/64XPaoNTc4as0Cb6bSj+6l7mKWWa bKdqbVFKtxK7bxefdy4WaqiQpECX1PfAxpo5hMhOWeVHXPpOp+/xyGObe6GQwngPcael F+12PYXTdkD4w+N/y5jnTjD+4hPllori4IZ/aRy+0NoN173YPtjc0q5WqUM+eqrGcxAv xudw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690551423; x=1691156223; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cT9tTiTNC+0dc91UzzBi/jG1dsycuMB1SbT8keFJIxg=; b=RxO6iYKKPYqDt8xAL/xBZMG1ifsbZc0KgTQmNA6Y3SzX6Xd1zZo/F2WOlcF/j516tP Y1Ea7faVwJokKT281GLfFQLnf2XdBMBYLveBfxfz3e+0TewulYyPhVPz7rs8BzKHvLZM HIKmXAfaEOj3jYvbY7YCJGLkA0JzdZY3Lz99snhnM/INkxkj8ZxXCb0b9cD9AnOJYCdL a0B6iPwVcg6KVuiT5f8lKKJ/aXXhn4LvnkyzSwVyl/g/IiA4/na9FbyhdabB0B/Tjp7n 3VDXBEXdG94s3aTkdoYdRTuhBE1oUkFoECpPuLMcIB/521jP+Yq87anua/ZZC/JEWlZu Dsuw== X-Gm-Message-State: ABy/qLbI5i8JJ6isgA563MFTzza9xGXFz+jLT70n1V55eScb/5jmbNw9 mK4b0kK0z2lGKr2l4dLi5AJCH1WBdoHdxb5AI3E= X-Google-Smtp-Source: APBJJlHtusRF9FezqKS4+whGmqwVV4LdvWwxbeZlCySKz0FdXeNK9918e/hA7pKDo5sJ+7H4Oa0bbA== X-Received: by 2002:a5d:4d8c:0:b0:317:6ada:b614 with SMTP id b12-20020a5d4d8c000000b003176adab614mr1965241wru.30.1690551423520; Fri, 28 Jul 2023 06:37:03 -0700 (PDT) Received: from pi4-davidp.pitowers.org ([2a00:1098:3142:14:2bce:64d6:1a5c:49a2]) by smtp.gmail.com with ESMTPSA id i15-20020adffdcf000000b003145559a691sm4847758wrs.41.2023.07.28.06.37.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Jul 2023 06:37:03 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Fri, 28 Jul 2023 14:36:59 +0100 Message-Id: <20230728133700.3713-3-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230728133700.3713-1-david.plowman@raspberrypi.com> References: <20230728133700.3713-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/3] ipa: rpi: agc: Filter exposures before dealing with digital gain 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: , X-Patchwork-Original-From: David Plowman via libcamera-devel From: David Plowman Reply-To: David Plowman Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" We now time-filter the exposure before sorting out how much digital gain is required. This is actually a little more natural and simplifies the code. It also prepares us for some future work where this arrangement will be helpful. Signed-off-by: David Plowman Reviewed-by: Naushir Patuck Reviewed-by: Jacopo Mondi --- src/ipa/rpi/controller/rpi/agc.cpp | 30 +++++------------------------- src/ipa/rpi/controller/rpi/agc.h | 2 +- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp index e8526355..6087fc60 100644 --- a/src/ipa/rpi/controller/rpi/agc.cpp +++ b/src/ipa/rpi/controller/rpi/agc.cpp @@ -469,14 +469,14 @@ void Agc::process(StatisticsPtr &stats, Metadata *imageMetadata) computeGain(stats, imageMetadata, gain, targetY); /* Now compute the target (final) exposure which we think we want. */ computeTargetExposure(gain); + /* The results have to be filtered so as not to change too rapidly. */ + filterExposure(); /* * Some of the exposure has to be applied as digital gain, so work out * what that is. This function also tells us whether it's decided to * "desaturate" the image more quickly. */ bool desaturate = applyDigitalGain(gain, targetY); - /* The results have to be filtered so as not to change too rapidly. */ - filterExposure(desaturate); /* * The last thing is to divide up the exposure value into a shutter time * and analogue gain, according to the current exposure mode. @@ -757,12 +757,12 @@ bool Agc::applyDigitalGain(double gain, double targetY) if (desaturate) dg /= config_.fastReduceThreshold; LOG(RPiAgc, Debug) << "Digital gain " << dg << " desaturate? " << desaturate; - target_.totalExposureNoDG = target_.totalExposure / dg; - LOG(RPiAgc, Debug) << "Target totalExposureNoDG " << target_.totalExposureNoDG; + filtered_.totalExposureNoDG = filtered_.totalExposure / dg; + LOG(RPiAgc, Debug) << "Target totalExposureNoDG " << filtered_.totalExposureNoDG; return desaturate; } -void Agc::filterExposure(bool desaturate) +void Agc::filterExposure() { double speed = config_.speed; /* @@ -774,7 +774,6 @@ void Agc::filterExposure(bool desaturate) speed = 1.0; if (!filtered_.totalExposure) { filtered_.totalExposure = target_.totalExposure; - filtered_.totalExposureNoDG = target_.totalExposureNoDG; } else { /* * If close to the result go faster, to save making so many @@ -785,26 +784,7 @@ void Agc::filterExposure(bool desaturate) speed = sqrt(speed); filtered_.totalExposure = speed * target_.totalExposure + filtered_.totalExposure * (1.0 - speed); - /* - * When desaturing, take a big jump down in totalExposureNoDG, - * which we'll hide with digital gain. - */ - if (desaturate) - filtered_.totalExposureNoDG = - target_.totalExposureNoDG; - else - filtered_.totalExposureNoDG = - speed * target_.totalExposureNoDG + - filtered_.totalExposureNoDG * (1.0 - speed); } - /* - * We can't let the totalExposureNoDG exposure deviate too far below the - * total exposure, as there might not be enough digital gain available - * in the ISP to hide it (which will cause nasty oscillation). - */ - if (filtered_.totalExposureNoDG < - filtered_.totalExposure * config_.fastReduceThreshold) - filtered_.totalExposureNoDG = filtered_.totalExposure * config_.fastReduceThreshold; LOG(RPiAgc, Debug) << "After filtering, totalExposure " << filtered_.totalExposure << " no dg " << filtered_.totalExposureNoDG; } diff --git a/src/ipa/rpi/controller/rpi/agc.h b/src/ipa/rpi/controller/rpi/agc.h index 939f9729..b7122de3 100644 --- a/src/ipa/rpi/controller/rpi/agc.h +++ b/src/ipa/rpi/controller/rpi/agc.h @@ -93,8 +93,8 @@ private: void computeGain(StatisticsPtr &statistics, Metadata *imageMetadata, double &gain, double &targetY); void computeTargetExposure(double gain); + void filterExposure(); bool applyDigitalGain(double gain, double targetY); - void filterExposure(bool desaturate); void divideUpExposure(); void writeAndFinish(Metadata *imageMetadata, bool desaturate); libcamera::utils::Duration limitShutter(libcamera::utils::Duration shutter); From patchwork Fri Jul 28 13:37:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 18901 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 8F7C5C32AA for ; Fri, 28 Jul 2023 13:37:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 36AFA627F6; Fri, 28 Jul 2023 15:37:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1690551428; bh=qfswQo62xoNwkb8FaJzYW9d9N3UAYhmrrsRaMkii3Hc=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=Km62fjI74f88/WgMIqqKNaIfTIqRlbGJen8UY2Kx5fC4FllECtRJiT87cFfP3GGxi A9TcXU+s9p6vmtywaGG5xAS+K+PihDjJF/0+Of9Gcm4cBep+NzTS1twnqTcFvnw6yS 3jrjnV4t7sJ14KASnIB+FyQYqe1vU1U6Jc4s0tVnjvgaSjT81n7vxVo7KL1+2Q40Wj Percazi0BQTcHKYBXwcF0N4ng22Y+owPg8SRFSbVL5k/QV3lk3Or7Dt8T7YHyElTiQ 4dSoDeCPMmhKHZCGCC6+F4DcKCxSKfUzdLmST1kklnaeahGL5l25sBpLbTkkz9BKo3 jb1W4tkUHlJFQ== Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0132E627F0 for ; Fri, 28 Jul 2023 15:37:05 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="ef2YYTg4"; dkim-atps=neutral Received: by mail-wr1-x430.google.com with SMTP id ffacd0b85a97d-31771a876b5so1973766f8f.3 for ; Fri, 28 Jul 2023 06:37:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1690551424; x=1691156224; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=m9XmLKKQDUXgVbu1Hi4NS602c6ORw8D/if6U++CcbuI=; b=ef2YYTg41hVSAcvWRv2MZ+9KpLPD/lnp8bg9aNVMxcv3sItHnblPo1FcT4aeMm2jTn Xg/dvVlvlIIV8kWmgRJE1O48F2/pbEoK99puX0MJKIbKEqLshE4Xllys6pvP8iGzzBTm +zlAlG9XPeKSbU9I7TNIiFAIe+EpMiGvDmRCswGjRSSD9Z7yqZFscM43XyEEy/cswZoC oRu5AqABDbQ7jMiI2cFk3NSmT5Y9wD+FE+OX2K4gt5z9aenDStpD8whjDFRBOIkMHOuu 8I1jkdf2JeOlkbUdmryYdmQI67MEp/FJICDKC7mmhyBI/7N/ZAz60fr9dFCBXEDX+zx1 C36w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690551424; x=1691156224; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=m9XmLKKQDUXgVbu1Hi4NS602c6ORw8D/if6U++CcbuI=; b=Z3o6G46T1q8Ut/XIJUsm1rb0p1JAQc6PPTQyRPwcQuqPtlY2D2kMOCMLYk092p0n93 X1q5Zez5axMxHI+ssKab7VeWNdue2TXpyi1X0h5OqihS3Scq4ibcM9OuvHIygzGOQfeC ff0o0ztsvK/+/0EnMn8FiV2DRXuDGTDlEgQyzo6XLP5e2/2wilDNF/scFRQ2i01t/2tp C/nxIOjDk7KdOBrpARf6hAhgZsrizAGVbbzD8z+39m5DuGTyg2PY5+0k7v2a+mq3mDR0 PHEaqRCKk4FU+Zcl7le3+kQRfGgCslQjiuwHCvaS0bAvK1cI4MJiLGQpwuazmiOUJKTJ 9fzA== X-Gm-Message-State: ABy/qLZZqwoQPgG0hjgsE5US1xd5fOsep8N/F9HlYYWIS+OmCQecF01h 1zoKgLsdtlUuGMrmq7VYv85xag/neEScDH60XCs= X-Google-Smtp-Source: APBJJlEDwIh9/ebyKjrWblQ9tIcXz+ztQ9q7CH/0+m3bBNjKFrXk632bQyUQ6ZtZjtQf3KaG3Fru+g== X-Received: by 2002:a05:6000:48:b0:313:ef08:c83b with SMTP id k8-20020a056000004800b00313ef08c83bmr1751532wrx.56.1690551424308; Fri, 28 Jul 2023 06:37:04 -0700 (PDT) Received: from pi4-davidp.pitowers.org ([2a00:1098:3142:14:2bce:64d6:1a5c:49a2]) by smtp.gmail.com with ESMTPSA id i15-20020adffdcf000000b003145559a691sm4847758wrs.41.2023.07.28.06.37.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Jul 2023 06:37:03 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Fri, 28 Jul 2023 14:37:00 +0100 Message-Id: <20230728133700.3713-4-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230728133700.3713-1-david.plowman@raspberrypi.com> References: <20230728133700.3713-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/3] ipa: rpi: agc: Split AgcStatus into AgcStatus and AgcPrepareStatus 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: , X-Patchwork-Original-From: David Plowman via libcamera-devel From: David Plowman Reply-To: David Plowman Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The Agc::process() function returns an AgcStatus object in the metadata as before, but Agc::prepare() is changed to return the values it computes in a separate AgcPrepareStatus object (under the new tag "agc.prepare_status"). The "digitalGain" and "locked" fields are moved from AgcStatus to AgcPrepareStatus. This will be useful going forward as we can be more flexible about the order in which prepare() and process() are called, without them trampling on each other's results. Signed-off-by: David Plowman Reviewed-by: Naushir Patuck Reviewed-by: Jacopo Mondi --- src/ipa/rpi/common/ipa_base.cpp | 8 ++++---- src/ipa/rpi/controller/agc_status.h | 9 +++++++-- src/ipa/rpi/controller/rpi/agc.cpp | 20 +++++++++++--------- src/ipa/rpi/controller/rpi/agc.h | 2 +- src/ipa/rpi/vc4/vc4.cpp | 6 +++--- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp index f40f2e71..6ae84cc6 100644 --- a/src/ipa/rpi/common/ipa_base.cpp +++ b/src/ipa/rpi/common/ipa_base.cpp @@ -1151,10 +1151,10 @@ void IpaBase::reportMetadata(unsigned int ipaContext) libcameraMetadata_.set(controls::LensPosition, *deviceStatus->lensPosition); } - AgcStatus *agcStatus = rpiMetadata.getLocked("agc.status"); - if (agcStatus) { - libcameraMetadata_.set(controls::AeLocked, agcStatus->locked); - libcameraMetadata_.set(controls::DigitalGain, agcStatus->digitalGain); + AgcPrepareStatus *agcPrepareStatus = rpiMetadata.getLocked("agc.prepare_status"); + if (agcPrepareStatus) { + libcameraMetadata_.set(controls::AeLocked, agcPrepareStatus->locked); + libcameraMetadata_.set(controls::DigitalGain, agcPrepareStatus->digitalGain); } LuxStatus *luxStatus = rpiMetadata.getLocked("lux.status"); diff --git a/src/ipa/rpi/controller/agc_status.h b/src/ipa/rpi/controller/agc_status.h index 6c112e76..597eddd7 100644 --- a/src/ipa/rpi/controller/agc_status.h +++ b/src/ipa/rpi/controller/agc_status.h @@ -11,8 +11,10 @@ #include /* - * The AGC algorithm should post the following structure into the image's - * "agc.status" metadata. + * The AGC algorithm process method should post an AgcStatus into the image + * metadata under the tag "agc.status". + * The AGC algorithm prepare method should post an AgcPrepareStatus instead + * under "agc.prepare_status". */ /* @@ -34,6 +36,9 @@ struct AgcStatus { int floatingRegionEnable; libcamera::utils::Duration fixedShutter; double fixedAnalogueGain; +}; + +struct AgcPrepareStatus { double digitalGain; int locked; }; diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp index 6087fc60..7b02972a 100644 --- a/src/ipa/rpi/controller/rpi/agc.cpp +++ b/src/ipa/rpi/controller/rpi/agc.cpp @@ -419,11 +419,13 @@ void Agc::prepare(Metadata *imageMetadata) { Duration totalExposureValue = status_.totalExposureValue; AgcStatus delayedStatus; + AgcPrepareStatus prepareStatus; if (!imageMetadata->get("agc.delayed_status", delayedStatus)) totalExposureValue = delayedStatus.totalExposureValue; - status_.digitalGain = 1.0; + prepareStatus.digitalGain = 1.0; + prepareStatus.locked = false; if (status_.totalExposureValue) { /* Process has run, so we have meaningful values. */ @@ -432,23 +434,23 @@ void Agc::prepare(Metadata *imageMetadata) Duration actualExposure = deviceStatus.shutterSpeed * deviceStatus.analogueGain; if (actualExposure) { - status_.digitalGain = totalExposureValue / actualExposure; + double digitalGain = totalExposureValue / actualExposure; LOG(RPiAgc, Debug) << "Want total exposure " << totalExposureValue; /* * Never ask for a gain < 1.0, and also impose * some upper limit. Make it customisable? */ - status_.digitalGain = std::max(1.0, std::min(status_.digitalGain, 4.0)); + prepareStatus.digitalGain = std::max(1.0, std::min(digitalGain, 4.0)); LOG(RPiAgc, Debug) << "Actual exposure " << actualExposure; - LOG(RPiAgc, Debug) << "Use digitalGain " << status_.digitalGain; + LOG(RPiAgc, Debug) << "Use digitalGain " << prepareStatus.digitalGain; LOG(RPiAgc, Debug) << "Effective exposure " - << actualExposure * status_.digitalGain; + << actualExposure * prepareStatus.digitalGain; /* Decide whether AEC/AGC has converged. */ - updateLockStatus(deviceStatus); + prepareStatus.locked = updateLockStatus(deviceStatus); } } else LOG(RPiAgc, Warning) << name() << ": no device metadata"; - imageMetadata->set("agc.status", status_); + imageMetadata->set("agc.prepare_status", prepareStatus); } } @@ -486,7 +488,7 @@ void Agc::process(StatisticsPtr &stats, Metadata *imageMetadata) writeAndFinish(imageMetadata, desaturate); } -void Agc::updateLockStatus(DeviceStatus const &deviceStatus) +bool Agc::updateLockStatus(DeviceStatus const &deviceStatus) { const double errorFactor = 0.10; /* make these customisable? */ const int maxLockCount = 5; @@ -522,7 +524,7 @@ void Agc::updateLockStatus(DeviceStatus const &deviceStatus) lastTargetExposure_ = status_.targetExposureValue; LOG(RPiAgc, Debug) << "Lock count updated to " << lockCount_; - status_.locked = lockCount_ == maxLockCount; + return lockCount_ == maxLockCount; } void Agc::housekeepConfig() diff --git a/src/ipa/rpi/controller/rpi/agc.h b/src/ipa/rpi/controller/rpi/agc.h index b7122de3..aaf77c8f 100644 --- a/src/ipa/rpi/controller/rpi/agc.h +++ b/src/ipa/rpi/controller/rpi/agc.h @@ -85,7 +85,7 @@ public: void process(StatisticsPtr &stats, Metadata *imageMetadata) override; private: - void updateLockStatus(DeviceStatus const &deviceStatus); + bool updateLockStatus(DeviceStatus const &deviceStatus); AgcConfig config_; void housekeepConfig(); void fetchCurrentExposure(Metadata *imageMetadata); diff --git a/src/ipa/rpi/vc4/vc4.cpp b/src/ipa/rpi/vc4/vc4.cpp index 3eea40a6..1de0d3cc 100644 --- a/src/ipa/rpi/vc4/vc4.cpp +++ b/src/ipa/rpi/vc4/vc4.cpp @@ -60,7 +60,7 @@ private: bool validateIspControls(); void applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls); - void applyDG(const struct AgcStatus *dgStatus, ControlList &ctrls); + void applyDG(const struct AgcPrepareStatus *dgStatus, ControlList &ctrls); void applyCCM(const struct CcmStatus *ccmStatus, ControlList &ctrls); void applyBlackLevel(const struct BlackLevelStatus *blackLevelStatus, ControlList &ctrls); void applyGamma(const struct ContrastStatus *contrastStatus, ControlList &ctrls); @@ -142,7 +142,7 @@ void IpaVc4::platformPrepareIsp([[maybe_unused]] const PrepareParams ¶ms, if (ccmStatus) applyCCM(ccmStatus, ctrls); - AgcStatus *dgStatus = rpiMetadata.getLocked("agc.status"); + AgcPrepareStatus *dgStatus = rpiMetadata.getLocked("agc.prepare_status"); if (dgStatus) applyDG(dgStatus, ctrls); @@ -284,7 +284,7 @@ void IpaVc4::applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls) static_cast(awbStatus->gainB * 1000)); } -void IpaVc4::applyDG(const struct AgcStatus *dgStatus, ControlList &ctrls) +void IpaVc4::applyDG(const struct AgcPrepareStatus *dgStatus, ControlList &ctrls) { ctrls.set(V4L2_CID_DIGITAL_GAIN, static_cast(dgStatus->digitalGain * 1000));