From patchwork Mon Jul 31 09:46:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 18907 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 80DABBDB13 for ; Mon, 31 Jul 2023 09:46:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2F93E627EF; Mon, 31 Jul 2023 11:46:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1690796812; bh=jGq5jBI3BqwxJE7FTkFcHo3Tzt/Lct4FiWi97U8t/Dw=; 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=cq6Q+hxRL2Bb2036cb2E6OUW2aNU0jGEUjMmkQ9ERNixklmOdJW3m3oHV/JcMPm+l T0VozjCettKXs1O75lp4bryXjKkkU21/1HE77gI0W5V2Ih3yxdEWjxKCJjRLlaUMIv jHJBWmYUqp8p/mYUL7U/kf02giYp8aVbKGqImaTyLJLmaKjGQJ05JVAbmPM7fsaaxO Yo6bfhzIgoSJIhYn75Db8qE/vCQBlaYzTL1/Xdx8Mpwtd/pgXOeuGGBEB2W6qsWPgo kCeydiRSXJ/5CWONWy/em4w4r8UJY89MAx+ZBPr6ii1QaIS7MCHxVqN11Z90mFspKT 1oqkNlhy5sIyg== Received: from mail-lj1-x233.google.com (mail-lj1-x233.google.com [IPv6:2a00:1450:4864:20::233]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 23FDC627ED for ; Mon, 31 Jul 2023 11:46:48 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="PcxU5ntk"; dkim-atps=neutral Received: by mail-lj1-x233.google.com with SMTP id 38308e7fff4ca-2b74fa5e7d7so62476651fa.2 for ; Mon, 31 Jul 2023 02:46:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1690796807; x=1691401607; 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=9vptURN2phqMoGwpBtJfb059dhhw16s4PNq8MmQlO9c=; b=PcxU5ntk9nVmjQPGYiB98sQC4cjYPEuaxew9p/w7sCVNhp9lOi6f9lPjOIDhd8r/ZG RNxQ5FLtEkyUpuxlDO8AGnxanv7eEe1xX+i+mxpkwV8MDMfQaeFk3Q7NGbEowvK6IAxu OJdAFb7ccbXeiWQgyz/pYIF5kC6ES/nL4ceuZOBrKhhrvK+pL9jYWjgB8UCd+1QLEOrZ WU67DO+0TceNJyZRiLOKAX0fyQrSv/pwFEstejGedkftHVbodYZrQXQ+Q98sAG880HW3 v78fnDEaIIihGfD8X0MqVy+5QdRJgmQaHrPOf9oPz/F7ZCTVgjvasTpk3X4Wym6jElwH 2Dww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690796807; x=1691401607; 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=9vptURN2phqMoGwpBtJfb059dhhw16s4PNq8MmQlO9c=; b=Sf2n8ByIQYTYYiPfXBfWR+GOORcnptQEw3ql8SjGMD9r7rzCNG7TCjLfZ1T911x5N3 17gmDy7acnxiSBXVwMNaBlRQxS95GiHlokB2NXadqhzyMI2gCft0DYKiQvjkRtLvombx M/fUFQmt4S4gRWUsSgaQ9cOoYexPot6URVDOPDl8KI9f8iDh7k4NW7/rTo+/l6BAlxRk Hlbu9NmLLCLuReAdVZqqCW/rTeakBXeckEM4UWNK5V3YqI38GM6c5WBmWsoLjz1wq5xb jDWyUweLGuhSEH+Ya9T+f2fJmhz2oUzDI7U1Pw1YNIAMtlXn2/fg1Xs6vI3C/DOXpr9b QYXg== X-Gm-Message-State: ABy/qLbPgPS1sAR+G6E2SQUx02pWW+qAd2LSoQTFcAD7Tva+rDxiJNJP 138zEPpvYuAQccsqw8pJHwUo/ZNlydQ1zB9RPiY= X-Google-Smtp-Source: APBJJlGJe5DiqDhgfKL8QlafMloOwTkNiWXt91kNby/O38RTSvX3zLJGr3gUF0Fa9ejZR+QzKrBZqw== X-Received: by 2002:a2e:93cd:0:b0:2b9:43a7:376e with SMTP id p13-20020a2e93cd000000b002b943a7376emr3881949ljh.29.1690796807039; Mon, 31 Jul 2023 02:46:47 -0700 (PDT) Received: from pi4-davidp.pitowers.org ([2a00:1098:3142:14:2bce:64d6:1a5c:49a2]) by smtp.gmail.com with ESMTPSA id 9-20020a05600c240900b003fa98908014sm13612838wmp.8.2023.07.31.02.46.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jul 2023 02:46:46 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Mon, 31 Jul 2023 10:46:40 +0100 Message-Id: <20230731094641.73646-5-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230731094641.73646-1-david.plowman@raspberrypi.com> References: <20230731094641.73646-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 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..ed8a3b30 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; +} + +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(std::move(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;