From patchwork Mon Jun 28 20:22:53 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: 12740 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 20E76C321F for ; Mon, 28 Jun 2021 20:23:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C0323684D8; Mon, 28 Jun 2021 22:23:07 +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="T+qxM5m8"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A526A60508 for ; Mon, 28 Jun 2021 22:23:00 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:c3ad:78d0:405e:fc33]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5D829E1A; Mon, 28 Jun 2021 22:23:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1624911780; bh=tBFLU0Yeg3WjK5ACTVDZvPYeav6Mg9xubS1dBFY8Yuo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=T+qxM5m8xllxmC27Vs9iib5ZxfmY5yvvmU6vCCyegNLzkj17wk9gYiZqfS5utvA+Q 4PejKKi8DPzoL39W1m4SykaWUrTCetJdRATgTeVqLVT6mtxSztDN3hHPy2wPAgWrKk SRF53GRGhkni2Eoj6yIXdKN4o/1YDYJvdb7kZZZ8= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Mon, 28 Jun 2021 22:22:53 +0200 Message-Id: <20210628202255.138874-6-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210628202255.138874-1-jeanmichel.hautbois@ideasonboard.com> References: <20210628202255.138874-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 5/7] ipa: ipu3: Improve AWB behaviour 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" In order to use a better grid, clamp the values calculated from the BDS resolution to at least 2 times the minimum grid size. The number of zones needed to have sufficiently relevant statistics is now based on the region sizes and not on an arbitrary value. Last, the default green gains where not properly used, it should be 8192 and not 4096 to have a multiplier of 1.0 on the R/G/B gains. The default CCM is adjusted for Surface Go2 only, and should eventually be calculated in the CameraSensorHelper class. Signed-off-by: Jean-Michel Hautbois --- src/ipa/ipu3/ipu3.cpp | 12 ++++++++---- src/ipa/ipu3/ipu3_awb.cpp | 23 +++++++++++------------ src/ipa/ipu3/ipu3_awb.h | 1 + 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 4466391a..9a2def64 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -123,12 +123,16 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize) bdsGrid_ = {}; for (uint32_t widthShift = 3; widthShift <= 7; ++widthShift) { - uint32_t width = std::min(kMaxCellWidthPerSet, - bdsOutputSize.width >> widthShift); + uint32_t width = std::clamp(bdsOutputSize.width >> widthShift, + 2 * kAwbStatsSizeX, + kMaxCellWidthPerSet); + width = width << widthShift; for (uint32_t heightShift = 3; heightShift <= 7; ++heightShift) { - int32_t height = std::min(kMaxCellHeightPerSet, - bdsOutputSize.height >> heightShift); + uint32_t height = std::clamp(bdsOutputSize.height >> heightShift, + 2 * kAwbStatsSizeY, + kMaxCellHeightPerSet); + height = height << heightShift; uint32_t error = std::abs(static_cast(width - bdsOutputSize.width)) + std::abs(static_cast(height - bdsOutputSize.height)); diff --git a/src/ipa/ipu3/ipu3_awb.cpp b/src/ipa/ipu3/ipu3_awb.cpp index a94935c5..a39536b0 100644 --- a/src/ipa/ipu3/ipu3_awb.cpp +++ b/src/ipa/ipu3/ipu3_awb.cpp @@ -18,9 +18,6 @@ namespace ipa::ipu3 { LOG_DEFINE_CATEGORY(IPU3Awb) -static constexpr uint32_t kMinZonesCounted = 16; -static constexpr uint32_t kMinGreenLevelInZone = 32; - /** * \struct IspStatsRegion * \brief RGB statistics for a given region @@ -92,7 +89,7 @@ static constexpr uint32_t kMinGreenLevelInZone = 32; /* Default settings for Bayer noise reduction replicated from the Kernel */ static const struct ipu3_uapi_bnr_static_config imguCssBnrDefaults = { - .wb_gains = { 16, 16, 16, 16 }, + .wb_gains = { 8192, 8192, 8192, 8192 }, .wb_gains_thr = { 255, 255, 255, 255 }, .thr_coeffs = { 1700, 0, 31, 31, 0, 16 }, .thr_ctrl_shd = { 26, 26, 26, 26 }, @@ -130,7 +127,7 @@ static const struct ipu3_uapi_awb_config_s imguCssAwbDefaults = { /* Default color correction matrix defined as an identity matrix */ static const struct ipu3_uapi_ccm_mat_config imguCssCcmDefault = { 8191, 0, 0, 0, - 0, 8191, 0, 0, + 0, 6000, 0, 0, 0, 0, 8191, 0 }; @@ -166,6 +163,7 @@ IPU3Awb::IPU3Awb() asyncResults_.greenGain = 1.0; asyncResults_.redGain = 1.0; asyncResults_.temperatureK = 4500; + minZonesCounted_ = 0; } IPU3Awb::~IPU3Awb() @@ -241,7 +239,7 @@ void IPU3Awb::generateZones(std::vector &zones) for (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) { RGB zone; double counted = awbStats_[i].counted; - if (counted >= kMinZonesCounted) { + if (counted >= minZonesCounted_) { zone.G = awbStats_[i].gSum / counted; if (zone.G >= kMinGreenLevelInZone) { zone.R = awbStats_[i].rSum / counted; @@ -258,6 +256,7 @@ void IPU3Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats) uint32_t regionWidth = round(awbGrid_.width / static_cast(kAwbStatsSizeX)); uint32_t regionHeight = round(awbGrid_.height / static_cast(kAwbStatsSizeY)); + minZonesCounted_ = ((regionWidth * regionHeight) * 4) / 5; /* * Generate a (kAwbStatsSizeX x kAwbStatsSizeY) array from the IPU3 grid which is * (awbGrid_.width x awbGrid_.height). @@ -269,7 +268,7 @@ void IPU3Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats) uint32_t cellY = ((cellPosition / awbGrid_.width) / regionHeight) % kAwbStatsSizeY; uint32_t awbRegionPosition = cellY * kAwbStatsSizeX + cellX; - cellPosition *= 8; + cellPosition *= sizeof(Ipu3AwbCell); /* Cast the initial IPU3 structure to simplify the reading */ Ipu3AwbCell *currentCell = reinterpret_cast(const_cast(&stats->awb_raw_buffer.meta_data[cellPosition])); @@ -361,12 +360,12 @@ void IPU3Awb::updateWbParameters(ipu3_uapi_params ¶ms, double agcGamma) /* * Green gains should not be touched and considered 1. * Default is 16, so do not change it at all. - * 4096 is the value for a gain of 1.0 + * 8192 is the value for a gain of 1.0 */ - params.acc_param.bnr.wb_gains.gr = 16; - params.acc_param.bnr.wb_gains.r = 4096 * asyncResults_.redGain; - params.acc_param.bnr.wb_gains.b = 4096 * asyncResults_.blueGain; - params.acc_param.bnr.wb_gains.gb = 16; + params.acc_param.bnr.wb_gains.gr = 8192; + params.acc_param.bnr.wb_gains.r = 8192 * asyncResults_.redGain; + params.acc_param.bnr.wb_gains.b = 8192 * asyncResults_.blueGain; + params.acc_param.bnr.wb_gains.gb = 8192; LOG(IPU3Awb, Debug) << "Color temperature estimated: " << asyncResults_.temperatureK << " and gamma calculated: " << agcGamma; diff --git a/src/ipa/ipu3/ipu3_awb.h b/src/ipa/ipu3/ipu3_awb.h index 795e32e3..23865c21 100644 --- a/src/ipa/ipu3/ipu3_awb.h +++ b/src/ipa/ipu3/ipu3_awb.h @@ -49,6 +49,7 @@ private: std::vector zones_; IspStatsRegion awbStats_[kAwbStatsSizeX * kAwbStatsSizeY]; AwbStatus asyncResults_; + uint32_t minZonesCounted_; }; } /* namespace ipa::ipu3 */