From patchwork Wed Aug 23 12:09:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 18954 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 460E2C32B0 for ; Wed, 23 Aug 2023 12:09:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D2F13628D7; Wed, 23 Aug 2023 14:09:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1692792567; bh=Lc9MIYLNUxJ6O1kelx5tO983QpzUCyKjYL6vadoy/5E=; 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=AGZdAoqH0VLPOHSsMcyvLhecSgtTzZmNVLcnlBtjVGSkjIc1p60LsAs3xI4la4o7H 5aKl/H2dTjUqICFDjuI+KDR+6UYu3Nm1m6bX4eZvf6L+YSii/Dzv5eGy9nGD6wblwk uaMcR3iJlFBIWjgGv+alQnwqqSzcutp8ZaJpKwOt0HVazRGHq/Ngq0pPhH7BAXc1v9 z4HQF63LLNuCHGzuJIQNKiBCxf3ximH0HFZ6TqgL8njAfnedj5GSqWWHe75OBvVzSo bX2DPucLVhMBmnE6os6DhTADREaARLbXHPofWLmRcYkBZeX6SK8wRJOH5iZUgnF1/d 7AA9QDgzX4SiA== Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5C117628BC for ; Wed, 23 Aug 2023 14:09:22 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="FOFPcw8R"; dkim-atps=neutral Received: by mail-wm1-x32e.google.com with SMTP id 5b1f17b1804b1-3fee600dce6so38332225e9.1 for ; Wed, 23 Aug 2023 05:09:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1692792561; x=1693397361; 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=xyBn1rMtUAm//vTeerXmljtU3iKqtQ+pSllh1EOmZ2o=; b=FOFPcw8Ra64347zqg/CJcPx0WYVxVL8t0ejQKbI4ZiEHsVeXm8Bb8qTtNHaRkDTzKp aqV3bpVTN8vdXDKskr3gZztoqUU0htrrYxi5sddx0Tzi6imaSzfMpjUB1k1KVD3hqYDi 5sCTAl8QJG3rPrLgufrMs9XZfIY3higXIYu7vHiSpGcSa87xFS0r2xiZSW+U73fteQIV JG0zsD8QJXc7UXL47LmkZB/L1OW3y/HFWGtqU11+hClOL0BgHgF8ibki5cBCEY/ZMyH9 8taI6TNdbce6tsSYaYssAIIUzMGFDcfGsClbws9nQNTzQxLZ04hmAnBRn5H2gK8DgMSY pPog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692792561; x=1693397361; 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=xyBn1rMtUAm//vTeerXmljtU3iKqtQ+pSllh1EOmZ2o=; b=VmHLDKy/6lDpcWt5RMkL+ZZLNG7ghq8NfN31QgqGcgngqk4DgDj33cVlwpWoAhxSA5 STb+DT5RKzy0FizTvTNu1ld4dy9LvNL/X7n1W9eMqIoyC6I15SD/BHERXZ44EZqUEICT 14LtwT4rDGf0OmNIZhh5s2Wm/UTFffjyfwLGH+2U5rD3hdYG4//DgdmCF8+rMeBhYxSF Wf6ZyNq88aMaYXbRw1WiAFtFR15ZTCE0Scsi+dfjrTgGSGZorcbA632336BzDxIQYIxd iSaCZfhKRn/lN19R1JNTG63mm0kX4qs9pPmeeu3TBVPchZMYJKn+Dg0dZC2j+a3l5Z35 XMiA== X-Gm-Message-State: AOJu0YxT4Ww5JXCY4lO7gSCMZ7RhdPhree17p2501s1vy5HSe76J6wn7 Hh2IkcGw19/PyeqTrSq/Uv762ah7QhTpdN8Pjy8= X-Google-Smtp-Source: AGHT+IFrtV+SioMcMbZg3NV6/+eo23ep26RPMFPnOea9T+eh+XrlpXlyAGKoQkpvQ8YrLDzrs8du3Q== X-Received: by 2002:a05:600c:204b:b0:3fb:b3aa:1c8f with SMTP id p11-20020a05600c204b00b003fbb3aa1c8fmr10157557wmg.28.1692792561596; Wed, 23 Aug 2023 05:09:21 -0700 (PDT) Received: from pi4-davidp.pitowers.org ([2a00:1098:3142:14:2bce:64d6:1a5c:49a2]) by smtp.gmail.com with ESMTPSA id u1-20020a7bcb01000000b003fefcbe7fa8sm3800589wmj.28.2023.08.23.05.09.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 05:09:21 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 23 Aug 2023 13:09:14 +0100 Message-Id: <20230823120915.18621-5-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230823120915.18621-1-david.plowman@raspberrypi.com> References: <20230823120915.18621-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 4/5] ipa: rpi: agc: Add AgcChannelConstraint class 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" A channel constraint is somewhat similar to the upper/lower bound constraints that we use elsewhere, but these constraints apply between multiple AGC channels. For example, it lets you say things like "don't let the channel 1 total exposure be more than 8x that of channel 0", and so on. By using both an upper and lower bound constraint, you could fix one AGC channel always to be a fixed ratio of another. Also read a vector of them (if present) when loading the tuning file. Signed-off-by: David Plowman Reviewed-by: Naushir Patuck --- src/ipa/rpi/controller/rpi/agc_channel.cpp | 42 ++++++++++++++++++++++ src/ipa/rpi/controller/rpi/agc_channel.h | 10 ++++++ 2 files changed, 52 insertions(+) diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp index ddec611f..44198c2c 100644 --- a/src/ipa/rpi/controller/rpi/agc_channel.cpp +++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp @@ -173,6 +173,42 @@ readConstraintModes(std::map &constraintModes, return { 0, first }; } +int AgcChannelConstraint::read(const libcamera::YamlObject ¶ms) +{ + std::string boundString = params["bound"].get(""); + transform(boundString.begin(), boundString.end(), + boundString.begin(), ::toupper); + if (boundString != "UPPER" && boundString != "LOWER") { + LOG(RPiAgc, Error) << "AGC channelconstraint type should be UPPER or LOWER"; + return -EINVAL; + } + bound = boundString == "UPPER" ? Bound::UPPER : Bound::LOWER; + + auto value = params["factor"].get(); + if (!value) + return -EINVAL; + factor = *value; + + return 0; +} + +static int readChannelConstraints(std::vector &channelConstraints, + const libcamera::YamlObject ¶ms) +{ + int ret = 0; + + for (const auto &p : params.asList()) { + AgcChannelConstraint constraint; + ret = constraint.read(p); + if (ret) + return ret; + + channelConstraints.push_back(constraint); + } + + return ret; +} + int AgcConfig::read(const libcamera::YamlObject ¶ms) { LOG(RPiAgc, Debug) << "AgcConfig"; @@ -191,6 +227,12 @@ int AgcConfig::read(const libcamera::YamlObject ¶ms) if (ret) return ret; + if (params.contains("channel_constraints")) { + ret = readChannelConstraints(channelConstraints, params["channel_constraints"]); + if (ret) + return ret; + } + ret = yTarget.read(params["y_target"]); if (ret) return ret; diff --git a/src/ipa/rpi/controller/rpi/agc_channel.h b/src/ipa/rpi/controller/rpi/agc_channel.h index 0e3d44b0..446125ef 100644 --- a/src/ipa/rpi/controller/rpi/agc_channel.h +++ b/src/ipa/rpi/controller/rpi/agc_channel.h @@ -42,11 +42,21 @@ struct AgcConstraint { typedef std::vector AgcConstraintMode; +struct AgcChannelConstraint { + enum class Bound { LOWER = 0, + UPPER = 1 }; + Bound bound; + unsigned int channel; + double factor; + int read(const libcamera::YamlObject ¶ms); +}; + struct AgcConfig { int read(const libcamera::YamlObject ¶ms); std::map meteringModes; std::map exposureModes; std::map constraintModes; + std::vector channelConstraints; Pwl yTarget; double speed; uint16_t startupFrames;