From patchwork Tue Sep 12 10:24:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 18993 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 2173CC32B2 for ; Tue, 12 Sep 2023 10:24:56 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6D09A628F8; Tue, 12 Sep 2023 12:24:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694514295; bh=ssOxDy1COKONYMwOqGbhPP9i46GebBKZrY7TAZsl72I=; 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=FXjF8Ua+CgdWWwFistzDVBNW/vFqW2HnGVqBCFVcql5QM79U/sbw8AGT+e3DZNJWw RD+wwo2YxsWc+ahjkWRpNpIZUzlOwko2TjF+jLnKbjUlxek1D2gyOipfT7Nb2jnWVe JThM7sfaHP4Dy8OfmOjvJTOSFNHPpPLKNBrT8u5duZ/YpzJhAbsBX5qf8WiSFAsaYT gQcF5Kt7KsU9yIQfiObeFrqnun5CI6O8zKIXW7Yp+v5GGDAieTMrMjGSTtqwIaZ1n+ +Nyx4ZvwGFoQSgpJr2SxjLoC8Mb+upvl8HUoCZLtAZPKlFWt2bEzswQpb0GFuJVSMv 3c+4xHBMBsUMg== Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AEF7061DEF for ; Tue, 12 Sep 2023 12:24:52 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="B4rxI1Bz"; dkim-atps=neutral Received: by mail-wm1-x32a.google.com with SMTP id 5b1f17b1804b1-401d67434daso58373145e9.2 for ; Tue, 12 Sep 2023 03:24:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1694514292; x=1695119092; darn=lists.libcamera.org; 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=Fh/H/WqAaCgcyXj/u7SH9bguu1ZXy8aCpSWRL27uAKg=; b=B4rxI1Bz5L3JViZPqfvgz965nMDN7/0U7jaRC3jXxrC0AGF5omx35Fa4JUf6+tBDjz r1lZbmyvm8cmZl9hb0yGT2JD7H5u+7CGO0pDwV+/1hN6hDxhorcnhRHgBS9wYncOTxUP QpLuzot7/0xWSxrUCluMjcC3QXXe0Wh4a1shI2DI1DoQIgCFxcdmDPnXZ7hYJdD/dCvd PnL5krYXoxIIcPogb4OG11u171w2Ne4fJmvyD/Ffc2KEoWbSLGg1+Mknfzy4YHWyqp65 U32YCvJD7aa4BZ+VR11wxNr4W5vVZEvkiteNShfrDJnKIHJkv05PlxxxTlUhJKYnfUfc BSQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694514292; x=1695119092; 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=Fh/H/WqAaCgcyXj/u7SH9bguu1ZXy8aCpSWRL27uAKg=; b=NHjVbpVGiuISAtkqUFhbKjMNw9KJJFSP6MIHjgy3phkY6mGhLoBJ3vGX2l2n3w7AWh dzqEWllr+M+PQABF+V9sQB/5ZkWDCj2g+ioRf8NdCBHhvFB+gqeF+W/G4IXg+J/FExOL 8CMDA2jVx+HO8cezxaekW3BabNGdE5oOycrKMz2Aw4TXyYv7YxK2perUbyK4kjvzWMa5 n4M5zEYsH1B0ONtKZ8VjPfOpElVwESGFSzKN5/odwRfTI/C6QBtZrx2PWIyAiRQSP+11 UyqzwODbFWujFQAAefqrxcNwxligvJGXUUZahsjIA6di/JgiQvq5AqO3XrEX7maTZfVi TRdQ== X-Gm-Message-State: AOJu0Yzm4ESNCLyZgJoLEIIQP2+mvOTO2VQu8vNdGS5PIdADO7p3L5Ux xx/v9mfVoK/SPqBqsLSFtMlutfg2NuuCcWaW4nw= X-Google-Smtp-Source: AGHT+IE3C7MuiQUY3uC3tn/cxxzzgWF50UMuAfrf7wDIqmQZf5pJYv3IUIZlqdRciPgiy1SnwMrVZA== X-Received: by 2002:a05:600c:ad3:b0:401:bcd9:4871 with SMTP id c19-20020a05600c0ad300b00401bcd94871mr11019630wmr.21.1694514292006; Tue, 12 Sep 2023 03:24:52 -0700 (PDT) Received: from pi4-davidp.pitowers.org ([2a00:1098:3142:14:2bce:64d6:1a5c:49a2]) by smtp.gmail.com with ESMTPSA id n10-20020a05600c294a00b003fefaf299b6sm12426575wmd.38.2023.09.12.03.24.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Sep 2023 03:24:51 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Tue, 12 Sep 2023 11:24:41 +0100 Message-Id: <20230912102442.169001-5-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230912102442.169001-1-david.plowman@raspberrypi.com> References: <20230912102442.169001-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 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 Reviewed-by: Jacopo Mondi --- src/ipa/rpi/controller/rpi/agc_channel.cpp | 49 ++++++++++++++++++++++ src/ipa/rpi/controller/rpi/agc_channel.h | 10 +++++ 2 files changed, 59 insertions(+) diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp index f1f19598..7fce35b0 100644 --- a/src/ipa/rpi/controller/rpi/agc_channel.cpp +++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp @@ -170,6 +170,49 @@ readConstraintModes(std::map &constraintModes, return { 0, first }; } +int AgcChannelConstraint::read(const libcamera::YamlObject ¶ms) +{ + auto channelValue = params["channel"].get(); + if (!channelValue) { + LOG(RPiAgc, Error) << "AGC channel constraint must have a channel"; + return -EINVAL; + } + channel = *channelValue; + + std::string boundString = params["bound"].get(""); + transform(boundString.begin(), boundString.end(), + boundString.begin(), ::toupper); + if (boundString != "UPPER" && boundString != "LOWER") { + LOG(RPiAgc, Error) << "AGC channel constraint type should be UPPER or LOWER"; + return -EINVAL; + } + bound = boundString == "UPPER" ? Bound::UPPER : Bound::LOWER; + + auto factorValue = params["factor"].get(); + if (!factorValue) { + LOG(RPiAgc, Error) << "AGC channel constraint must have a factor"; + return -EINVAL; + } + factor = *factorValue; + + return 0; +} + +static int readChannelConstraints(std::vector &channelConstraints, + const libcamera::YamlObject ¶ms) +{ + for (const auto &p : params.asList()) { + AgcChannelConstraint constraint; + int ret = constraint.read(p); + if (ret) + return ret; + + channelConstraints.push_back(constraint); + } + + return 0; +} + int AgcConfig::read(const libcamera::YamlObject ¶ms) { LOG(RPiAgc, Debug) << "AgcConfig"; @@ -188,6 +231,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 24ee3491..5d2d8a11 100644 --- a/src/ipa/rpi/controller/rpi/agc_channel.h +++ b/src/ipa/rpi/controller/rpi/agc_channel.h @@ -44,11 +44,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;