From patchwork Mon Oct 28 17:36:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Rudenko X-Patchwork-Id: 21765 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 5E227C330B for ; Mon, 28 Oct 2024 17:37:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1C5AB653A0; Mon, 28 Oct 2024 18:37:16 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="DIsNB+O+"; dkim-atps=neutral Received: from mail-lj1-x235.google.com (mail-lj1-x235.google.com [IPv6:2a00:1450:4864:20::235]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 154936539E for ; Mon, 28 Oct 2024 18:37:14 +0100 (CET) Received: by mail-lj1-x235.google.com with SMTP id 38308e7fff4ca-2fb5638dd57so41497931fa.0 for ; Mon, 28 Oct 2024 10:37:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1730137033; x=1730741833; 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=T9wQAQt3kQ8GXfSTN5Q58fUB0Jku6lzj5kKx0V1cfjs=; b=DIsNB+O+2rwWq5XfCta7PfVd6HS6AwVDb1yFLtsJhKw/Yi66+4J5nXs05N+Oi9jnqG tV+lWFeI4nkq5WhbsQ3Y2Uw/jlw8lw2ZKrQVPirMxA5C71wagGqs3lb+8Dd7a7tSr0VL hDXbR9/pr5fZkOIDhURkc/w/XCsU2Q9BUmDeFO2RUedgcV6GTea9+yuGXVcGOylUlD67 WedPpI1Ey1ZLps99e3YEwpvslMu2ItgCLKaFXuocU0fhA4XG1WTcR13XEdntGIpPIzQD v/VXh6f6j8hsgiazLCx0igXvlIG5m6F4ULPrjE/v0zX1eKk8pUk5NDneRYyvYGl2R7T2 szFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730137033; x=1730741833; 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=T9wQAQt3kQ8GXfSTN5Q58fUB0Jku6lzj5kKx0V1cfjs=; b=vXRDUtSJ6F//nTjxVTlLpSqHWDIBD1OZJ0UvhGZSmIyju4MdM5GIPY1RVfkl+sSaWd +50q7SElM76XvktvncUESQ7iEgeWyINxmAEqgMnb0nIDuNRRlRkRF2sqstMqdsA/zKGa Nvat1wkmyV8pCpBO3+0+dgPK3LP7yStZenbLO57EWKRrQhp95F2Pku1XsVcFLLn9IHKQ zV82MOdlCkuWhX6m0lyFSycLZeJbbp7ja6NE57oNtz1qiDnV8jl3VVnqf/ycg71Wj4+P 5sleRo/maaLTSUYRJDtuF+1dpK+eaG8vNHkGF8rD9mJX0QDIOAe2qBYgcgDqtpPRJAuT Lx/w== X-Gm-Message-State: AOJu0YyjekHY0ghO4IWcyq4PQoFYlFsY2rrkcuH7KyoanXdgU58EjOKa bSJopIVEBZyX4UUmUZHkk7/q6AjIOVbiSaLBxFEeHbio3Sw0bHoaXJacJfRiEaQ= X-Google-Smtp-Source: AGHT+IHlGBH2z74ovj+bOs8SKFEtZlpb+JSrGy2ypL3fDmPK90hfeCj9fqAdH78x+VWsZU0wupWdtw== X-Received: by 2002:a05:651c:a0a:b0:2fb:6198:d230 with SMTP id 38308e7fff4ca-2fcbdfc65d6mr39555901fa.18.1730137032430; Mon, 28 Oct 2024 10:37:12 -0700 (PDT) Received: from localhost.localdomain ([45.12.135.46]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-2fcb453e3afsm12115511fa.57.2024.10.28.10.37.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Oct 2024 10:37:11 -0700 (PDT) From: Mikhail Rudenko To: libcamera-devel@lists.libcamera.org Cc: Kieran Bingham , Laurent Pinchart , Mikhail Rudenko Subject: [PATCH RFC 3/3] ipa: rkisp1: Pass sensor delays from IPA to pipeline handler Date: Mon, 28 Oct 2024 20:36:59 +0300 Message-ID: <20241028173659.247353-4-mike.rudenko@gmail.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20241028173659.247353-1-mike.rudenko@gmail.com> References: <20241028173659.247353-1-mike.rudenko@gmail.com> MIME-Version: 1.0 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" At present, rkisp1 uses hardcoded sensor control delays. In the case when they do not match real sensor delays, the AGC algorithm operates in a suboptimal mode, leading to gain/exposure oscillations on capture start and slower convergence. So, pass the correct delays from IPA at the init() time. Signed-off-by: Mikhail Rudenko --- include/libcamera/ipa/rkisp1.mojom | 3 ++- src/ipa/rkisp1/rkisp1.cpp | 8 +++++-- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 27 ++++++++++-------------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/libcamera/ipa/rkisp1.mojom b/include/libcamera/ipa/rkisp1.mojom index 80d54a03..aedd9461 100644 --- a/include/libcamera/ipa/rkisp1.mojom +++ b/include/libcamera/ipa/rkisp1.mojom @@ -19,7 +19,8 @@ interface IPARkISP1Interface { uint32 hwRevision, libcamera.IPACameraSensorInfo sensorInfo, libcamera.ControlInfoMap sensorControls) - => (int32 ret, libcamera.ControlInfoMap ipaControls); + => (int32 ret, libcamera.ControlInfoMap ipaControls, + libcamera.IPASensorDelays sensorDelays); start() => (int32 ret); stop(); diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 9e161cab..b42ec976 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -54,7 +54,8 @@ public: int init(const IPASettings &settings, unsigned int hwRevision, const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, - ControlInfoMap *ipaControls) override; + ControlInfoMap *ipaControls, + IPASensorDelays *sensorDelays) override; int start() override; void stop() override; @@ -136,7 +137,8 @@ std::string IPARkISP1::logPrefix() const int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision, const IPACameraSensorInfo &sensorInfo, const ControlInfoMap &sensorControls, - ControlInfoMap *ipaControls) + ControlInfoMap *ipaControls, + IPASensorDelays *sensorDelays) { /* \todo Add support for other revisions */ switch (hwRevision) { @@ -168,6 +170,8 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision, return -ENODEV; } + *sensorDelays = context_.camHelper->sensorDelays(); + context_.configuration.sensor.lineDuration = sensorInfo.minLineLength * 1.0s / sensorInfo.pixelRate; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index c7b0b392..0ece3c55 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -96,7 +96,7 @@ public: } PipelineHandlerRkISP1 *pipe(); - int loadIPA(unsigned int hwRevision); + int loadIPA(unsigned int hwRevision, IPASensorDelays *sensorDelays); Stream mainPathStream_; Stream selfPathStream_; @@ -360,7 +360,7 @@ PipelineHandlerRkISP1 *RkISP1CameraData::pipe() return static_cast(Camera::Private::pipe()); } -int RkISP1CameraData::loadIPA(unsigned int hwRevision) +int RkISP1CameraData::loadIPA(unsigned int hwRevision, IPASensorDelays *sensorDelays) { ipa_ = IPAManager::createIPA(pipe(), 1, 1); if (!ipa_) @@ -391,7 +391,8 @@ int RkISP1CameraData::loadIPA(unsigned int hwRevision) } ret = ipa_->init({ ipaTuningFile, sensor_->model() }, hwRevision, - sensorInfo, sensor_->controls(), &ipaControls_); + sensorInfo, sensor_->controls(), &controlInfo_, + sensorDelays); if (ret < 0) { LOG(RkISP1, Error) << "IPA initialization failure"; return ret; @@ -1240,14 +1241,14 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) /* Initialize the camera properties. */ data->properties_ = data->sensor_->properties(); - /* - * \todo Read delay values from the sensor itself or from a - * a sensor database. For now use generic values taken from - * the Raspberry Pi and listed as generic values. - */ + IPASensorDelays sensorDelays; + ret = data->loadIPA(media_->hwRevision(), &sensorDelays); + if (ret) + return ret; + std::unordered_map params = { - { V4L2_CID_ANALOGUE_GAIN, { 1, false } }, - { V4L2_CID_EXPOSURE, { 2, false } }, + { V4L2_CID_ANALOGUE_GAIN, { sensorDelays.gainDelay, false } }, + { V4L2_CID_EXPOSURE, { sensorDelays.exposureDelay, false } }, }; data->delayedCtrls_ = @@ -1256,12 +1257,6 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) isp_->frameStart.connect(data->delayedCtrls_.get(), &DelayedControls::applyControls); - ret = data->loadIPA(media_->hwRevision()); - if (ret) - return ret; - - updateControls(data.get()); - std::set streams{ &data->mainPathStream_, &data->selfPathStream_,