From patchwork Wed May 3 12:20:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 18595 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 2D612C0DA4 for ; Wed, 3 May 2023 12:21:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DD33B633BC; Wed, 3 May 2023 14:21:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1683116462; bh=r8OWRW4exBKkEoNUxF9rW+e27c6/Jmh3844KlNQPoEo=; 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=xpCmzxBjJqkuhAdB4aUxcI/ia5ioeD44xbkOhTETt0diSPNurK69XJH6ecuRDymF/ T8OHui9XbGrHr3ydcyhn5C7x2ZwPJ73Tq+4JSUIQqcwzEzWQ5PNdDGgeH/P3SZBsYT bXDmwo/6bWycBLgKy/TGB/zfp8HK+3VquDuXakAn2f1HOua0jreVuo1lIluah/evvC j5RJISg73bV481SpiUBAtq7guBUYrOT0C9V/PHclqMEZEaNKJdHF7C4xya10wjHfbn PfBySb2y8fAIaSX4j2X0v8qpWL9bFVNZzF76+JfGQab6BKSkCfVYeU47SgAP+dYfBa sCXYLnc5nY+wQ== 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 954F5627DE for ; Wed, 3 May 2023 14:21:01 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="HQ+sQKKc"; dkim-atps=neutral Received: by mail-wm1-x32a.google.com with SMTP id 5b1f17b1804b1-3f19a7f9424so50264815e9.2 for ; Wed, 03 May 2023 05:21:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1683116461; x=1685708461; 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=K+6m0TmzUBQDH0KaQ5mGecYbrYCVSMAcwOdAkyRWqrM=; b=HQ+sQKKcW2e/n5CeBtb1x+gtlQZio6sCQN9GJtQ9DVOnqE3GL4dw5Vuo3c528gNSFR HfVYF/DT3rf2wd/wOQprhqIrDmpAvCLrhrW6Xl6g8hFwnxhbMD0xcEI66j+ezb86iZnL 5V8WEIQEvTTqNiGWn6YwVYPbUVxeiwu6xPGQ4hMW5Ile6eIwpWtIeu6pu92Uc3uJT+Lt 2989A8zgs+4MXvLOnThRZxUKAdBen096eJTvZ2UoKLQ/QYejdTuQaCy1Qp3D214DNCD8 p+rGfXb0GDD8wZZ/BzCcuwS4VlQkmtS8UcplnXR2/yVDTaJ5baULGX/b6SXouL4SfXWo lelQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683116461; x=1685708461; 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=K+6m0TmzUBQDH0KaQ5mGecYbrYCVSMAcwOdAkyRWqrM=; b=g9fP+1qtLaRbLuIyQOlZU/2LPv57FUE78yS2klU+1EBSF0/VoWhAHP8/0l8CipbDVL bDYxdekURNGmjzBFkFUhP1YFg4i4v/Ew2FV0mL90UBsJFfTR925+dO1OmCH9KEIRY16D FyBlS9esyof1oCm6iAZykASAN3dlvuihou2V3MXVU/07Y9HBvVB+jpBqQfGz9A4vZeoM We4BJDPRVzuhcO9NIbATcKVSaQSmre7TsVuD9te+k0pr5Xs/RpKuHzVH8C/24KfJ2esL dkDs3F1Ixpp1guqf57+CHRUbJKrElM67xiJxFkhj7skwctEnEnNvrjIgfMh5oOW0rDBD 4SOQ== X-Gm-Message-State: AC+VfDzjQs11NRBIBaMIjsFnrlO/J/gEFx+9hJ+EKv4TH6mEaHFveA0R KlVTUW8yU1M5V0JUwKnu/ba6CslGfQBvM/RGTdg2iQ== X-Google-Smtp-Source: ACHHUZ7R3Htwphvu97nPFyVpNGQQ89doJVZRhl/ibzJsDId01DcyObENuvdH9EWfWTYfgDvqgitnfg== X-Received: by 2002:a1c:f305:0:b0:3f1:93c2:4df7 with SMTP id q5-20020a1cf305000000b003f193c24df7mr14649326wmq.5.1683116460791; Wed, 03 May 2023 05:21:00 -0700 (PDT) Received: from localhost.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id f23-20020a7bcd17000000b003ee443bf0c7sm1736785wmj.16.2023.05.03.05.21.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 May 2023 05:21:00 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 3 May 2023 13:20:32 +0100 Message-Id: <20230503122035.32026-11-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230503122035.32026-1-naush@raspberrypi.com> References: <20230503122035.32026-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 10/13] ipa: raspberrypi: agc: Move weights out of AGC 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: Naushir Patuck via libcamera-devel From: Naushir Patuck Reply-To: Naushir Patuck Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: David Plowman The region weights for the the AGC zones are handled by the AGC algorithm. Apply them directly in the IPA (vc4.cpp) to the statistics that we pass to the AGC. Signed-off-by: David Plowman Signed-off-by: Naushir Patuck Reviewed-by: Jacopo Mondi --- src/ipa/rpi/controller/agc_algorithm.h | 3 +++ src/ipa/rpi/controller/rpi/agc.cpp | 27 +++++++++++++++++--------- src/ipa/rpi/controller/rpi/agc.h | 1 + src/ipa/rpi/vc4/vc4.cpp | 26 ++++++++++++++++++------- 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/ipa/rpi/controller/agc_algorithm.h b/src/ipa/rpi/controller/agc_algorithm.h index 36e6c11058ee..b6949daa7135 100644 --- a/src/ipa/rpi/controller/agc_algorithm.h +++ b/src/ipa/rpi/controller/agc_algorithm.h @@ -6,6 +6,8 @@ */ #pragma once +#include + #include #include "algorithm.h" @@ -18,6 +20,7 @@ public: AgcAlgorithm(Controller *controller) : Algorithm(controller) {} /* An AGC algorithm must provide the following: */ virtual unsigned int getConvergenceFrames() const = 0; + virtual std::vector const &getWeights() const = 0; virtual void setEv(double ev) = 0; virtual void setFlickerPeriod(libcamera::utils::Duration flickerPeriod) = 0; virtual void setFixedShutter(libcamera::utils::Duration fixedShutter) = 0; diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp index e6fb7b8dbeb3..e79c82e2e65b 100644 --- a/src/ipa/rpi/controller/rpi/agc.cpp +++ b/src/ipa/rpi/controller/rpi/agc.cpp @@ -292,6 +292,18 @@ unsigned int Agc::getConvergenceFrames() const return config_.convergenceFrames; } +std::vector const &Agc::getWeights() const +{ + /* + * In case someone calls setMeteringMode and then this before the + * algorithm has run and updated the meteringMode_ pointer. + */ + auto it = config_.meteringModes.find(meteringModeName_); + if (it == config_.meteringModes.end()) + return meteringMode_->weights; + return it->second.weights; +} + void Agc::setEv(double ev) { ev_ = ev; @@ -595,19 +607,16 @@ static double computeInitialY(StatisticsPtr &stats, AwbStatus const &awb, ASSERT(weights.size() == stats->agcRegions.numRegions()); /* - * Note how the calculation below means that equal weights give you - * "average" metering (i.e. all pixels equally important). + * Note that the weights are applied by the IPA to the statistics directly, + * before they are given to us here. */ double rSum = 0, gSum = 0, bSum = 0, pixelSum = 0; for (unsigned int i = 0; i < stats->agcRegions.numRegions(); i++) { auto ®ion = stats->agcRegions.get(i); - double rAcc = std::min(region.val.rSum * gain, (maxVal - 1) * region.counted); - double gAcc = std::min(region.val.gSum * gain, (maxVal - 1) * region.counted); - double bAcc = std::min(region.val.bSum * gain, (maxVal - 1) * region.counted); - rSum += rAcc * weights[i]; - gSum += gAcc * weights[i]; - bSum += bAcc * weights[i]; - pixelSum += region.counted * weights[i]; + rSum += std::min(region.val.rSum * gain, (maxVal - 1) * region.counted); + gSum += std::min(region.val.gSum * gain, (maxVal - 1) * region.counted); + bSum += std::min(region.val.bSum * gain, (maxVal - 1) * region.counted); + pixelSum += region.counted; } if (pixelSum == 0.0) { LOG(RPiAgc, Warning) << "computeInitialY: pixelSum is zero"; diff --git a/src/ipa/rpi/controller/rpi/agc.h b/src/ipa/rpi/controller/rpi/agc.h index 4e5f272fac78..939f97295a02 100644 --- a/src/ipa/rpi/controller/rpi/agc.h +++ b/src/ipa/rpi/controller/rpi/agc.h @@ -69,6 +69,7 @@ public: char const *name() const override; int read(const libcamera::YamlObject ¶ms) override; unsigned int getConvergenceFrames() const override; + std::vector const &getWeights() const override; void setEv(double ev) override; void setFlickerPeriod(libcamera::utils::Duration flickerPeriod) override; void setMaxShutter(libcamera::utils::Duration maxShutter) override; diff --git a/src/ipa/rpi/vc4/vc4.cpp b/src/ipa/rpi/vc4/vc4.cpp index a32db9bcaf9a..e38024ac5418 100644 --- a/src/ipa/rpi/vc4/vc4.cpp +++ b/src/ipa/rpi/vc4/vc4.cpp @@ -211,13 +211,25 @@ RPiController::StatisticsPtr IpaVc4::platformProcessStats(Span mem) stats->awb_stats[i].counted, stats->awb_stats[i].notcounted }); - statistics->agcRegions.init(hw.agcRegions); - for (i = 0; i < statistics->agcRegions.numRegions(); i++) - statistics->agcRegions.set(i, { { stats->agc_stats[i].r_sum << scale, - stats->agc_stats[i].g_sum << scale, - stats->agc_stats[i].b_sum << scale }, - stats->agc_stats[i].counted, - stats->awb_stats[i].notcounted }); + RPiController::AgcAlgorithm *agc = dynamic_cast( + controller_.getAlgorithm("agc")); + if (!agc) { + LOG(IPARPI, Debug) << "No AGC algorithm - not copying statistics"; + statistics->agcRegions.init(0); + } else { + statistics->agcRegions.init(hw.agcRegions); + const std::vector &weights = agc->getWeights(); + for (i = 0; i < statistics->agcRegions.numRegions(); i++) { + uint64_t rSum = (stats->agc_stats[i].r_sum << scale) * weights[i]; + uint64_t gSum = (stats->agc_stats[i].g_sum << scale) * weights[i]; + uint64_t bSum = (stats->agc_stats[i].b_sum << scale) * weights[i]; + uint32_t counted = stats->agc_stats[i].counted * weights[i]; + uint32_t notcounted = stats->agc_stats[i].notcounted * weights[i]; + statistics->agcRegions.set(i, { { rSum, gSum, bSum }, + counted, + notcounted }); + } + } statistics->focusRegions.init(hw.focusRegions); for (i = 0; i < statistics->focusRegions.numRegions(); i++)