From patchwork Mon Mar 27 09:34:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 18465 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 EC98AC326C for ; Mon, 27 Mar 2023 09:34:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DC51E6273D; Mon, 27 Mar 2023 11:34:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1679909685; bh=O145NJ/eDREy69ovZASc8+j6VP/8f0yzLsVuI+LQYX0=; 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=mn1vPY9sVW3l8bD0BuJRF7EENjH58fjWKF3y+ZPwcMAjL1SGZPz1bKEAxQ2Nl2xCy NOlbY9Y2aTrBi0hgInDU6RGV9wYb7O7XearFfyf5zHUaZxC5IFTfqVRe/yZopOT4Ms aRb/JJNkxW3gLux1oDHXBS2QXRi4pCRWnBxqvLfpRqmayYKSWOBj3VNR/1Vqe30FQ/ FTD/OYyyO2RHMdSwtVmR3L1GWhJCpZbDrMF7uIcB7QBMMNRbLM1v3szocKcaHsgfVq 7CubsIeS7Z5swaRUuwBan7ZMVL3ThqZTpsAKvH0vfH4vBTi97PnCKJUFfNZnvwXt+l ogtnFmVdnByYQ== Received: from mail-io1-xd30.google.com (mail-io1-xd30.google.com [IPv6:2607:f8b0:4864:20::d30]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 89662626DB for ; Mon, 27 Mar 2023 11:34:43 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="TdSkYR14"; dkim-atps=neutral Received: by mail-io1-xd30.google.com with SMTP id e13so3630220ioc.0 for ; Mon, 27 Mar 2023 02:34:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1679909682; 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=57Xo0a5+A05ZYv9p8DpBaQMTnNKtoIQ1uVFpyH98Sv0=; b=TdSkYR14iTLtbvRtPlf1lrBuXkzgWmLRo78+3YQBHDB0CBG3NI5tYYYSnauSK7yEPp l+VDoTbDj8l3SwhskvUe/RhDitd5iFz0ADEgJQUInxUdxlLMJnXygZdV09cUrzI3PM86 IfbD1V/PCz7bYNC3MT+Hx4Fftrpa/VMt8/zgFzJQAsmCEEaxIqySWc2CINUwHnbn0P9N bBkHTRbn8/9fTiJBodrAQfa9Wg6IlaHoKx00lXEXQVa2y1f83WzouNmXG9qJVTZTvS0l zo6geBZzXpwQqG9oO3u+iwkWQ2knfJCc4/gaLhcmg+lLj8HVsUAoRasDDVDjkdL47nI+ T9XA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679909682; 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=57Xo0a5+A05ZYv9p8DpBaQMTnNKtoIQ1uVFpyH98Sv0=; b=4/TqsrNVS2xpPHdb2vW7coUL7ckd0cqExHRLcVJccgeg93fvy6WN11WYI8msIZNBgT /oyiRFlYEh6GvMCxcYr/WGuRQahGoA1KSoqSUVShKCSRwQQBPwvOM/cE4mhrSC/nIJRd 6dsOIpG64YlEqtdXTYdp9qI5bulB//zSklWU7C6vGnPZ4f3GOphCO0JY4zuNRxb3W4u0 oL+l/UsUKh36eDK/A07Sci9qC9AnRhHX2Gh7jAgZOKsY4axSzJvGzqEpLWzkIK5DIuZ0 yOh8ePTyUQx6eNM9cO3kOxAMPNDF8YJwnuFYB3N8AxEyxlKY5xzsNPLcq0Oj69bnn1AQ 1sSg== X-Gm-Message-State: AAQBX9f7zuShPhBJocSTl00IMPj+jdmosP5RnRo1ldSk2mMVMDRfgDbV ibE1OfxpJjk+stI5fdgit2Zn8n8XwMqjQBKWzeIBew== X-Google-Smtp-Source: AKy350ZK8QsuRYm3dXschrbqabF5qt9Ee+lg7yc5ghLTx7mR7ZRVpN+NZ0KxoACyiCldQSL1d1xHEw== X-Received: by 2002:a6b:da05:0:b0:759:a25a:c755 with SMTP id x5-20020a6bda05000000b00759a25ac755mr5086148iob.1.1679909682260; Mon, 27 Mar 2023 02:34:42 -0700 (PDT) Received: from localhost.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id d12-20020a056602328c00b0075464a69c10sm7658345ioz.10.2023.03.27.02.34.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Mar 2023 02:34:42 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Mar 2023 10:34:36 +0100 Message-Id: <20230327093439.24670-2-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230327093439.24670-1-naush@raspberrypi.com> References: <20230327093439.24670-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 1/4] ipa: raspberrypi: Add sensor mode limits to CameraMode 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: Naushir Patuck via libcamera-devel From: Naushir Patuck Reply-To: Naushir Patuck Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add fields in the CameraMode structure to capture the mode specific limits for analogue gain and shutter speed. For convenience, also add fields for minimum and maximum frame durations. Populate these new fields when setting up the CameraMode structure. Signed-off-by: Naushir Patuck Reviewed-by: David Plowman Reviewed-by: Jacopo Mondi --- src/ipa/raspberrypi/controller/camera_mode.h | 10 +++++++++- src/ipa/raspberrypi/raspberrypi.cpp | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/ipa/raspberrypi/controller/camera_mode.h b/src/ipa/raspberrypi/controller/camera_mode.h index 94c51ddf1686..63b1177852d0 100644 --- a/src/ipa/raspberrypi/controller/camera_mode.h +++ b/src/ipa/raspberrypi/controller/camera_mode.h @@ -36,9 +36,11 @@ struct CameraMode { double scaleY; /* scaling of the noise compared to the native sensor mode */ double noiseFactor; - /* minimum and maximum line time */ + /* minimum and maximum line time and frame durations */ libcamera::utils::Duration minLineLength; libcamera::utils::Duration maxLineLength; + libcamera::utils::Duration minFrameDuration; + libcamera::utils::Duration maxFrameDuration; /* any camera transform *not* reflected already in the camera tuning */ libcamera::Transform transform; /* minimum and maximum frame lengths in units of lines */ @@ -48,4 +50,10 @@ struct CameraMode { double sensitivity; /* pixel clock rate */ uint64_t pixelRate; + /* Mode specific shutter speed limits */ + libcamera::utils::Duration minShutter; + libcamera::utils::Duration maxShutter; + /* Mode specific analogue gain limits */ + double minAnalogueGain; + double maxAnalogueGain; }; diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 1375795568e2..3f1afb846420 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -407,11 +407,27 @@ void IPARPi::setMode(const IPACameraSensorInfo &sensorInfo) mode_.minFrameLength = sensorInfo.minFrameLength; mode_.maxFrameLength = sensorInfo.maxFrameLength; + /* Store these for convenience. */ + mode_.minFrameDuration = mode_.minFrameLength * mode_.minLineLength; + mode_.maxFrameDuration = mode_.maxFrameLength * mode_.maxLineLength; + /* * Some sensors may have different sensitivities in different modes; * the CamHelper will know the correct value. */ mode_.sensitivity = helper_->getModeSensitivity(mode_); + + const ControlInfo &gainCtrl = sensorCtrls_.at(V4L2_CID_ANALOGUE_GAIN); + const ControlInfo &shutterCtrl = sensorCtrls_.at(V4L2_CID_EXPOSURE); + + mode_.minAnalogueGain = helper_->gain(gainCtrl.min().get()); + mode_.maxAnalogueGain = helper_->gain(gainCtrl.max().get()); + + /* Shutter speed is calculated based on the limits of the frame durations. */ + mode_.minShutter = helper_->exposure(shutterCtrl.min().get(), mode_.minLineLength); + mode_.maxShutter = Duration::max(); + helper_->getBlanking(mode_.maxShutter, + mode_.minFrameDuration, mode_.maxFrameDuration); } int IPARPi::configure(const IPACameraSensorInfo &sensorInfo, const IPAConfig &ipaConfig, From patchwork Mon Mar 27 09:34:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 18466 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 EC0F9C329C for ; Mon, 27 Mar 2023 09:34:47 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 467D462747; Mon, 27 Mar 2023 11:34:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1679909687; bh=JVdfbSnT6OCQKMajmp+DwoRSSQ66yxco/CpyDTl3f1U=; 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=QNtOy+oCB13c8ePw6MtmJyYLn59JaE3b4XJ63bTxggU/QIBSB3oJBnKsGXLe+bC4u dUe4q9/mVf30esZ/9m99udNjBu6OAKhFSHtfkg318wu83YWAwcH7CNv9ngFgnSuGKZ XhrVUZS7F18k6x1IcZSvjdc3z62UzfkLrgWz0exeolX35Ohl3IE1oUFvgul86dj07F T0PzANBpdQej7NCsskYu3/ut4l1xpbIZK2epXrY3MmBMkMNP561cXWlNVS2/nfk9KV 7V9rnrMiC8WRfuBz1v/hQlZD6NtbaYeAeSkvij6V8wVuG+kFrVLp5xLQ3cIDzZDkoJ dwXs5IGA+F9yg== Received: from mail-io1-xd29.google.com (mail-io1-xd29.google.com [IPv6:2607:f8b0:4864:20::d29]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A9FF26271E for ; Mon, 27 Mar 2023 11:34:44 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="IPuUjmRo"; dkim-atps=neutral Received: by mail-io1-xd29.google.com with SMTP id z1so3596778iot.11 for ; Mon, 27 Mar 2023 02:34:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1679909683; 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=m0q0eJhd3Kapv18ykdi9paPfoedIk4GLldhtnmYKlLw=; b=IPuUjmRoiPK11b780NesBgK1nNJ62RWuJse1+FgJDTpcTw49tiw3Kd3SZYc2ocFu81 aEQ16y242OeVACxsOVaO6zon6mt/ogvlAzeCZuo6xjpHRxNSH7fToVCxzflk864gpT9I G3pTPzKtWR3d2oFUnYJNXd/70Gss9x/LisWf5KRgtExZuSe+it4OEvvqPzjlPHky1Mpi 9//3EFpPjKzps9gZATxVET8Cs8kiTR1gagrpp3GlWRsrVIxry7SIhKGyfCq3T0WmziyC ZwFcXEY01rPunlBbQioyD+RI6bTNvAsLBMrVmSMEfX0Q/LkZByf4l0/1HUrLF4yJz7cW uTaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679909683; 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=m0q0eJhd3Kapv18ykdi9paPfoedIk4GLldhtnmYKlLw=; b=5XSrJ43s0HuTJhOGQ8d8Ijpg8U5ca12L2RkIr61jBoYV3K+J5YMVkkCPYPLtoURVgm 1GhVOnX8Zw9itinC5WE8nDhBG8v2wDl2Ha6TApZGHhQAWO8skiyWa7RR9BkNbMalFjG+ fUzAX/BPkPdHBM99ImB4E4k6jNwm1krSbslCvphGLENHQOSFM6zcc17T2bcpnnlp8PfC sMnrzVVTk8Arl4jrbHG0e9PIflRxdxv1V5wwmQXdiEPs48EKKuwrrTbv6s63d4egjHW2 wKDHLroDpak1b1WPdrNHujfwNGwrD3WCg+nZt1SWT9MzIM7c/pcZXaZk8Xcwqw94IIOY CK0g== X-Gm-Message-State: AO0yUKU2YnQaw3aW8UlttJlex6N7ORA2vx7naXR5kae1A54x0C5BviYv RDe67O7NEMe4SV0HN5kWLt1/ptuh4X9+lA3RO/VDcg== X-Google-Smtp-Source: AK7set9NMaC5KydlQZa0CUJAZnCKfwMwhiTxfXnMRwrLyvAFQvPgV7MWUoVFIMaUMl0S5RLXVPFxZw== X-Received: by 2002:a6b:d310:0:b0:74c:9cc4:ac0 with SMTP id s16-20020a6bd310000000b0074c9cc40ac0mr7854459iob.14.1679909683140; Mon, 27 Mar 2023 02:34:43 -0700 (PDT) Received: from localhost.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id d12-20020a056602328c00b0075464a69c10sm7658345ioz.10.2023.03.27.02.34.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Mar 2023 02:34:42 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Mar 2023 10:34:37 +0100 Message-Id: <20230327093439.24670-3-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230327093439.24670-1-naush@raspberrypi.com> References: <20230327093439.24670-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/4] ipa: raspberrypi: Use the new sensor limits fields in CameraMode 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: Naushir Patuck via libcamera-devel From: Naushir Patuck Reply-To: Naushir Patuck Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Use the new analogue gain and shutter speed limit fields in the ipa code when reporting back the control value limits and calculating the analogue gain code to use. This also replaces the now unused (and removed) maxSensorGainCode_ field. Signed-off-by: Naushir Patuck Reviewed-by: David Plowman Reviewed-by: Jacopo Mondi --- src/ipa/raspberrypi/raspberrypi.cpp | 37 +++++++++-------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 3f1afb846420..c10e57e07ab0 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -224,9 +224,6 @@ private: Duration minFrameDuration_; Duration maxFrameDuration_; - /* Maximum gain code for the sensor. */ - uint32_t maxSensorGainCode_; - /* Track the frame length times over FrameLengthsQueueSize frames. */ std::deque frameLengths_; Duration lastTimeout_; @@ -455,8 +452,6 @@ int IPARPi::configure(const IPACameraSensorInfo &sensorInfo, const IPAConfig &ip } } - maxSensorGainCode_ = sensorCtrls_.at(V4L2_CID_ANALOGUE_GAIN).max().get(); - /* Setup a metadata ControlList to output metadata. */ libcameraMetadata_ = ControlList(controls::controls); @@ -517,26 +512,17 @@ int IPARPi::configure(const IPACameraSensorInfo &sensorInfo, const IPAConfig &ip * based on the current sensor mode. */ ControlInfoMap::Map ctrlMap = ipaControls; - const Duration minSensorFrameDuration = mode_.minFrameLength * mode_.minLineLength; - const Duration maxSensorFrameDuration = mode_.maxFrameLength * mode_.maxLineLength; ctrlMap[&controls::FrameDurationLimits] = - ControlInfo(static_cast(minSensorFrameDuration.get()), - static_cast(maxSensorFrameDuration.get())); + ControlInfo(static_cast(mode_.minFrameDuration.get()), + static_cast(mode_.maxFrameDuration.get())); ctrlMap[&controls::AnalogueGain] = - ControlInfo(1.0f, static_cast(helper_->gain(maxSensorGainCode_))); - - /* - * Calculate the max exposure limit from the frame duration limit as V4L2 - * will limit the maximum control value based on the current VBLANK value. - */ - Duration maxShutter = Duration::max(); - helper_->getBlanking(maxShutter, minSensorFrameDuration, maxSensorFrameDuration); - const uint32_t exposureMin = sensorCtrls_.at(V4L2_CID_EXPOSURE).min().get(); + ControlInfo(static_cast(mode_.minAnalogueGain), + static_cast(mode_.maxAnalogueGain)); ctrlMap[&controls::ExposureTime] = - ControlInfo(static_cast(helper_->exposure(exposureMin, mode_.minLineLength).get()), - static_cast(maxShutter.get())); + ControlInfo(static_cast(mode_.minShutter.get()), + static_cast(mode_.maxShutter.get())); /* Declare Autofocus controls, only if we have a controllable lens */ if (lensPresent_) @@ -1496,9 +1482,6 @@ void IPARPi::applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls) void IPARPi::applyFrameDurations(Duration minFrameDuration, Duration maxFrameDuration) { - const Duration minSensorFrameDuration = mode_.minFrameLength * mode_.minLineLength; - const Duration maxSensorFrameDuration = mode_.maxFrameLength * mode_.maxLineLength; - /* * This will only be applied once AGC recalculations occur. * The values may be clamped based on the sensor mode capabilities as well. @@ -1506,9 +1489,9 @@ void IPARPi::applyFrameDurations(Duration minFrameDuration, Duration maxFrameDur minFrameDuration_ = minFrameDuration ? minFrameDuration : defaultMaxFrameDuration; maxFrameDuration_ = maxFrameDuration ? maxFrameDuration : defaultMinFrameDuration; minFrameDuration_ = std::clamp(minFrameDuration_, - minSensorFrameDuration, maxSensorFrameDuration); + mode_.minFrameDuration, mode_.maxFrameDuration); maxFrameDuration_ = std::clamp(maxFrameDuration_, - minSensorFrameDuration, maxSensorFrameDuration); + mode_.minFrameDuration, mode_.maxFrameDuration); maxFrameDuration_ = std::max(maxFrameDuration_, minFrameDuration_); /* Return the validated limits via metadata. */ @@ -1531,6 +1514,8 @@ void IPARPi::applyFrameDurations(Duration minFrameDuration, Duration maxFrameDur void IPARPi::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls) { + const int32_t minGainCode = helper_->gainCode(mode_.minAnalogueGain); + const int32_t maxGainCode = helper_->gainCode(mode_.maxAnalogueGain); int32_t gainCode = helper_->gainCode(agcStatus->analogueGain); /* @@ -1538,7 +1523,7 @@ void IPARPi::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls) * DelayedControls. The AGC will correctly handle a lower gain returned * by the sensor, provided it knows the actual gain used. */ - gainCode = std::min(gainCode, maxSensorGainCode_); + gainCode = std::clamp(gainCode, minGainCode, maxGainCode); /* getBlanking might clip exposure time to the fps limits. */ Duration exposure = agcStatus->shutterTime; From patchwork Mon Mar 27 09:34:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 18467 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 222C5C0F2A for ; Mon, 27 Mar 2023 09:34:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B3E4562722; Mon, 27 Mar 2023 11:34:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1679909689; bh=LtIvZoQ2b9m0ZRNttQCaBfvcaSM+z/JFpHVCN58WoZU=; 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=tUC/o68R112u1Xng/lcTItxKgacGrYr/jZ5iFOCvnxazbJY9n1AytEQG3NsFnMLqE YXy0oaXvP1KwGwQq4CuG48BVMePpn3044fj1DFsmUEgkn+CrO30PuerWSdoVPgfcU9 vTzFNdGFlyeeEMjMzigKYGYKqkp865jbnyTyW/cZWJytHqNkTofNdwYmP57RNXW9uQ /B60+opChQ9SGNFdQuYcAAVqNzRbYyvVDzYViN5mblY5JuqvCiN6yxIBXG+eDV0Omt F20kmoTDGxAkzhblgFGIa1+IGTEuISOX62purwjetw736f6bw5KirVQs+AoxPB5XhB swovBWfMrkaMw== Received: from mail-io1-xd2a.google.com (mail-io1-xd2a.google.com [IPv6:2607:f8b0:4864:20::d2a]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 98A7862734 for ; Mon, 27 Mar 2023 11:34:45 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="jcq7uoRL"; dkim-atps=neutral Received: by mail-io1-xd2a.google.com with SMTP id z1so3596792iot.11 for ; Mon, 27 Mar 2023 02:34:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1679909684; 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=J1p8odmcQLQ8khz9y4InWwm5liYe3di4rkdWz5nZxo0=; b=jcq7uoRLUHqcNNyTv0Xv1GDd8NBTdOO7ge2Rzqcwe87fNDth1PEb+GQCfcPx0aYKpI GJQc0yvlCewEI33vFRXhYitn0PNnEWv0v7vGM7mPoISuyG3r8ek23Lkmq66hbsODxiQX lPCjvaiLMt7i9qP0RtTgYCkw4/abliyhphWZTRBNlIu/7srBpRTHf1UVznfjZSqeKC1m 57KTUPPXh0/q53EQ8k6rVTmB8UqDDb/eLbcazykpwcO2idw58t+snki7BYs7r11yN7Df +LqyoR8CfpMCBFlsP+DHoMPkLUW6grrIgk5OqW1GhH0wVGZokOo1BrhUHWttb+g/xwKg 296w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679909684; 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=J1p8odmcQLQ8khz9y4InWwm5liYe3di4rkdWz5nZxo0=; b=BGqTBZpspqAzi7muQIggod/10sKsYWXB3Xxf7Zww8Ds7fxftKRquqSYaTTii7sV3BI K2f2qF2FQX1lDSRF63jN51XIFwvC97995D3l78rGiv1lBKdGf3xhmuFtv/+Uu65fZJuf CoenOIz0zHXMDRUxrWMEDmAUX0bgDZDlxIwPJGT/sRNjFLdsDh2raUpjRYSDM7LXiETo RY97Kuom5S+ZKwYF90W+ZHgchPOErGPqUp5L52GH/0qqA7FLGfdvCLoosZAuF7CMFtzf KgfIG5gPaslZgWBHE4a2FnzK3rNKXQ1bOS1zqbFYoCxHDqRXw0FeuV6IpINzmkTbV2uo vRUg== X-Gm-Message-State: AO0yUKXuzs6A2Vg8UDq4RHYkYWpbzQ+LMe9g3x8KEIl3Dmm+hHnBOHmd Q72a+f8nh6IXkn0r/l2D7ppdSmoSEH9VCH1xpf4EKQ== X-Google-Smtp-Source: AK7set/iielrwtrI/ajdwkjEq3aUZTj+gW52er+epZ1AwOwJC4UgrsY8zTNkBkRPP1Vj5WqojEfUFQ== X-Received: by 2002:a6b:6101:0:b0:71b:5cd7:fcd9 with SMTP id v1-20020a6b6101000000b0071b5cd7fcd9mr8123158iob.20.1679909684066; Mon, 27 Mar 2023 02:34:44 -0700 (PDT) Received: from localhost.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id d12-20020a056602328c00b0075464a69c10sm7658345ioz.10.2023.03.27.02.34.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Mar 2023 02:34:43 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Mar 2023 10:34:38 +0100 Message-Id: <20230327093439.24670-4-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230327093439.24670-1-naush@raspberrypi.com> References: <20230327093439.24670-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 3/4] ipa: raspberrypi: Ensure shutter speed and gain are clipped in the AGC 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: Naushir Patuck via libcamera-devel From: Naushir Patuck Reply-To: Naushir Patuck Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Make a copy of the CameraMode structure on a switch mode call. This replaces the existing lastSensitivity_ field. Limit the AGC gain calculations to the minimum value given by the CameraMode structure. The maximum value remains unclipped as any gain over the sensor maximum will be made up by digital gain. Rename clipShutter to limitShutter for consistency, and have the latter limit the shutter speed to both upper and lower bounds. Signed-off-by: Naushir Patuck Reviewed-by: David Plowman Reviewed-by: Jacopo Mondi --- src/ipa/raspberrypi/controller/rpi/agc.cpp | 55 +++++++++++++++++----- src/ipa/raspberrypi/controller/rpi/agc.h | 4 +- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp index 4ea0dd41e66c..ed7ecbe05a8e 100644 --- a/src/ipa/raspberrypi/controller/rpi/agc.cpp +++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp @@ -309,14 +309,14 @@ void Agc::setFixedShutter(Duration fixedShutter) { fixedShutter_ = fixedShutter; /* Set this in case someone calls disableAuto() straight after. */ - status_.shutterTime = clipShutter(fixedShutter_); + status_.shutterTime = limitShutter(fixedShutter_); } void Agc::setFixedAnalogueGain(double fixedAnalogueGain) { fixedAnalogueGain_ = fixedAnalogueGain; /* Set this in case someone calls disableAuto() straight after. */ - status_.analogueGain = fixedAnalogueGain; + status_.analogueGain = limitGain(fixedAnalogueGain); } void Agc::setMeteringMode(std::string const &meteringModeName) @@ -342,7 +342,7 @@ void Agc::switchMode(CameraMode const &cameraMode, housekeepConfig(); - Duration fixedShutter = clipShutter(fixedShutter_); + Duration fixedShutter = limitShutter(fixedShutter_); if (fixedShutter && fixedAnalogueGain_) { /* We're going to reset the algorithm here with these fixed values. */ @@ -371,7 +371,7 @@ void Agc::switchMode(CameraMode const &cameraMode, * current exposure profile, which takes care of everything else. */ - double ratio = lastSensitivity_ / cameraMode.sensitivity; + double ratio = mode_.sensitivity / cameraMode.sensitivity; target_.totalExposureNoDG *= ratio; target_.totalExposure *= ratio; filtered_.totalExposureNoDG *= ratio; @@ -393,8 +393,11 @@ void Agc::switchMode(CameraMode const &cameraMode, writeAndFinish(metadata, false); - /* We must remember the sensitivity of this mode for the next SwitchMode. */ - lastSensitivity_ = cameraMode.sensitivity; + /* + * Store the more in the local state. We must remember the sensitivity + * of this mode for the next SwitchMode. + */ + mode_ = cameraMode; } void Agc::prepare(Metadata *imageMetadata) @@ -516,7 +519,7 @@ void Agc::housekeepConfig() { /* First fetch all the up-to-date settings, so no one else has to do it. */ status_.ev = ev_; - status_.fixedShutter = clipShutter(fixedShutter_); + status_.fixedShutter = limitShutter(fixedShutter_); status_.fixedAnalogueGain = fixedAnalogueGain_; status_.flickerPeriod = flickerPeriod_; LOG(RPiAgc, Debug) << "ev " << status_.ev << " fixedShutter " @@ -703,7 +706,7 @@ void Agc::computeTargetExposure(double gain) Duration maxShutter = status_.fixedShutter ? status_.fixedShutter : exposureMode_->shutter.back(); - maxShutter = clipShutter(maxShutter); + maxShutter = limitShutter(maxShutter); Duration maxTotalExposure = maxShutter * (status_.fixedAnalogueGain != 0.0 @@ -803,15 +806,16 @@ void Agc::divideUpExposure() double analogueGain; shutterTime = status_.fixedShutter ? status_.fixedShutter : exposureMode_->shutter[0]; - shutterTime = clipShutter(shutterTime); + shutterTime = limitShutter(shutterTime); analogueGain = status_.fixedAnalogueGain != 0.0 ? status_.fixedAnalogueGain : exposureMode_->gain[0]; + analogueGain = limitGain(analogueGain); if (shutterTime * analogueGain < exposureValue) { for (unsigned int stage = 1; stage < exposureMode_->gain.size(); stage++) { if (!status_.fixedShutter) { Duration stageShutter = - clipShutter(exposureMode_->shutter[stage]); + limitShutter(exposureMode_->shutter[stage]); if (stageShutter * analogueGain >= exposureValue) { shutterTime = exposureValue / analogueGain; break; @@ -824,6 +828,7 @@ void Agc::divideUpExposure() break; } analogueGain = exposureMode_->gain[stage]; + analogueGain = limitGain(analogueGain); } } } @@ -846,6 +851,7 @@ void Agc::divideUpExposure() * gain as a side-effect. */ analogueGain = std::min(analogueGain, exposureMode_->gain.back()); + analogueGain = limitGain(analogueGain); shutterTime = newShutterTime; } LOG(RPiAgc, Debug) << "After flicker avoidance, shutter " @@ -872,13 +878,36 @@ void Agc::writeAndFinish(Metadata *imageMetadata, bool desaturate) << " analogue gain " << filtered_.analogueGain; } -Duration Agc::clipShutter(Duration shutter) +Duration Agc::limitShutter(Duration shutter) { - if (maxShutter_) - shutter = std::min(shutter, maxShutter_); + /* + * shutter == 0 is a special case for fixed shutter values, and must pass + * through unchanged + */ + if (!shutter) + return shutter; + + shutter = std::clamp(shutter, mode_.minShutter, maxShutter_); return shutter; } +double Agc::limitGain(double gain) const +{ + /* + * Only limit the lower bounds of the gain value to what the sensor limits. + * The upper bound on analogue gain will be made up with additional digital + * gain applied by the ISP. + * + * gain == 0.0 is a special case for fixed shutter values, and must pass + * through unchanged + */ + if (!gain) + return gain; + + gain = std::max(gain, mode_.minAnalogueGain); + return gain; +} + /* Register algorithm with the system. */ static Algorithm *create(Controller *controller) { diff --git a/src/ipa/raspberrypi/controller/rpi/agc.h b/src/ipa/raspberrypi/controller/rpi/agc.h index f04896ca25ad..661d8b08cea2 100644 --- a/src/ipa/raspberrypi/controller/rpi/agc.h +++ b/src/ipa/raspberrypi/controller/rpi/agc.h @@ -103,10 +103,12 @@ private: void filterExposure(bool desaturate); void divideUpExposure(); void writeAndFinish(Metadata *imageMetadata, bool desaturate); - libcamera::utils::Duration clipShutter(libcamera::utils::Duration shutter); + libcamera::utils::Duration limitShutter(libcamera::utils::Duration shutter); + double limitGain(double gain) const; AgcMeteringMode *meteringMode_; AgcExposureMode *exposureMode_; AgcConstraintMode *constraintMode_; + CameraMode mode_; uint64_t frameCount_; AwbStatus awb_; struct ExposureValues { From patchwork Mon Mar 27 09:34:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 18468 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 A1A26C326C for ; Mon, 27 Mar 2023 09:34:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 47E356271E; Mon, 27 Mar 2023 11:34:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1679909690; bh=XSUIUUNxfOpTmzrNOaJlxZ9ZFDh4NyWbb8aWkoecDO0=; 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=qfIaw05zYK0tA0LOlWkfkN6VsQq1XWVwXIyKo6Wgy0B/jdVo1PGYLr3aDvedTlXO5 baYVdyKgLlKjQz0/GSMWY3C/siE1Zg+wmkOo8ymu7e/N0R4iBvDJ91ShovXpjSLgzZ 02p0mfg+4MxgTUJvx1IC9OoSi6/KyWE9oIcgm97pDXJjPoBwuvz3+BjZfohxtSVa6N PvDVH8kEzyaMpGQW1Vyp96VIZNBf6DHjHo0fgujCOy7XhNQ8g8KfJ0cxFlDrKAn2TZ nXf0bQur3jXh4IurbbCRf1vGt3OugeXg1konkjftAlwhZju1VQlZqBGC7Z5+DF0ISX qcuYiTC8R3qhA== Received: from mail-io1-xd2e.google.com (mail-io1-xd2e.google.com [IPv6:2607:f8b0:4864:20::d2e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5548A62724 for ; Mon, 27 Mar 2023 11:34:46 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="CUn+q5aQ"; dkim-atps=neutral Received: by mail-io1-xd2e.google.com with SMTP id p17so3601603ioj.10 for ; Mon, 27 Mar 2023 02:34:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1679909685; 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=p0hVtHHnzZKHAsyUKyPksKTBylxtTOrJ1jmAU6zbBEE=; b=CUn+q5aQCWiaM2LvBo4a5CHoUrX3FTUbxqilQ1Zt4t5/8/mm8PWkCxOzpgU6nKiJZ+ QVOuAzaMVETQSAdRxVehb4RtZwV+DBNPB85NqePt16yMIYSDt5Esp6eMqmd3pZPKuDub WoGJEjnILEoUSCdgeG5N5ONl16HEKhOplpYWBb/LfguY0i0b9cKV5LexkZ5pBBrHOQbr 2rblJtvnNbNElptS4dKPhu/SNruYb7E/uBid12lw2A5hl2IfdsWpQnXz6E7a9ZCDymr2 ki0/s6+HVBe/CP3sLWKieserF4zZfeNzTONmFQtI0DQn74gFYD0LdF0AJO2BNSTnIc68 zRHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679909685; 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=p0hVtHHnzZKHAsyUKyPksKTBylxtTOrJ1jmAU6zbBEE=; b=uclv+rquOUsvvZwZ044aPV4aqKtA/MYPwZgcGMZ8J04dMuFWAToHepMu8/g2A1bQCt rLvY8e+AWzTOHU3P7gaTQaOC2rGe9T3amtCnmJX8I/IBWDH2JEa+KcqHpzp327DY58mK gTd2Nt70yRfG3A4hivw4U5iyJmXt4XsOOdg6JKPM0V1oz2pEhfyKzAwr+Sg9IAIjTaAP rbZnKK9ZLOqE1xbKUW7aOec2PR1wtH3/VC1lSjJDPQRtSeeNkBdP3pklKtu6AMj4vd/P X51ORoyVh5TAn9/rebOU4WniWGywbwI8e/Lj8Oo+hg7CJ/bG5tvjd4SVGGr0xsrs6Jg8 3zxA== X-Gm-Message-State: AO0yUKXVuNu+VS8U7o4ZiXRT3WoSR0aZTZYHkU9q0v88AjnYQgcETDlI DXHG8Mn2DMsAdvEG1LYz50eyLYUnlpPM7Ie81ZVF9g== X-Google-Smtp-Source: AK7set8CimX3INzdlWFcB7p0VJRWZM5wTJ989l/nlPYYCM07nA85xUdyqyx05MJeCUnOr0ha0Hkd/A== X-Received: by 2002:a5e:8c05:0:b0:759:6a8e:96e5 with SMTP id n5-20020a5e8c05000000b007596a8e96e5mr7057239ioj.17.1679909684982; Mon, 27 Mar 2023 02:34:44 -0700 (PDT) Received: from localhost.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id d12-20020a056602328c00b0075464a69c10sm7658345ioz.10.2023.03.27.02.34.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Mar 2023 02:34:44 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Mar 2023 10:34:39 +0100 Message-Id: <20230327093439.24670-5-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230327093439.24670-1-naush@raspberrypi.com> References: <20230327093439.24670-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 4/4] ipa: raspberrypi: Fix default frame durations calculation 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: Naushir Patuck via libcamera-devel From: Naushir Patuck Reply-To: Naushir Patuck Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Fix a bug in the default frame durations calculation where the min/max values are swapped round. This is a rarely travelled code path, so has not actually caused a reported failure. Signed-off-by: Naushir Patuck Reviewed-by: David Plowman Reviewed-by: Jacopo Mondi --- src/ipa/raspberrypi/raspberrypi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index c10e57e07ab0..66a020d022cd 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -1486,8 +1486,8 @@ void IPARPi::applyFrameDurations(Duration minFrameDuration, Duration maxFrameDur * This will only be applied once AGC recalculations occur. * The values may be clamped based on the sensor mode capabilities as well. */ - minFrameDuration_ = minFrameDuration ? minFrameDuration : defaultMaxFrameDuration; - maxFrameDuration_ = maxFrameDuration ? maxFrameDuration : defaultMinFrameDuration; + minFrameDuration_ = minFrameDuration ? minFrameDuration : defaultMinFrameDuration; + maxFrameDuration_ = maxFrameDuration ? maxFrameDuration : defaultMaxFrameDuration; minFrameDuration_ = std::clamp(minFrameDuration_, mode_.minFrameDuration, mode_.maxFrameDuration); maxFrameDuration_ = std::clamp(maxFrameDuration_,