From patchwork Fri Oct 20 08:39:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 19162 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 45A4FC3275 for ; Fri, 20 Oct 2023 08:40:32 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7405F62988; Fri, 20 Oct 2023 10:40:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1697791231; bh=jPOOtFeFO691t5CANdGRuf0v9dP+awElgPtevT6dTLs=; 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=XEuOy5Og5dXhYH+P5lLiu6UBtLcxx547vuVL0/AvvPFHxd5RuwR/vV9p/jXqHeA8J ewiaBazvujVAO/rRmJ/op4CLW1Jv0cPLQJ/hLhBmYfRHN0lehmzGBjPxggBCKz2UHO NKCglhgwOADt9ONJzJzq0HkZpA4kuC9WKJpQzpTwTlKQMV44rPA3sSRbugBdPACbC8 Fe9/RIH/QR71KNW4Ik+0c3eRyWHPvWGE9NCemwTEDFQ25XP0ZwS4mlDOxXcGTlctjG DUqDivKR+wBskr/SkrjOxdopZuYRKaqv9/TcbofYoFmP+Y1xDL7KvnwgpH/Dd4bT+P Toon8RQVVG18g== Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9875661DCF for ; Fri, 20 Oct 2023 10:40:28 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="V+ysmBJ1"; dkim-atps=neutral Received: by mail-wr1-x433.google.com with SMTP id ffacd0b85a97d-32d9d8284abso388544f8f.3 for ; Fri, 20 Oct 2023 01:40:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1697791228; x=1698396028; 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=JXyzeKU2fDyJlg0dlNuph+ANleEJ18H6lcHHs7yn1j4=; b=V+ysmBJ1DOTZZhp+2gLJN+mADKl970Ct4HKhvmv+DhkPX+xBOStf50vh/t49SivyJk 1GFa1M0Y0oijaA4oDQMMUE3hCixlZMVu3XtcH+mu8rqE55rxC0mX0KDZl7VNmARwEQf2 kRsy2hTJTtNaKplLQCRFco/x8WHy/LkxvVOpzqE2CYuWaAjTlL/uhHVJ9yoFp0+GgIcI 6SE4dSG7M49+xFn1ZIVkHjd2WxIHTCsyTQAWUtJ64vF39TQqa4KvtRRmQ6+ebtZmXI2p L4UdDzm6QxkUSNNINGWaXthSLV4GxqmPdRDM+zpYH8Ka1HAKRfr8g15ug1+nDm3Xyy7W zwSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697791228; x=1698396028; 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=JXyzeKU2fDyJlg0dlNuph+ANleEJ18H6lcHHs7yn1j4=; b=GClJ30D0ErRzs34JRJ/ux34JgNmxCtv58G2PmyIBjM4MAyuma7mXjKkeC40SYAL6I8 iYHj3Fg/A48n+/IQN0dm79tg61gcW4+ifdPq88EAYXI9JT0p7EmjiVdptnjVzUP77KlC uypif38MF4DFuchG1dCQxrNei4etrc6/HkQOSh3y+3jLb+jeI/hBCz8OgkxgEgeLDBuY KeyrJfr8rTrVM4nJQJtfkZGQLKYM9uQ/hwP/J5a6upW9lcsw4/XoZ3tWq5Fsi0O8cazm iMXUGL+T4lhxQ+BpEtnYoL58WDge5nJeP+og6AXoVG32lNZ2j2RKEkYzg1SLcgmMPHR9 kXEQ== X-Gm-Message-State: AOJu0YzleJL6/jK+OTfFKnTSNfyrnMorP03bfQWbzOJAKb7watx3JIIq SAVuM9urKimLX6Ud7HHe6gvvA+nv0pozgCZuWyYp5g== X-Google-Smtp-Source: AGHT+IHCAVP+v9NPOR4auDwEdNZYhAFWUASh4PYV5WxciGJ7mCE7WU10CwGYv4X+Q2loYZaLCJCUQg== X-Received: by 2002:a5d:5267:0:b0:31f:f65f:74ac with SMTP id l7-20020a5d5267000000b0031ff65f74acmr953790wrc.70.1697791227858; Fri, 20 Oct 2023 01:40:27 -0700 (PDT) Received: from localhost.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id r3-20020adff103000000b0032d9337e7d1sm1213356wro.11.2023.10.20.01.40.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 01:40:27 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Fri, 20 Oct 2023 09:39:57 +0100 Message-Id: <20231020084002.30665-2-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231020084002.30665-1-naush@raspberrypi.com> References: <20231020084002.30665-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 1/6] ipa: rpi: hdr: Add the ability to alter the LSC table 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 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: David Plowman We can perform some of the local contrast adjustment using global gains in the LSC table. We can vary the amount of gain according to the measured brightness of that image region. Signed-off-by: David Plowman Reviewed-by: Naushir Patuck --- src/ipa/rpi/controller/rpi/hdr.cpp | 183 ++++++++++++++++++++--------- src/ipa/rpi/controller/rpi/hdr.h | 18 +-- 2 files changed, 136 insertions(+), 65 deletions(-) diff --git a/src/ipa/rpi/controller/rpi/hdr.cpp b/src/ipa/rpi/controller/rpi/hdr.cpp index 295e4c5f1c0a..fb580548d068 100644 --- a/src/ipa/rpi/controller/rpi/hdr.cpp +++ b/src/ipa/rpi/controller/rpi/hdr.cpp @@ -10,6 +10,7 @@ #include #include "../agc_status.h" +#include "../alsc_status.h" #include "../stitch_status.h" #include "../tonemap_status.h" @@ -37,29 +38,26 @@ void HdrConfig::read(const libcamera::YamlObject ¶ms, const std::string &mod for (const auto &[k, v] : params["channel_map"].asDict()) channelMap[v.get().value()] = k; + /* Lens shading related parameters. */ + if (params.contains("spatial_gain")) { + spatialGain.read(params["spatial_gain"]); + diffusion = params["diffusion"].get(3); + /* Clip to an arbitrary limit just to stop typos from killing the system! */ + const unsigned int MAX_DIFFUSION = 15; + if (diffusion > MAX_DIFFUSION) { + diffusion = MAX_DIFFUSION; + LOG(RPiHdr, Warning) << "Diffusion value clipped to " << MAX_DIFFUSION; + } + } + /* Read any tonemap parameters. */ tonemapEnable = params["tonemap_enable"].get(0); detailConstant = params["detail_constant"].get(50); detailSlope = params["detail_slope"].get(8.0); iirStrength = params["iir_strength"].get(8.0); strength = params["strength"].get(1.5); - - if (tonemapEnable) { - /* We need either an explicit tonemap, or the information to build them dynamically. */ - if (params.contains("tonemap")) { - if (tonemap.read(params["tonemap"])) - LOG(RPiHdr, Fatal) << "Failed to read tonemap in HDR mode " << name; - } else { - if (target.read(params["target"])) - LOG(RPiHdr, Fatal) << "Failed to read target in HDR mode " << name; - if (maxSlope.read(params["max_slope"])) - LOG(RPiHdr, Fatal) << "Failed to read max_slope in HDR mode " << name; - minSlope = params["min_slope"].get(1.0); - maxGain = params["max_gain"].get(64.0); - step = params["step"].get(0.05); - speed = params["speed"].get(0.5); - } - } + if (tonemapEnable) + tonemap.read(params["tonemap"]); /* Read any stitch parameters. */ stitchEnable = params["stitch_enable"].get(0); @@ -73,6 +71,10 @@ void HdrConfig::read(const libcamera::YamlObject ¶ms, const std::string &mod Hdr::Hdr(Controller *controller) : HdrAlgorithm(controller) { + regions_ = controller->getHardwareConfig().awbRegions; + numRegions_ = regions_.width * regions_.height; + gains_[0].resize(numRegions_, 1.0); + gains_[1].resize(numRegions_, 1.0); } char const *Hdr::name() const @@ -143,7 +145,40 @@ void Hdr::switchMode([[maybe_unused]] CameraMode const &cameraMode, Metadata *me delayedStatus_ = status_; } -bool Hdr::updateTonemap(StatisticsPtr &stats, HdrConfig &config) +void Hdr::prepare(Metadata *imageMetadata) +{ + AgcStatus agcStatus; + if (!imageMetadata->get("agc.delayed_status", agcStatus)) + delayedStatus_ = agcStatus.hdr; + + auto it = config_.find(delayedStatus_.mode); + if (it == config_.end()) { + /* Shouldn't be possible. There would be nothing we could do. */ + LOG(RPiHdr, Warning) << "Unexpected HDR mode " << delayedStatus_.mode; + return; + } + + HdrConfig &config = it->second; + if (config.spatialGain.empty()) + return; + + AlscStatus alscStatus{}; /* some compilers seem to require the braces */ + if (imageMetadata->get("alsc.status", alscStatus)) { + LOG(RPiHdr, Warning) << "No ALSC status"; + return; + } + + /* The final gains ended up in the odd or even array, according to diffusion. */ + std::vector &gains = gains_[config.diffusion & 1]; + for (unsigned int i = 0; i < numRegions_; i++) { + alscStatus.r[i] *= gains[i]; + alscStatus.g[i] *= gains[i]; + alscStatus.b[i] *= gains[i]; + } + imageMetadata->set("alsc.status", alscStatus); +} + +bool Hdr::updateTonemap([[maybe_unused]] StatisticsPtr &stats, HdrConfig &config) { /* When there's a change of HDR mode we start over with a new tonemap curve. */ if (delayedStatus_.mode != previousMode_) { @@ -162,56 +197,85 @@ bool Hdr::updateTonemap(StatisticsPtr &stats, HdrConfig &config) } /* - * We only update the tonemap on short frames when in multi-exposure mode. But + * We wouldn't update the tonemap on short frames when in multi-exposure mode. But * we still need to output the most recent tonemap. Possibly we should make the * config indicate the channels for which we should update the tonemap? */ if (delayedStatus_.mode == "MultiExposure" && delayedStatus_.channel != "short") return true; - /* Build the tonemap dynamically using the image histogram. */ - Pwl tonemap; - tonemap.append(0, 0); - - double prev_input_val = 0; - double prev_output_val = 0; - const double step2 = config.step / 2; - for (double q = config.step; q < 1.0 - step2; q += config.step) { - double q_lo = std::max(0.0, q - step2); - double q_hi = std::min(1.0, q + step2); - double iqm = stats->yHist.interQuantileMean(q_lo, q_hi); - double input_val = std::min(iqm * 64, 65535.0); - - if (input_val > prev_input_val + 1) { - /* We're going to calcualte a Pwl to map input_val to this output_val. */ - double want_output_val = config.target.eval(q) * 65535; - /* But we must ensure we aren't applying too small or too great a local gain. */ - double want_slope = (want_output_val - prev_output_val) / (input_val - prev_input_val); - double slope = std::clamp(want_slope, config.minSlope, - config.maxSlope.eval(q)); - double output_val = prev_output_val + slope * (input_val - prev_input_val); - output_val = std::min(output_val, config.maxGain * input_val); - output_val = std::clamp(output_val, 0.0, 65535.0); - /* Let the tonemap adapte slightly more gently from frame to frame. */ - if (!tonemap_.empty()) { - double old_output_val = tonemap_.eval(input_val); - output_val = config.speed * output_val + - (1 - config.speed) * old_output_val; - } - LOG(RPiHdr, Debug) << "q " << q << " input " << input_val - << " output " << want_output_val << " slope " << want_slope - << " slope " << slope << " output " << output_val; - tonemap.append(input_val, output_val); - prev_input_val = input_val; - prev_output_val = output_val; + /* + * If we wanted to build or adjust tonemaps dynamically, this would be the place + * to do it. But for now we seem to be getting by without. + */ + + return true; +} + +static void averageGains(std::vector &src, std::vector &dst, const Size &size) +{ +#define IDX(y, x) ((y)*size.width + (x)) + unsigned int lastCol = size.width - 1; /* index of last column */ + unsigned int preLastCol = lastCol - 1; /* and the column before that */ + unsigned int lastRow = size.height - 1; /* index of last row */ + unsigned int preLastRow = lastRow - 1; /* and the row before that */ + + /* Corners first. */ + dst[IDX(0, 0)] = (src[IDX(0, 0)] + src[IDX(0, 1)] + src[IDX(1, 0)]) / 3; + dst[IDX(0, lastCol)] = (src[IDX(0, lastCol)] + src[IDX(0, preLastCol)] + src[IDX(1, lastCol)]) / 3; + dst[IDX(lastRow, 0)] = (src[IDX(lastRow, 0)] + src[IDX(lastRow, 1)] + src[IDX(preLastRow, 0)]) / 3; + dst[IDX(lastRow, lastCol)] = (src[IDX(lastRow, lastCol)] + src[IDX(lastRow, preLastCol)] + + src[IDX(preLastRow, lastCol)]) / + 3; + + /* Now the edges. */ + for (unsigned int i = 1; i < lastCol; i++) { + dst[IDX(0, i)] = (src[IDX(0, i - 1)] + src[IDX(0, i)] + src[IDX(0, i + 1)] + src[IDX(1, i)]) / 4; + dst[IDX(lastRow, i)] = (src[IDX(lastRow, i - 1)] + src[IDX(lastRow, i)] + + src[IDX(lastRow, i + 1)] + src[IDX(preLastRow, i)]) / + 4; + } + + for (unsigned int i = 1; i < lastRow; i++) { + dst[IDX(i, 0)] = (src[IDX(i - 1, 0)] + src[IDX(i, 0)] + src[IDX(i + 1, 0)] + src[IDX(i, 1)]) / 4; + dst[IDX(i, 31)] = (src[IDX(i - 1, lastCol)] + src[IDX(i, lastCol)] + + src[IDX(i + 1, lastCol)] + src[IDX(i, preLastCol)]) / + 4; + } + + /* Finally the interior. */ + for (unsigned int j = 1; j < lastRow; j++) { + for (unsigned int i = 1; i < lastCol; i++) { + dst[IDX(j, i)] = (src[IDX(j - 1, i)] + src[IDX(j, i - 1)] + src[IDX(j, i)] + + src[IDX(j, i + 1)] + src[IDX(j + 1, i)]) / + 5; } } +} - tonemap.append(65535, 65535); - /* tonemap.debug(); */ - tonemap_ = tonemap; +void Hdr::updateGains(StatisticsPtr &stats, HdrConfig &config) +{ + if (config.spatialGain.empty()) + return; - return true; + /* When alternating exposures, only compute these gains for the short frame. */ + if (delayedStatus_.mode == "MultiExposure" && delayedStatus_.channel != "short") + return; + + for (unsigned int i = 0; i < numRegions_; i++) { + auto ®ion = stats->awbRegions.get(i); + unsigned int counted = region.counted; + counted += (counted == 0); /* avoid div by zero */ + double r = region.val.rSum / counted; + double g = region.val.gSum / counted; + double b = region.val.bSum / counted; + double brightness = std::max({ r, g, b }) / 65535; + gains_[0][i] = config.spatialGain.eval(brightness); + } + + /* Ping-pong between the two gains_ buffers. */ + for (unsigned int i = 0; i < config.diffusion; i++) + averageGains(gains_[i & 1], gains_[(i & 1) ^ 1], regions_); } void Hdr::process(StatisticsPtr &stats, Metadata *imageMetadata) @@ -237,6 +301,9 @@ void Hdr::process(StatisticsPtr &stats, Metadata *imageMetadata) HdrConfig &config = it->second; + /* Update the spatially varying gains. They get written in prepare(). */ + updateGains(stats, config); + if (updateTonemap(stats, config)) { /* Add tonemap.status metadata. */ TonemapStatus tonemapStatus; diff --git a/src/ipa/rpi/controller/rpi/hdr.h b/src/ipa/rpi/controller/rpi/hdr.h index 01ba45f1d3dc..980aa3d1850d 100644 --- a/src/ipa/rpi/controller/rpi/hdr.h +++ b/src/ipa/rpi/controller/rpi/hdr.h @@ -10,6 +10,8 @@ #include #include +#include + #include "../hdr_algorithm.h" #include "../hdr_status.h" #include "../pwl.h" @@ -23,20 +25,17 @@ struct HdrConfig { std::vector cadence; std::map channelMap; + /* Lens shading related parameters. */ + Pwl spatialGain; /* Brightness to gain curve for different image regions. */ + unsigned int diffusion; /* How much to diffuse the gain spatially. */ + /* Tonemap related parameters. */ bool tonemapEnable; uint16_t detailConstant; double detailSlope; double iirStrength; double strength; - /* We must have either an explicit tonemap curve, or the other parameters. */ Pwl tonemap; - Pwl target; /* maps histogram quatile to desired target output value */ - Pwl maxSlope; /* the maximum slope allowed at each point in the mapping */ - double minSlope; /* the minimum allowed slope */ - double maxGain; /* limit to the max absolute gain */ - double step; /* the histogram granularity for building the mapping */ - double speed; /* rate at which tonemap is updated */ /* Stitch related parameters. */ bool stitchEnable; @@ -54,12 +53,14 @@ public: char const *name() const override; void switchMode(CameraMode const &cameraMode, Metadata *metadata) override; int read(const libcamera::YamlObject ¶ms) override; + void prepare(Metadata *imageMetadata) override; void process(StatisticsPtr &stats, Metadata *imageMetadata) override; int setMode(std::string const &mode) override; std::vector getChannels() const override; private: void updateAgcStatus(Metadata *metadata); + void updateGains(StatisticsPtr &stats, HdrConfig &config); bool updateTonemap(StatisticsPtr &stats, HdrConfig &config); std::map config_; @@ -67,6 +68,9 @@ private: HdrStatus delayedStatus_; /* track the delayed HDR mode and channel */ std::string previousMode_; Pwl tonemap_; + libcamera::Size regions_; /* stats regions */ + unsigned int numRegions_; /* total number of stats regions */ + std::vector gains_[2]; }; } /* namespace RPiController */ From patchwork Fri Oct 20 08:39:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 19163 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 9C4E1C3272 for ; Fri, 20 Oct 2023 08:40:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 33FF062984; Fri, 20 Oct 2023 10:40:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1697791232; bh=hyrcppkQ/aLO8GrgZTPwyUsByDlFOAsouuRaaeZJT+w=; 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=CycwwHNirE9AuTtU6HBmolrruVpdOv+sDHxQbXKJT9k7u0DDOfx4bJEe+8sNj334F Ry3q3TTq2fO0INQYKpMKsZbMqzyYsc9QEfN8pGc2CNnIYOwrJGvJu623M9/qV2R8Kr Vpn8gvnmKtQLhGuX+gB3zZFqegWyp3NcSlVHnauaTB3XgZx1lYp2OiedOcvgybX8ST NPOhVDqXugZ5kAuz2rKZnVvRZUv5cy3rYc+3wO5ftiddj+/GoaGUODVHSDGweFBDqb e5LMJ0by19LyyyQ/icTRPzNtD8rHgQIANpg/d/KnZ37q/384RZGKBwt+AusZRIJAm6 s2t6BFyB2PVig== Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 457F961DCF for ; Fri, 20 Oct 2023 10:40:29 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="shik20/7"; dkim-atps=neutral Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-408382da7f0so4642275e9.0 for ; Fri, 20 Oct 2023 01:40:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1697791228; x=1698396028; 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=XphytegKuvdJqBcBAhm4YNfDa2jw6aybWVFS0aOqByI=; b=shik20/7xFw/ZnuJXnGYANJgcS8Y04EST2y5yRnEXILyrlG+x50EvyMiQdoZaLkAJn rLohkvmpcQ26HoixjwRZu8QkSdNDzs5R6+q9MF+PTjrUzlrpFY62DFbMMhuOSacpQvLw BVhTqqQczG0TngSUIS6WRALai5X9FMUZBq8L0s/kPoPddvpyfUa8XD96di8dmBTAUToI 8sEUU4b9xb4crdBTqPIWY0tywIsdRn20li2mculnNKon0TXZWGzyDH2JF7lxapcsUhvx PI44FXkbJBP5fgd+MYnJxgbHXh8TItWuSkWOXRmCCrywkueQCrsnXmdKWkN7HIFgyCEC P3nA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697791228; x=1698396028; 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=XphytegKuvdJqBcBAhm4YNfDa2jw6aybWVFS0aOqByI=; b=EwA++qncni3nt79azexmMAgu+jZZu06WrcJMGvk1QMI+6wqEXpIgGkHhiix3qZQ4Ni /SO6hM9Pyq3hqq1L1eeiTbfeekERZ/OQeMkDOrK1wC551FOTWdR03QUuw5TjeJB4Ah6+ eIJk4jpUqvlM9lPQVuvFrq9c6ly8GFexu8IOTAKT6I1voO0sF6VWiIQDB0UC2pyVw3gd MSszeVSUAZxbawUU1LJXB9u0xNf0OPfEFFunmh48/09s/onFHrrWIpTJPz9sk7X0YDpY TYac3BxST7bwSMyDV3VAbF2CDkFdDI1q/5O7n2Oo80qEDiIx2WnsVun4JLkzsySBuCI1 fAPA== X-Gm-Message-State: AOJu0YxvnRG0Zm3Q4fwAr+I6xedGvA+tu62ESPHfSuRNDExqmbNTVPcu GP8/HMfaft0h+N8dFIEHHbrr4karfAuOVTji1h5M+w== X-Google-Smtp-Source: AGHT+IHXSRqUlzdTvS53QtTxpvTpAbOZIQAxc2coYpUh2KUHH5n+9YZNFU3nSheEHC1UMfCslUSNkg== X-Received: by 2002:a05:600c:4747:b0:408:2b:3ae with SMTP id w7-20020a05600c474700b00408002b03aemr868043wmo.6.1697791228433; Fri, 20 Oct 2023 01:40:28 -0700 (PDT) Received: from localhost.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id r3-20020adff103000000b0032d9337e7d1sm1213356wro.11.2023.10.20.01.40.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 01:40:28 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Fri, 20 Oct 2023 09:39:58 +0100 Message-Id: <20231020084002.30665-3-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231020084002.30665-1-naush@raspberrypi.com> References: <20231020084002.30665-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 2/6] ipa: rpi: alsc: Do not re-read the alsc.status metadata 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 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: David Plowman This was being re-read in order to determine what LSC gains had been applied. We can just retrieve these numbers from the prevAsyncResults_ instead. This will also enable other future algorithms to manipulate the LSC tables in the alsc.status, without it breaking the core ALSC algorithm here. Signed-off-by: David Plowman Reviewed-by: Naushir Patuck --- src/ipa/rpi/controller/rpi/alsc.cpp | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/ipa/rpi/controller/rpi/alsc.cpp b/src/ipa/rpi/controller/rpi/alsc.cpp index f1ccef87c70c..b7413611cdae 100644 --- a/src/ipa/rpi/controller/rpi/alsc.cpp +++ b/src/ipa/rpi/controller/rpi/alsc.cpp @@ -338,14 +338,14 @@ double getCt(Metadata *metadata, double defaultCt) } static void copyStats(RgbyRegions ®ions, StatisticsPtr &stats, - AlscStatus const &status) + std::array, 3> &prevSyncResults) { if (!regions.numRegions()) regions.init(stats->awbRegions.size()); - const std::vector &rTable = status.r; - const std::vector &gTable = status.g; - const std::vector &bTable = status.b; + const std::vector &rTable = prevSyncResults[0].data(); //status.r; + const std::vector &gTable = prevSyncResults[1].data(); //status.g; + const std::vector &bTable = prevSyncResults[2].data(); //status.b; for (unsigned int i = 0; i < stats->awbRegions.numRegions(); i++) { auto r = stats->awbRegions.get(i); if (stats->colourStatsPos == Statistics::ColourStatsPos::PostLsc) { @@ -367,18 +367,10 @@ void Alsc::restartAsync(StatisticsPtr &stats, Metadata *imageMetadata) ct_ = getCt(imageMetadata, ct_); /* * We have to copy the statistics here, dividing out our best guess of - * the LSC table that the pipeline applied to them. + * the LSC table that the pipeline applied to them which we get from + * prevSyncResults_. */ - AlscStatus alscStatus; - if (stats->colourStatsPos == Statistics::ColourStatsPos::PostLsc && - imageMetadata->get("alsc.status", alscStatus) != 0) { - LOG(RPiAlsc, Warning) - << "No ALSC status found for applied gains!"; - alscStatus.r.resize(config_.tableSize.width * config_.tableSize.height, 1.0); - alscStatus.g.resize(config_.tableSize.width * config_.tableSize.height, 1.0); - alscStatus.b.resize(config_.tableSize.width * config_.tableSize.height, 1.0); - } - copyStats(statistics_, stats, alscStatus); + copyStats(statistics_, stats, prevSyncResults_); framePhase_ = 0; asyncStarted_ = true; { From patchwork Fri Oct 20 08:39:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 19164 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 AC460C32B6 for ; Fri, 20 Oct 2023 08:40:34 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BCA9762987; Fri, 20 Oct 2023 10:40:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1697791232; bh=O4EfPYpoC00m4LTRVzGgk9BD6iEN24IqpLUu8p8OkxY=; 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=xN53IYytQYZ4xUH8ikmz8UkBedqWG4lcjZdPGmPAC2y6gp6FWh+13+WL8+//ewqyu ZSQuGKgr1GjIk0JM52mG+1y3noMv6K8DOH4j0+M+D6T4mghKRVHlKpqeAQ36wWj2f0 OO3A1UZcWyjifP6WrII9qEFwlZU6pmzmcZ46KGTfhkVLtYjOgey2nH4DeFA8SrGzeR gf2KjMpFgQRDPIbXlh4LBu5EWWci/+CfpGjKAVpBYTWPC2xl5uKquZbpynxVO7ZfGw B/PAfDzaeptDJeDpVfpnMEDAGuSE3azushlkMid7oL6iNq5Z66DiC28l8cUX0djac1 3sdcd5LzcOxXQ== Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id ECF7D62984 for ; Fri, 20 Oct 2023 10:40:29 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="Gu+RZyUP"; dkim-atps=neutral Received: by mail-wr1-x432.google.com with SMTP id ffacd0b85a97d-32dbbf3c782so992820f8f.1 for ; Fri, 20 Oct 2023 01:40:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1697791229; x=1698396029; 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=Q4kaeNRdLIkQc2M7j/gKLsUZmKM45BzBHk+4nObYgw8=; b=Gu+RZyUPk4ANqoOFkzWA3PveDthywZerhOT07j/BHuKYcuVTjHBTNhRZlmUFGQZB1v +NqGgQP2yH7vEbTCAimqfBOrtPP0MCwl/L5oJYadNeWYhiRixxb/92hnHyWskuMy1p5M tvYUCpRlW/+jEvxbLdZVfo8Q+lLzPWX2WCEmyzrIjpzYG37HUPx1Qh5Vu6plDQtY8EY/ EvFfjuPleyWOHh/+5PkZnCJqyDeCgZBCQbmy0afgqy1l/hZsLF91j+WfpW0uPfnd3Ubm hPWGFX59XZiY5E4VzcdprVk4e9rPW//AyPyOt4HCLwCpmh/tltBgJfIoGMZ1tl6EAAXb A9Ow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697791229; x=1698396029; 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=Q4kaeNRdLIkQc2M7j/gKLsUZmKM45BzBHk+4nObYgw8=; b=iykpwBGSCT1qVffIBaSKwlM3qrE3T10qTil+hiwPJxUEBfR2Io9vAe53vOFZdg3rqR ifPu3SfP+EPWLXW6lJADO37JRdAbafMVPFj2tEskq+bD1rGGXin+eCtAhPLceoEWGOFr +V/A7SSCyPGve3DOQNg9pG0DOqAF7ahxgxPUzCRsARpREtlKHj7DPYX/VV1cg7yQEcDq m1R0lyI7rMTWCfTrxusd/26La7Z8jdgYV0CM0JrD6VdVYZg5hpTC3bQ9SkekH59dUXrS uAtMt8sbbAB/b9p8YDPpccI+nqrX91i5FdgL6+slGz8TaOno3q7xQ0UF+sAWyYO8fgkb d8oA== X-Gm-Message-State: AOJu0YxmnKBsJheH2qvXn2P5Oh9JRdsFXZGDSuHk9NN03kGpE5jtvoM2 YeWQkskbGRKFx1ohwcVBWb0QcWUmPTxKWfJkkKTtkw== X-Google-Smtp-Source: AGHT+IEd0EofWbyecqtYAN7ea7OjImBfMEXKE/z25K8Toj8u+pgb7DTHIrQDup9AcWrX1kQGi4ClbA== X-Received: by 2002:adf:ec49:0:b0:32d:c705:3e5 with SMTP id w9-20020adfec49000000b0032dc70503e5mr3909683wrn.15.1697791229046; Fri, 20 Oct 2023 01:40:29 -0700 (PDT) Received: from localhost.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id r3-20020adff103000000b0032d9337e7d1sm1213356wro.11.2023.10.20.01.40.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 01:40:28 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Fri, 20 Oct 2023 09:39:59 +0100 Message-Id: <20231020084002.30665-4-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231020084002.30665-1-naush@raspberrypi.com> References: <20231020084002.30665-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 3/6] ipa: rpi: agc: Allow AGC channels to avoid using "fast desaturation" 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 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: David Plowman "Fast desaturation" is a technique that can help the AGC algorithm to desaturate images more quickly when they are very over-exposed. However, it uses digital gain to do this which can confuse our HDR techniques. Therefore make it optional. Signed-off-by: David Plowman Reviewed-by: Naushir Patuck --- src/ipa/rpi/controller/rpi/agc_channel.cpp | 8 ++++++-- src/ipa/rpi/controller/rpi/agc_channel.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp index 1e7eae06d425..3efb6482b67f 100644 --- a/src/ipa/rpi/controller/rpi/agc_channel.cpp +++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp @@ -253,6 +253,8 @@ int AgcConfig::read(const libcamera::YamlObject ¶ms) stableRegion = params["stable_region"].get(0.02); + desaturate = params["desaturate"].get(1); + return 0; } @@ -860,8 +862,10 @@ bool AgcChannel::applyDigitalGain(double gain, double targetY, bool channelBound * quickly (and we then approach the correct value more quickly from * below). */ - bool desaturate = !channelBound && - targetY > config_.fastReduceThreshold && gain < sqrt(targetY); + bool desaturate = false; + if (config_.desaturate) + desaturate = !channelBound && + targetY > config_.fastReduceThreshold && gain < sqrt(targetY); if (desaturate) dg /= config_.fastReduceThreshold; LOG(RPiAgc, Debug) << "Digital gain " << dg << " desaturate? " << desaturate; diff --git a/src/ipa/rpi/controller/rpi/agc_channel.h b/src/ipa/rpi/controller/rpi/agc_channel.h index c1808422498a..4cf7233eef25 100644 --- a/src/ipa/rpi/controller/rpi/agc_channel.h +++ b/src/ipa/rpi/controller/rpi/agc_channel.h @@ -76,6 +76,7 @@ struct AgcConfig { libcamera::utils::Duration defaultExposureTime; double defaultAnalogueGain; double stableRegion; + bool desaturate; }; class AgcChannel From patchwork Fri Oct 20 08:40:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 19165 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 2E940C32B7 for ; Fri, 20 Oct 2023 08:40:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A5A1862989; Fri, 20 Oct 2023 10:40:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1697791233; bh=TtHxFJeL4MD/PFY+wPrML5jb4cdVF6jM6t7lvNU07D0=; 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=wBjtl3lZYpqkKEmz+sJ6w9pYyaz6D9gWkGnpKqFIbRvYUplmNHaFbgt0w+17Dtume h4Un9TYVdR4awdT523HMoTB4wvLpir7M0CEZXGb8awU4A7eKiVyU/70cwOiUp7jN/h /c3+tRjn9Gw9CSSd+SoJOQzeq4bpO1IuzaQxDgXY4/hhMMn9Kme7Zhkgl+f2KyVKSX WEGGfb3jjHP0yTIqucIrl5/8QyIskcwEnTlBbIQoGnXpPU9yjY/ivbFIEUoDquwoBp SCT9JnpOKYR5mr6aFAmpawDvmX8MaUh8Z16HDEtVKjJ+Z9BiY9p5aBjhQMNAnmjAYP vYCZg8WkVhlqw== Received: from mail-wm1-x32b.google.com (mail-wm1-x32b.google.com [IPv6:2a00:1450:4864:20::32b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 331BA62985 for ; Fri, 20 Oct 2023 10:40:30 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="T/iEajda"; dkim-atps=neutral Received: by mail-wm1-x32b.google.com with SMTP id 5b1f17b1804b1-4084b0223ccso4282825e9.2 for ; Fri, 20 Oct 2023 01:40:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1697791229; x=1698396029; 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=THs8OugOrZxgqGgWsO6DaNgV0gChhONcOouxjenHTMQ=; b=T/iEajdaqTzyBeyA9tMXDP+rEw8MCini12gLUFKe27gsVXSxihqrC//hhUTkanIzEz HItoiwi4IF1mSuzeBrg7Y5QB/zoqD9PnEDcjYfCQ8HzwgNvrPSy9r3Xq2XdWZzojwgob L7gW/BLMgtRKREaYaYI+0fR1BjGeXHvWfDCW6ixpo76nv9MY/6ekEODlgbVcuyRIKPHf 3srxAZdFliGpBdTqtST5RdYgBmz8Z8v1ppA9eCnrt4iYCF6OoPRWodv3JTNwoo+478Pn 1WNjFbcCbzGoc81Xg0UEKXHgGEtZeb0Z7B7Tyb6LWRWPZiXTK6OY12nogLN2qW4Vr7jv R63w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697791229; x=1698396029; 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=THs8OugOrZxgqGgWsO6DaNgV0gChhONcOouxjenHTMQ=; b=pUxy6+ilYEmw6yu9tzM+KOowXAx042hd6y/p3liAfeK+7cfrNAZf+uKi766SVJX6Zu dFXRzImtMUD1x/c/wYcx0nh8r2LPgM0TnTXfaq6zppY/37Xamu14VK2ScQv1igPJ4Wqv utmaqLy5G83XYYtKKYqX0B8rj0h/KPOldR6WQG+/ixU2C+NlG8rtMLHk9I9LNpUeCfg/ CBYoqPtxZ6eALq2e9Wm54f/WgYR/YD3XMpBpGU1CZnG81kcAa7LBJlpabkzSpJhHGaOq Vjz+HSBX5OeH+Oe6Owoazgwxd6DWar/vnmF9rkdyM0Tuq2yMO2nnSnURoYgfklmBzkwY gCEw== X-Gm-Message-State: AOJu0YxRIj9gYbiAdPN0pfne2ttSi6PhlPnsVXSEXwjvUBvliZmfd2TC ryw3R2CGALOBwLl12dt8RRtdzARaji+p5GvV3XEGdQ== X-Google-Smtp-Source: AGHT+IFdd25n/bnE8tmforA6yc2GQNZxcxT9JONvW9CTWo5Dmaekh4YiGPFJ+3dUsFWg0RwJlddLuw== X-Received: by 2002:a05:600c:1910:b0:401:b2c7:34a8 with SMTP id j16-20020a05600c191000b00401b2c734a8mr986585wmq.7.1697791229602; Fri, 20 Oct 2023 01:40:29 -0700 (PDT) Received: from localhost.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id r3-20020adff103000000b0032d9337e7d1sm1213356wro.11.2023.10.20.01.40.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 01:40:29 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Fri, 20 Oct 2023 09:40:00 +0100 Message-Id: <20231020084002.30665-5-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231020084002.30665-1-naush@raspberrypi.com> References: <20231020084002.30665-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 4/6] ipa: rpi: vc4: Move denoise control handling into the VC4 derived IPA 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 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Since noise control handling differs between the VC4 and PiSP IPAs, move the current denoise control handler from ipa base into the vc4 IPA derived class. Signed-off-by: Naushir Patuck Reviewed-by: David Plowman --- src/ipa/rpi/common/ipa_base.cpp | 41 ++++----------------------------- src/ipa/rpi/vc4/vc4.cpp | 35 ++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 39 deletions(-) diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp index f28eb36b7a44..2583c6226f44 100644 --- a/src/ipa/rpi/common/ipa_base.cpp +++ b/src/ipa/rpi/common/ipa_base.cpp @@ -643,14 +643,6 @@ static const std::map AwbModeTable = { { controls::AwbCustom, "custom" }, }; -static const std::map DenoiseModeTable = { - { controls::draft::NoiseReductionModeOff, RPiController::DenoiseMode::Off }, - { controls::draft::NoiseReductionModeFast, RPiController::DenoiseMode::ColourFast }, - { controls::draft::NoiseReductionModeHighQuality, RPiController::DenoiseMode::ColourHighQuality }, - { controls::draft::NoiseReductionModeMinimal, RPiController::DenoiseMode::ColourOff }, - { controls::draft::NoiseReductionModeZSL, RPiController::DenoiseMode::ColourHighQuality }, -}; - static const std::map AfModeTable = { { controls::AfModeManual, RPiController::AfAlgorithm::AfModeManual }, { controls::AfModeAuto, RPiController::AfAlgorithm::AfModeAuto }, @@ -1032,36 +1024,11 @@ void IpaBase::applyControls(const ControlList &controls) break; } - case controls::NOISE_REDUCTION_MODE: { - RPiController::DenoiseAlgorithm *sdn = dynamic_cast( - controller_.getAlgorithm("SDN")); - /* Some platforms may have a combined "denoise" algorithm instead. */ - if (!sdn) - sdn = dynamic_cast( - controller_.getAlgorithm("denoise")); - if (!sdn) { - LOG(IPARPI, Warning) - << "Could not set NOISE_REDUCTION_MODE - no SDN algorithm"; - break; - } - - int32_t idx = ctrl.second.get(); - auto mode = DenoiseModeTable.find(idx); - if (mode != DenoiseModeTable.end()) { - sdn->setMode(mode->second); - - /* - * \todo If the colour denoise is not going to run due to an - * analysis image resolution or format mismatch, we should - * report the status correctly in the metadata. - */ - libcameraMetadata_.set(controls::draft::NoiseReductionMode, idx); - } else { - LOG(IPARPI, Error) << "Noise reduction mode " << idx - << " not recognised"; - } + case controls::NOISE_REDUCTION_MODE: + /* Handled below in handleControls() */ + libcameraMetadata_.set(controls::draft::NoiseReductionMode, + ctrl.second.get()); break; - } case controls::AF_MODE: break; /* We already handled this one above */ diff --git a/src/ipa/rpi/vc4/vc4.cpp b/src/ipa/rpi/vc4/vc4.cpp index 4a4d720ce7dd..354b901bb796 100644 --- a/src/ipa/rpi/vc4/vc4.cpp +++ b/src/ipa/rpi/vc4/vc4.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include "common/ipa_base.h" @@ -247,9 +248,39 @@ RPiController::StatisticsPtr IpaVc4::platformProcessStats(Span mem) return statistics; } -void IpaVc4::handleControls([[maybe_unused]] const ControlList &controls) +void IpaVc4::handleControls(const ControlList &controls) { - /* No controls require any special updates to the hardware configuration. */ + static const std::map DenoiseModeTable = { + { controls::draft::NoiseReductionModeOff, RPiController::DenoiseMode::Off }, + { controls::draft::NoiseReductionModeFast, RPiController::DenoiseMode::ColourFast }, + { controls::draft::NoiseReductionModeHighQuality, RPiController::DenoiseMode::ColourHighQuality }, + { controls::draft::NoiseReductionModeMinimal, RPiController::DenoiseMode::ColourOff }, + { controls::draft::NoiseReductionModeZSL, RPiController::DenoiseMode::ColourHighQuality }, + }; + + for (auto const &ctrl : controls) { + switch (ctrl.first) { + case controls::NOISE_REDUCTION_MODE: { + RPiController::DenoiseAlgorithm *sdn = dynamic_cast( + controller_.getAlgorithm("SDN")); + /* Some platforms may have a combined "denoise" algorithm instead. */ + if (!sdn) + sdn = dynamic_cast( + controller_.getAlgorithm("denoise")); + if (!sdn) { + LOG(IPARPI, Warning) + << "Could not set NOISE_REDUCTION_MODE - no SDN algorithm"; + return; + } + + int32_t idx = ctrl.second.get(); + auto mode = DenoiseModeTable.find(idx); + if (mode != DenoiseModeTable.end()) + sdn->setMode(mode->second); + break; + } + } + } } bool IpaVc4::validateIspControls() From patchwork Fri Oct 20 08:40:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 19166 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 76C2CC3275 for ; Fri, 20 Oct 2023 08:40:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 245E562982; Fri, 20 Oct 2023 10:40:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1697791236; bh=ylFITJcGz25qrF6i5eL+oH9LlPjYqrPKrAPETAxOwoY=; 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=mmEEJo+z6ewRBHi0JUZwfV8VXZgaMGyeY/74dryaTsbe+CXqQh0B3TEWlFKyAUM1y vxErD839o76px9nKs4rkc0wFTnJEtY+vKjnOY84fyf8ZHCeLKnwmcXMRl869GHUnC7 gxV3Hc9Gs1AoDAR8hGW3Nl7LEeQ9RCD7GQ6+l2hpsIBQnNO6Bwq8oaObb+EPLT7HGi FXZTvlT7JkYUXXRh75oq+fP/uss5yn2vZlRZQaTL3GuqCgFBmti8d1a4w7jT+KR3V9 Jhn74F3cLstoE8S3+K1F55lO/W67RJ4SVrwRUwqYJnRgaEFOS/D6ut2VmQgWcWP7wL yAfuZ2VTnajFQ== Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0B26B61DCF for ; Fri, 20 Oct 2023 10:40:31 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="dLUBsBAo"; dkim-atps=neutral Received: by mail-wr1-x42f.google.com with SMTP id ffacd0b85a97d-32d9b507b00so434590f8f.1 for ; Fri, 20 Oct 2023 01:40:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1697791230; x=1698396030; 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=A0D0tXnU990HtWARhVc3XMkpdyaSBOIWYzTRIuhHRcc=; b=dLUBsBAoKSQq8Fx6SUOG+YYxWPdiJMeOBCSClTvg/fM8BTZs+XSz136CViSFxzIXGU 396Cel1JSljFsKe4KjyyOZLy6gJMQedooZKp9RST4hK6aJ14EP0H1j9MyH0bnVe3HwPS 4E2jIlbObFHRdTX/U6Xv9JSMHlqmp0Evkqx45Km0MSDCWtyOCowpQBScP0ot6B8Q6/pp SOcGr5Vj0C9az/1L+ngxI6dMciYwwIRYTfh4bja2Og1AXIXpftAuXRlVYonIouT7fsum wTLf1rhneyKB7AWvRyKTYdntFHAhX1edcMwKqj2ejgVvAPf1iMH70CLVVIVzGx9CICF9 5wLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697791230; x=1698396030; 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=A0D0tXnU990HtWARhVc3XMkpdyaSBOIWYzTRIuhHRcc=; b=F+jDQWDMvP4wzvksR17ttRo7008ZpvAW5bqF47R7/clrr8YzX4zDPmAFozOf0CetI2 td/7XZDZnl1RT+f0tv+83p6gxQgnDs1qfiG4zcF4E5A+R8vyMa2oqXhe9b8HngwhPAhj Qrs+eJVkKBKIzAC5qzoW4x33NqJfG6TwNRojiJAw9N0hrN97R6OMY6FtTfeupWv2IX4L Vn4dABuMF7DFHye65EYMI70Mnyz3I2xU1tpwwEdk9ikhuFCUH3/zV+LBAbLxjYpAqcLf rDCo9ayVsVvgVt7APVG+OfqAChdjxqlrhyU0rZNcPbsJoxx1taj9qJh6N4vtieHd2Z14 dePQ== X-Gm-Message-State: AOJu0Ywdy0e4HKn+TWGXpljYPukVhnWBFtZz0jVHVmYYpXkEn8BClDYf pYDK73yTUKVIPCmu5h739Cujb/GQ8z9zfZTsHk95JQ== X-Google-Smtp-Source: AGHT+IHNtWK8arF3ev0j4V8har8751+XVA0bwLcUQuP0IBRCh4IRXcvBZSuZt8In9KvWddSnaZeiVA== X-Received: by 2002:adf:e5c8:0:b0:32d:6891:f819 with SMTP id a8-20020adfe5c8000000b0032d6891f819mr937397wrn.41.1697791230448; Fri, 20 Oct 2023 01:40:30 -0700 (PDT) Received: from localhost.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id r3-20020adff103000000b0032d9337e7d1sm1213356wro.11.2023.10.20.01.40.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 01:40:29 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Fri, 20 Oct 2023 09:40:01 +0100 Message-Id: <20231020084002.30665-6-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231020084002.30665-1-naush@raspberrypi.com> References: <20231020084002.30665-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 5/6] ipa: rpi: agc: Fetch AWB status in the prepare method 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 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: David Plowman AWB writes this out during prepare, so we may as well read it in AGC prepare as well. Reading it in process is wrong on the PiSP platform because process runs before prepare, so the AWB status won't be there (on vc4 it made no difference). Signed-off-by: David Plowman Reviewed-by: Naushir Patuck --- src/ipa/rpi/controller/rpi/agc_channel.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp index 3efb6482b67f..8d374b53689d 100644 --- a/src/ipa/rpi/controller/rpi/agc_channel.cpp +++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp @@ -270,7 +270,11 @@ AgcChannel::AgcChannel() lastTargetExposure_(0s), ev_(1.0), flickerPeriod_(0s), maxShutter_(0s), fixedShutter_(0s), fixedAnalogueGain_(0.0) { - memset(&awb_, 0, sizeof(awb_)); + /* Set AWB default values in case early frames have no updates in metadata. */ + awb_.gainR = 1.0; + awb_.gainG = 1.0; + awb_.gainB = 1.0; + /* * Setting status_.totalExposureValue_ to zero initially tells us * it's not been calculated yet (i.e. Process hasn't yet run). @@ -409,7 +413,6 @@ void AgcChannel::switchMode(CameraMode const &cameraMode, Duration fixedShutter = limitShutter(fixedShutter_); if (fixedShutter && fixedAnalogueGain_) { /* We're going to reset the algorithm here with these fixed values. */ - fetchAwbStatus(metadata); double minColourGain = std::min({ awb_.gainR, awb_.gainG, awb_.gainB, 1.0 }); ASSERT(minColourGain != 0.0); @@ -464,6 +467,9 @@ void AgcChannel::prepare(Metadata *imageMetadata) AgcStatus delayedStatus; AgcPrepareStatus prepareStatus; + /* Fetch the AWB status now because AWB also sets it in the prepare method. */ + fetchAwbStatus(imageMetadata); + if (!imageMetadata->get("agc.delayed_status", delayedStatus)) totalExposureValue = delayedStatus.totalExposureValue; @@ -507,8 +513,6 @@ void AgcChannel::process(StatisticsPtr &stats, DeviceStatus const &deviceStatus, * configuration, that kind of thing. */ housekeepConfig(); - /* Fetch the AWB status immediately, so that we can assume it's there. */ - fetchAwbStatus(imageMetadata); /* Get the current exposure values for the frame that's just arrived. */ fetchCurrentExposure(deviceStatus); /* Compute the total gain we require relative to the current exposure. */ @@ -637,9 +641,6 @@ void AgcChannel::fetchCurrentExposure(DeviceStatus const &deviceStatus) void AgcChannel::fetchAwbStatus(Metadata *imageMetadata) { - awb_.gainR = 1.0; /* in case not found in metadata */ - awb_.gainG = 1.0; - awb_.gainB = 1.0; if (imageMetadata->get("awb.status", awb_) != 0) LOG(RPiAgc, Debug) << "No AWB status found"; } From patchwork Fri Oct 20 08:40:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 19167 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 03C89C32B8 for ; Fri, 20 Oct 2023 08:40:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A554562988; Fri, 20 Oct 2023 10:40:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1697791236; bh=Yp1iH+nU2dfob3NUfknPBnEJJ6Ut319oQzWEz8fTTzs=; 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=eq1eKlU1RdczhQTyS4WKztfMnnMei3ZIi1aaIcoDW7yWou7wJfnniK7FJhal+LI/l EN6lothnw1amLJA71ORr1AcEztIWzQPBsMsmv5OTCeQOaSw1gJ0CobaTCcCRqpVcbR tpKw7KLVdJUMkjG9G+DWyxhM6AMrXWDnkoxJC5Vwx/YIXm1mtZRxH8RxTfkxoU+WMM NY4beNPMChDeiHlZUMk3gWnwxp6mvGfoFMEOOIa8/zhmG+5vL5uIJkE0tCC2Svdwv1 PvURRlIthcmDWRcyVb/c7h91WBQXY4xhROG/ueyXlHZFKBbkdcIXRek1uJNSJON9vB YI9ivvD+fnk4g== Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C73396298A for ; Fri, 20 Oct 2023 10:40:31 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="PYHCfc+T"; dkim-atps=neutral Received: by mail-wr1-x435.google.com with SMTP id ffacd0b85a97d-31c5cac3ae2so430733f8f.3 for ; Fri, 20 Oct 2023 01:40:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1697791231; x=1698396031; 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=ONlW2T4HkI3qwVgetsJja6/efFs+Qrn3bOK1EZjcag4=; b=PYHCfc+Tsirfckb9ThgE/xo4RfnCldwP8ZClnMJ3E1kipBCBUt+lh4sp3RqFXOcJKY ZqwhtgtvsbJnNMZgjKK9LMpIApKZqgcUQMgGuoavCV4C8zgGCu25wqI3X1W+TVTkNjTm DywdLSS6rvceH8OXIX58Xqy7TwjYBnU7e/YZLOVwsqDuV65CWGfyx6cctWGKX2Ip1Pp6 FTXSQHGD89pqLllqQRvPsy8oxpwRwsPARMwDlSdITsaTs5/jTmmHGdW0yzux4aSBaXq2 cBQGp6SzT17N/oP/iMmAggALEddW/KI5vByCWWmABBbXel2TSZTKAm9yWfOVOS6O4OjO YueQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697791231; x=1698396031; 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=ONlW2T4HkI3qwVgetsJja6/efFs+Qrn3bOK1EZjcag4=; b=kD+0cG41efWxdc3zLzPpGbkZDRx7KNl+C4MkVZeu2G9+K15S3PKEJwvoXLni+9d7Cg WxHDAwM6FnD7k6Ds95gFlJ3VKCy70wxW9c/FSlEUpP2+uBW376y+RHtlvlpYc7bOdF1g 26wuAgVMs2om7MFKr8wDEOFcGSTaLjIb/QLNEivMHMftVQDzuunAENVnhw9zDMxdJFTq BhifG9cspy9DwHcuSzuf9duVUTY5GeaeozOtna4XbeAFGZUJqbtZiWqpMJx1KW2QCRQY m7CFUNesl7oZuKWWHeg31hAJkYclQGTtbpfW40kL+sY/CXqleOf1rpKkIua5un+MBol2 klSA== X-Gm-Message-State: AOJu0YxH1MR2w3bX9GKlSZasjmj4YefuzAKQ06Rjy+PTqDxpJvtD5+hh toHjEQj+pEOXs8MYEvokgMCxd2PyZC11HwWzraUUsA== X-Google-Smtp-Source: AGHT+IEk71pn0N6xWdEq3YobfW2udBMIHXGfWBnxp6rWXskrwR6YlkPsw8O+FqWZU4yeyQ6BvLsINg== X-Received: by 2002:a05:6000:ac9:b0:31a:e8e6:8a96 with SMTP id di9-20020a0560000ac900b0031ae8e68a96mr797758wrb.67.1697791231193; Fri, 20 Oct 2023 01:40:31 -0700 (PDT) Received: from localhost.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id r3-20020adff103000000b0032d9337e7d1sm1213356wro.11.2023.10.20.01.40.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Oct 2023 01:40:30 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Fri, 20 Oct 2023 09:40:02 +0100 Message-Id: <20231020084002.30665-7-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231020084002.30665-1-naush@raspberrypi.com> References: <20231020084002.30665-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 6/6] ipa: rpi: agc: Make AGC controls affect all channels 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 Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: David Plowman We need to be able to do things like enable/disable AGC for all the channels, so most of the AGC controls are updated to be applied to all channels. There are a couple of exceptions, such as setting explicit shutter/gain values, which apply only to channel 0. Signed-off-by: David Plowman Reviewed-by: Naushir Patuck --- src/ipa/rpi/common/ipa_base.cpp | 14 +++---- src/ipa/rpi/controller/agc_algorithm.h | 11 +++--- src/ipa/rpi/controller/rpi/agc.cpp | 51 +++++++++++++------------- src/ipa/rpi/controller/rpi/agc.h | 13 +++---- 4 files changed, 42 insertions(+), 47 deletions(-) diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp index 2583c6226f44..a1fec3aa3dd1 100644 --- a/src/ipa/rpi/common/ipa_base.cpp +++ b/src/ipa/rpi/common/ipa_base.cpp @@ -702,9 +702,9 @@ void IpaBase::applyControls(const ControlList &controls) } if (ctrl.second.get() == false) - agc->disableAuto(0); + agc->disableAuto(); else - agc->enableAuto(0); + agc->enableAuto(); libcameraMetadata_.set(controls::AeEnable, ctrl.second.get()); break; @@ -773,7 +773,7 @@ void IpaBase::applyControls(const ControlList &controls) int32_t idx = ctrl.second.get(); if (ConstraintModeTable.count(idx)) { - agc->setConstraintMode(0, ConstraintModeTable.at(idx)); + agc->setConstraintMode(ConstraintModeTable.at(idx)); libcameraMetadata_.set(controls::AeConstraintMode, idx); } else { LOG(IPARPI, Error) << "Constraint mode " << idx @@ -793,7 +793,7 @@ void IpaBase::applyControls(const ControlList &controls) int32_t idx = ctrl.second.get(); if (ExposureModeTable.count(idx)) { - agc->setExposureMode(0, ExposureModeTable.at(idx)); + agc->setExposureMode(ExposureModeTable.at(idx)); libcameraMetadata_.set(controls::AeExposureMode, idx); } else { LOG(IPARPI, Error) << "Exposure mode " << idx @@ -836,12 +836,12 @@ void IpaBase::applyControls(const ControlList &controls) switch (mode) { case controls::FlickerOff: - agc->setFlickerPeriod(0, 0us); + agc->setFlickerPeriod(0us); break; case controls::FlickerManual: - agc->setFlickerPeriod(0, flickerState_.manualPeriod); + agc->setFlickerPeriod(flickerState_.manualPeriod); break; @@ -875,7 +875,7 @@ void IpaBase::applyControls(const ControlList &controls) * first, and the period updated after, or vice versa. */ if (flickerState_.mode == controls::FlickerManual) - agc->setFlickerPeriod(0, flickerState_.manualPeriod); + agc->setFlickerPeriod(flickerState_.manualPeriod); break; } diff --git a/src/ipa/rpi/controller/agc_algorithm.h b/src/ipa/rpi/controller/agc_algorithm.h index b8986560ac88..534e38e2b5b7 100644 --- a/src/ipa/rpi/controller/agc_algorithm.h +++ b/src/ipa/rpi/controller/agc_algorithm.h @@ -22,17 +22,16 @@ public: virtual unsigned int getConvergenceFrames() const = 0; virtual std::vector const &getWeights() const = 0; virtual void setEv(unsigned int channel, double ev) = 0; - virtual void setFlickerPeriod(unsigned int channel, - libcamera::utils::Duration flickerPeriod) = 0; + virtual void setFlickerPeriod(libcamera::utils::Duration flickerPeriod) = 0; virtual void setFixedShutter(unsigned int channel, libcamera::utils::Duration fixedShutter) = 0; virtual void setMaxShutter(libcamera::utils::Duration maxShutter) = 0; virtual void setFixedAnalogueGain(unsigned int channel, double fixedAnalogueGain) = 0; virtual void setMeteringMode(std::string const &meteringModeName) = 0; - virtual void setExposureMode(unsigned int channel, std::string const &exposureModeName) = 0; - virtual void setConstraintMode(unsigned int channel, std::string const &contraintModeName) = 0; - virtual void enableAuto(unsigned int channel) = 0; - virtual void disableAuto(unsigned int channel) = 0; + virtual void setExposureMode(std::string const &exposureModeName) = 0; + virtual void setConstraintMode(std::string const &contraintModeName) = 0; + virtual void enableAuto() = 0; + virtual void disableAuto() = 0; virtual void setActiveChannels(const std::vector &activeChannels) = 0; }; diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp index 32eb36242268..6549dedd0a07 100644 --- a/src/ipa/rpi/controller/rpi/agc.cpp +++ b/src/ipa/rpi/controller/rpi/agc.cpp @@ -74,22 +74,22 @@ int Agc::checkChannel(unsigned int channelIndex) const return 0; } -void Agc::disableAuto(unsigned int channelIndex) +void Agc::disableAuto() { - if (checkChannel(channelIndex)) - return; + LOG(RPiAgc, Debug) << "disableAuto"; - LOG(RPiAgc, Debug) << "disableAuto for channel " << channelIndex; - channelData_[channelIndex].channel.disableAuto(); + /* All channels are enabled/disabled together. */ + for (auto &data : channelData_) + data.channel.disableAuto(); } -void Agc::enableAuto(unsigned int channelIndex) +void Agc::enableAuto() { - if (checkChannel(channelIndex)) - return; + LOG(RPiAgc, Debug) << "enableAuto"; - LOG(RPiAgc, Debug) << "enableAuto for channel " << channelIndex; - channelData_[channelIndex].channel.enableAuto(); + /* All channels are enabled/disabled together. */ + for (auto &data : channelData_) + data.channel.enableAuto(); } unsigned int Agc::getConvergenceFrames() const @@ -118,14 +118,13 @@ void Agc::setEv(unsigned int channelIndex, double ev) channelData_[channelIndex].channel.setEv(ev); } -void Agc::setFlickerPeriod(unsigned int channelIndex, Duration flickerPeriod) +void Agc::setFlickerPeriod(Duration flickerPeriod) { - if (checkChannel(channelIndex)) - return; + LOG(RPiAgc, Debug) << "setFlickerPeriod " << flickerPeriod; - LOG(RPiAgc, Debug) << "setFlickerPeriod " << flickerPeriod - << " for channel " << channelIndex; - channelData_[channelIndex].channel.setFlickerPeriod(flickerPeriod); + /* Flicker period will be the same across all channels. */ + for (auto &data : channelData_) + data.channel.setFlickerPeriod(flickerPeriod); } void Agc::setMaxShutter(Duration maxShutter) @@ -162,22 +161,22 @@ void Agc::setMeteringMode(std::string const &meteringModeName) data.channel.setMeteringMode(meteringModeName); } -void Agc::setExposureMode(unsigned int channelIndex, std::string const &exposureModeName) +void Agc::setExposureMode(std::string const &exposureModeName) { - if (checkChannel(channelIndex)) - return; + LOG(RPiAgc, Debug) << "setExposureMode " << exposureModeName; - LOG(RPiAgc, Debug) << "setExposureMode " << exposureModeName - << " for channel " << channelIndex; - channelData_[channelIndex].channel.setExposureMode(exposureModeName); + /* Exposure mode will be the same across all channels. */ + for (auto &data : channelData_) + data.channel.setExposureMode(exposureModeName); } -void Agc::setConstraintMode(unsigned int channelIndex, std::string const &constraintModeName) +void Agc::setConstraintMode(std::string const &constraintModeName) { - if (checkChannel(channelIndex)) - return; + LOG(RPiAgc, Debug) << "setConstraintMode " << constraintModeName; - channelData_[channelIndex].channel.setConstraintMode(constraintModeName); + /* Constraint mode will be the same across all channels. */ + for (auto &data : channelData_) + data.channel.setConstraintMode(constraintModeName); } template diff --git a/src/ipa/rpi/controller/rpi/agc.h b/src/ipa/rpi/controller/rpi/agc.h index 908904393fbf..7d26bdf6df45 100644 --- a/src/ipa/rpi/controller/rpi/agc.h +++ b/src/ipa/rpi/controller/rpi/agc.h @@ -31,20 +31,17 @@ public: unsigned int getConvergenceFrames() const override; std::vector const &getWeights() const override; void setEv(unsigned int channel, double ev) override; - void setFlickerPeriod(unsigned int channelIndex, - libcamera::utils::Duration flickerPeriod) override; + void setFlickerPeriod(libcamera::utils::Duration flickerPeriod) override; void setMaxShutter(libcamera::utils::Duration maxShutter) override; void setFixedShutter(unsigned int channelIndex, libcamera::utils::Duration fixedShutter) override; void setFixedAnalogueGain(unsigned int channelIndex, double fixedAnalogueGain) override; void setMeteringMode(std::string const &meteringModeName) override; - void setExposureMode(unsigned int channelIndex, - std::string const &exposureModeName) override; - void setConstraintMode(unsigned int channelIndex, - std::string const &contraintModeName) override; - void enableAuto(unsigned int channelIndex) override; - void disableAuto(unsigned int channelIndex) override; + void setExposureMode(std::string const &exposureModeName) override; + void setConstraintMode(std::string const &contraintModeName) override; + void enableAuto() override; + void disableAuto() override; void switchMode(CameraMode const &cameraMode, Metadata *metadata) override; void prepare(Metadata *imageMetadata) override; void process(StatisticsPtr &stats, Metadata *imageMetadata) override;