From patchwork Fri Sep 15 15:58:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 19037 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 0C138BD160 for ; Fri, 15 Sep 2023 15:58:59 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2FC1162922; Fri, 15 Sep 2023 17:58:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1694793538; bh=5PzYmMOI5wAtHa3mMKkYWwZMOkHBy0H98iLwtngsCZI=; 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=DFQsLOIpqqsFZ9/Z9bspGHH5olGi7KIwZ5vWmMT/UJ/3rGJSvj59frOkXXUGHXHmH cKBIbHIH5WFq1AS0FYiJrKxK4AimLz+rds1iemvnGHscfa/9UQ9JbzJythw8C9bslL NXNcsNcnKy5zD4eSFiAZoYLT6LeN1z8xrqMn+SYlbKG+XgQYPztmN9eUZNgh9Ox48p KvQnUavgxUQGagEoOqtffd1dug3nLS6bClVTnI6qfWDHf6hXmN5fAFxWdn3L8igsn+ SYFKntxSTMeI3bPThXc7pDidSsszxl00+eVgStqB0BSi3x57g5bMwnd5HA056ORQ18 krz0jJvbEWqWw== Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7B7AF6291C for ; Fri, 15 Sep 2023 17:58:55 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="C4KMXmcv"; dkim-atps=neutral Received: by mail-wm1-x332.google.com with SMTP id 5b1f17b1804b1-402d499580dso25007765e9.1 for ; Fri, 15 Sep 2023 08:58:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1694793535; x=1695398335; 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=L5ti10stfJGjHOx0NZCJZ7ipLRVCzaFb97PYLKAMgso=; b=C4KMXmcvDjDn1dQcfMhF5yqzECNpJoyzX4L0n116h/ZZO/Jm4X6foERnApE0OtJ+QL 1prY3OvNr9/7EdRzyXVCR3ydL2sCDcXfKIr+lh+1BTz2yd8V3IBATuFvVyp9LOgm2oT2 H6daYKS9JvD2aA+0WUl4VmDRPgiJcGrk9X/E7Nuc6UxDFe2fPjgmgOQof/wQZzGerEUH PF5qniIq6zT9Pm9nq5W5i3NDIDVuiL/QxfPPD8M0PUP35RmNm07vcnxARHc8YY/GhK1P /C0QuqW08BsN6rZniQm64HXFWfGf0zM9CnPQ2gcC2l2H4CPRDrHYNEk0MXXuasBcCZH9 9LxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694793535; x=1695398335; 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=L5ti10stfJGjHOx0NZCJZ7ipLRVCzaFb97PYLKAMgso=; b=VVKj75qVJbaOFP5z1FyJdwxYLnxEgEuq6Z+R5eWF7ywmMyK53suzVfNX/0DHUSxgjV s9qt8zYrrrnYG7Yza5nNOYtz+X0moqKGtVYvorpi4JBvPO9JxAOpRYZ79bclg2Fltk0Z Ie+ZBAQCo6+d2E9cMVXsCuDVRMv/EEM6R8hKkUMGStx7iyZv4Lv61LikcD+mPIrp/RvX uypEMJRd9J7dQkUlSHqwxkIEsaOISII3EUCKJ5x68gOfgeNk6aG3r+DLjZDhit4K/E6m vD88LkjwJMnlL4VGs+DFzK5OYCShuu9pCxiRDAIUhpBXPDzU3SCfT/QExXxC6I90N5fO AbDg== X-Gm-Message-State: AOJu0YzpPSRIxBicEGMLgHIjWeh96bc6DjgKYCWZY70eW/96NMMr3QPD CXf4iV/K7GY5tedNuQc0BfMrTMzqV/tiVknuem8= X-Google-Smtp-Source: AGHT+IGLeC++Kp1wkV7LzaDbMCZwk9g48Mhc4qdfpHUbcG5BG1LnKTbcpoymWuEpg+ofjoRc274qjg== X-Received: by 2002:a1c:7706:0:b0:401:2ee0:754a with SMTP id t6-20020a1c7706000000b004012ee0754amr2109767wmi.13.1694793534728; Fri, 15 Sep 2023 08:58:54 -0700 (PDT) Received: from localhost.localdomain ([195.180.61.40]) by smtp.gmail.com with ESMTPSA id l13-20020a7bc44d000000b00401c595fcc7sm7810618wmi.11.2023.09.15.08.58.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Sep 2023 08:58:54 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Fri, 15 Sep 2023 16:58:43 +0100 Message-Id: <20230915155844.2388-5-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230915155844.2388-1-david.plowman@raspberrypi.com> References: <20230915155844.2388-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 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 84eafe7d..dfe363ff 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;