From patchwork Fri Aug 20 06:53:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 13413 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 B972DC3245 for ; Fri, 20 Aug 2021 06:53:31 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D560F688A2; Fri, 20 Aug 2021 08:53:30 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="I4YOhEl2"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DFDEC68919 for ; Fri, 20 Aug 2021 08:53:22 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:e43b:edb2:932:6b0a]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 8B69118EE; Fri, 20 Aug 2021 08:53:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1629442402; bh=9YS54Lj9B9mRrvwh0wl/yeWopRzugic0IomrM2dj9gA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I4YOhEl2fiM5lACCx0Hr1LwRd6ILiPO1p9Uz2C6AF7lrwZvSkP2nEjgoX1LSqCLDe 9MHCl+UTiVIjT98t5RvVn5mx6RPsdmQgtDe7hTboCtw11kmP2OpaNAcA0g6w3Pyb4I ieDzwpBvLweU2l1NcujHzJLq8gOY+fwrBGeEfm3Q= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 20 Aug 2021 08:53:16 +0200 Message-Id: <20210820065316.44343-10-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210820065316.44343-1-jeanmichel.hautbois@ideasonboard.com> References: <20210820065316.44343-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 9/9] ipa: ipu3: Move IPU3 agc into algorithms 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Now that the interface is properly used by the AGC class, move it into ipa::ipu3::algorithms and let the loops do the calls. As we need to exchange the exposure_ and gain_ by passing them through the FrameContext, use the calculated values in setControls() function to ease the reading. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- .../ipu3/{ipu3_agc.cpp => algorithms/agc.cpp} | 18 ++++++++--------- src/ipa/ipu3/{ipu3_agc.h => algorithms/agc.h} | 20 +++++++++---------- src/ipa/ipu3/algorithms/meson.build | 1 + src/ipa/ipu3/ipu3.cpp | 20 ++++++++----------- src/ipa/ipu3/meson.build | 1 - 5 files changed, 28 insertions(+), 32 deletions(-) rename src/ipa/ipu3/{ipu3_agc.cpp => algorithms/agc.cpp} (94%) rename src/ipa/ipu3/{ipu3_agc.h => algorithms/agc.h} (73%) diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp similarity index 94% rename from src/ipa/ipu3/ipu3_agc.cpp rename to src/ipa/ipu3/algorithms/agc.cpp index 1c156b89..e4598b2e 100644 --- a/src/ipa/ipu3/ipu3_agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -5,7 +5,7 @@ * ipu3_agc.cpp - AGC/AEC control algorithm */ -#include "ipu3_agc.h" +#include "agc.h" #include #include @@ -21,7 +21,7 @@ namespace libcamera { using namespace std::literals::chrono_literals; -namespace ipa::ipu3 { +namespace ipa::ipu3::algorithms { LOG_DEFINE_CATEGORY(IPU3Agc) @@ -50,14 +50,14 @@ static constexpr double kEvGainTarget = 0.5; /* A cell is 8 bytes and contains averages for RGB values and saturation ratio */ static constexpr uint8_t kCellSize = 8; -IPU3Agc::IPU3Agc() +Agc::Agc() : frameCount_(0), lastFrame_(0), iqMean_(0.0), lineDuration_(0s), maxExposureTime_(0s), prevExposure_(0s), prevExposureNoDg_(0s), currentExposure_(0s), currentExposureNoDg_(0s) { } -int IPU3Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) +int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) { aeGrid_ = context.configuration.grid.bdsGrid; @@ -68,7 +68,7 @@ int IPU3Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) return 0; } -void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats) +void Agc::processBrightness(const ipu3_uapi_stats_3a *stats) { const struct ipu3_uapi_grid_config statsAeGrid = stats->stats_4a_config.awb_config.grid; Rectangle aeRegion = { statsAeGrid.x_start, @@ -109,7 +109,7 @@ void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats) iqMean_ = Histogram(Span(hist)).interQuantileMean(0.98, 1.0); } -void IPU3Agc::filterExposure() +void Agc::filterExposure() { double speed = 0.2; if (prevExposure_ == 0s) { @@ -143,7 +143,7 @@ void IPU3Agc::filterExposure() LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << prevExposure_; } -void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) +void Agc::lockExposureGain(uint32_t &exposure, double &gain) { /* Algorithm initialization should wait for first valid frames */ /* \todo - have a number of frames given by DelayedControls ? @@ -186,7 +186,7 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) lastFrame_ = frameCount_; } -void IPU3Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) +void Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) { uint32_t &exposure = context.frameContext.agc.exposure; double &gain = context.frameContext.agc.gain; @@ -195,6 +195,6 @@ void IPU3Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) frameCount_++; } -} /* namespace ipa::ipu3 */ +} /* namespace ipa::ipu3::algorithms */ } /* namespace libcamera */ diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/algorithms/agc.h similarity index 73% rename from src/ipa/ipu3/ipu3_agc.h rename to src/ipa/ipu3/algorithms/agc.h index 0e922664..1739d2fd 100644 --- a/src/ipa/ipu3/ipu3_agc.h +++ b/src/ipa/ipu3/algorithms/agc.h @@ -2,10 +2,10 @@ /* * Copyright (C) 2021, Ideas On Board * - * ipu3_agc.h - IPU3 AGC/AEC control algorithm + * agc.h - IPU3 AGC/AEC control algorithm */ -#ifndef __LIBCAMERA_IPU3_AGC_H__ -#define __LIBCAMERA_IPU3_AGC_H__ +#ifndef __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ +#define __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ #include @@ -13,21 +13,21 @@ #include -#include "algorithms/algorithm.h" +#include "algorithm.h" namespace libcamera { struct IPACameraSensorInfo; -namespace ipa::ipu3 { +namespace ipa::ipu3::algorithms { using utils::Duration; -class IPU3Agc : public Algorithm +class Agc : public Algorithm { public: - IPU3Agc(); - ~IPU3Agc() = default; + Agc(); + ~Agc() = default; int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override; @@ -53,8 +53,8 @@ private: Duration currentExposureNoDg_; }; -} /* namespace ipa::ipu3 */ +} /* namespace ipa::ipu3::algorithms */ } /* namespace libcamera */ -#endif /* __LIBCAMERA_IPU3_AGC_H__ */ +#endif /* __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ */ diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build index fa004df4..deae225b 100644 --- a/src/ipa/ipu3/algorithms/meson.build +++ b/src/ipa/ipu3/algorithms/meson.build @@ -1,6 +1,7 @@ # SPDX-License-Identifier: CC0-1.0 ipu3_ipa_algorithms = files([ + 'agc.cpp', 'algorithm.cpp', 'awb.cpp', 'tone_mapping.cpp', diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 5fc358fa..0ed0a6f1 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -29,10 +29,10 @@ #include "libcamera/internal/mapped_framebuffer.h" +#include "algorithms/agc.h" #include "algorithms/algorithm.h" #include "algorithms/awb.h" #include "algorithms/tone_mapping.h" -#include "ipu3_agc.h" #include "libipa/camera_sensor_helper.h" /** @@ -187,8 +187,6 @@ private: uint32_t minGain_; uint32_t maxGain_; - /* Interface to the AEC/AGC algorithm */ - std::unique_ptr agcAlgo_; /* Interface to the Camera Helper */ std::unique_ptr camHelper_; @@ -268,6 +266,7 @@ int IPAIPU3::init(const IPASettings &settings, *ipaControls = ControlInfoMap(std::move(controls), controls::controls); /* Construct our Algorithms */ + algorithms_.push_back(std::make_unique()); algorithms_.push_back(std::make_unique()); algorithms_.push_back(std::make_unique()); @@ -386,9 +385,6 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) return ret; } - agcAlgo_ = std::make_unique(); - agcAlgo_->configure(context_, configInfo); - return 0; } @@ -476,15 +472,12 @@ void IPAIPU3::parseStatistics(unsigned int frame, { ControlList ctrls(controls::controls); - for (auto const &algo : algorithms_) - algo->process(context_, stats); - /* \todo These fields should not be written by the IPAIPU3 layer */ context_.frameContext.agc.gain = camHelper_->gain(gain_); context_.frameContext.agc.exposure = exposure_; - agcAlgo_->process(context_, stats); - exposure_ = context_.frameContext.agc.exposure; - gain_ = camHelper_->gainCode(context_.frameContext.agc.gain); + + for (auto const &algo : algorithms_) + algo->process(context_, stats); setControls(frame); @@ -505,6 +498,9 @@ void IPAIPU3::setControls(unsigned int frame) IPU3Action op; op.op = ActionSetSensorControls; + exposure_ = context_.frameContext.agc.exposure; + gain_ = camHelper_->gainCode(context_.frameContext.agc.gain); + ControlList ctrls(ctrls_); ctrls.set(V4L2_CID_EXPOSURE, static_cast(exposure_)); ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast(gain_)); diff --git a/src/ipa/ipu3/meson.build b/src/ipa/ipu3/meson.build index d1126947..39320980 100644 --- a/src/ipa/ipu3/meson.build +++ b/src/ipa/ipu3/meson.build @@ -6,7 +6,6 @@ ipa_name = 'ipa_ipu3' ipu3_ipa_sources = files([ 'ipu3.cpp', - 'ipu3_agc.cpp', ]) ipu3_ipa_sources += ipu3_ipa_algorithms