From patchwork Fri Sep 15 12:29:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 19018 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 0132BC3260 for ; Fri, 15 Sep 2023 12:30:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 85E6C6291F; Fri, 15 Sep 2023 14:30:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694781026; bh=1Xr4pR8DrROQ0Dcl/6NOOQtbpvCaJFLJFQ45yEclGpo=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=V9XocSmdjfk9rAsKG6R7G3tA2RXi1cXQBxQoQwKdl3R0Py98YlFMKZ9QBhDf1aITe n3xJDgRp6uMCY33KtK5hPzBjd6pgMyBT7wWC2pFRDTbwtGdTf2T5p3m7zDCVxp7ozs kzqcw7U2b+afVfYR3Wo3GFR7upsBKPRr/9ahQK/BW8XLtwUZIEd/dfS06Kneav2csQ 4wT2zS2VJhcncvmQ6FjkQVjMAZszJEV+iaa+Jnor34csbYFBeraWei59eOdT4sford f60eiBJgzFjmU/omdIr+iQ4WOg6VTMF5fU3+3UHxPVaA5cFMFde+Ck7zAbnZ+ppDdA xhD/nYmcQKcMw== Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 167FF62920 for ; Fri, 15 Sep 2023 14:30:23 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="o0i1uiZH"; dkim-atps=neutral Received: by mail-wm1-x32f.google.com with SMTP id 5b1f17b1804b1-402d0eda361so23086335e9.0 for ; Fri, 15 Sep 2023 05:30:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1694781022; x=1695385822; 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=CP7uUqAsGX+5ivupZb0spXi2UflxOvBFjljPrq0s5Zs=; b=o0i1uiZHYjbvinnG7m+XIn9ciFL3icsJBkPW7bs75jpXLCpPLJHHNawLOqOyzhsBCQ nYqK4bM+kdbiKbAde83b7LY9GU10UoTaIeFBT38Q4fhWBStdx1Lv8kDRBfTfP47r7Hcx nHV5Syvx6zTJpIzjXyjJI+4l522aAZymnxFB9HvDqVpVzIjQP3rU6Asxa9+CgJKLfKt/ grVpLefP+F43aMCnn0PJW4KMJP2scEuZ7o1GTpTYLMQ36zvZs0293AelyABy/LTmIgmH 1dLO5nx2QJCdydpcJUPKetBKMR4B1Fzfy4b125Nxu5hWHUTauKqkSDY1DANQMRdmLC4G /kyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694781022; x=1695385822; 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=CP7uUqAsGX+5ivupZb0spXi2UflxOvBFjljPrq0s5Zs=; b=U8pERHJtA/IO0lnbbpzLAc00fGjoVJXT0QmSq/WGKHQnNYRYjRzPvjhwGcRB775YKT pKGhulMZxSF8Q2wzv8yMoxnLiOMHw3TWq8Tj4j/zZvsCpcr1Jr/TFNnc+ruWqA/G4mrd 2TLHyi1yS0URZ8Gvvd+GZf+0psL6mY7VcEknw1YYZdSt5doepyf316Cy9tmUexZJYOnU odX4Nu3+cjIzdJk5z7VVcmEyQdfsTqkDgKGIJp7Qb/Qeycqtny/SmZjJH7GvjbuwDxCD 7Qe2vU+l9mggPswDdwaec6s59Frk+Evl01UxG9PgNRBQO2Bcb7YPZsFbVRMlYphoiG5C n2Jg== X-Gm-Message-State: AOJu0YzaG8ghUlhNARE1QycgrnJ7k4UZj/LRkhvaGAmf9Z84WFVpt8Lr +1BuJk2Zg5soAoJj3BaYjgEtIWJ/nKtvPMhmdqE= X-Google-Smtp-Source: AGHT+IFO9ChwqJVjsIxhXffh830LwsTS5gK1fadzZUGLJrDGkufQGtZyS5y2yBouD/L8DF1KtI1QTA== X-Received: by 2002:a05:600c:21da:b0:3fe:2b8c:9f0b with SMTP id x26-20020a05600c21da00b003fe2b8c9f0bmr1318415wmj.23.1694781022274; Fri, 15 Sep 2023 05:30:22 -0700 (PDT) Received: from localhost.localdomain ([195.180.61.40]) by smtp.gmail.com with ESMTPSA id y14-20020a7bcd8e000000b004030e8ff964sm7435009wmj.34.2023.09.15.05.30.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Sep 2023 05:30:21 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Sep 2023 13:29:53 +0100 Message-Id: <20230915122954.5231-5-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230915122954.5231-1-david.plowman@raspberrypi.com> References: <20230915122954.5231-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 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 Cc: Jacopo Mondi 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 9c8d1a6f..afa06686 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 b2f554db..ceaab12f 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;