From patchwork Thu Oct 8 16:50:46 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 28415 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 A0158BDCB2 for ; Thu, 8 Oct 2026 16:51:40 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4E56668E22; Thu, 8 Oct 2026 18:51:40 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="NuZ2jXrh"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EF8BB689EA for ; Thu, 8 Oct 2026 18:51:38 +0200 (CEST) Received: from ideasonboard.com (dynamic-2a00-1028-8389-0276-ea41-93be-167f-9761.ipv6.o2.cz [IPv6:2a00:1028:8389:276:ea41:93be:167f:9761]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1AFBC4F1; Thu, 8 Oct 2026 18:49:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1791478181; bh=Lve9kGyX11SlzCTjmok2C0KBDtAQmeGP8ZzcTeCl+sM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NuZ2jXrh2LgyZecaxf9qmORVy6D8hLmtowOrHYpmrP2exoBTSSq71EvjaD5tH2zpw jKwYZoEQn1zCTX2bu6Athp/z4sCR1fw41i5MysZq1sl9+0Ui7SK5+CTlEMtirlfauv /4Sg9PXWzB3qOTp0XhFAuwDeKBYOloNk1ZO0gnj8= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v1 1/3] libcamera: converter: dw100_vertexmap: Add debug logging of dewarp parameters Date: Thu, 8 Oct 2026 18:50:46 +0200 Message-ID: <20261008165113.67511-2-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261008165113.67511-1-stefan.klug@ideasonboard.com> References: <20261008165113.67511-1-stefan.klug@ideasonboard.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" When analyzing issues with the dewarper it is very helpful to be able to get a log of the complete dewarper parameter set. Add the missing lens dewarp parameters. Signed-off-by: Stefan Klug Reviewed-by: Kieran Bingham --- .../converter/converter_dw100_vertexmap.cpp | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/libcamera/converter/converter_dw100_vertexmap.cpp b/src/libcamera/converter/converter_dw100_vertexmap.cpp index 5b813435706e..b36814c80a19 100644 --- a/src/libcamera/converter/converter_dw100_vertexmap.cpp +++ b/src/libcamera/converter/converter_dw100_vertexmap.cpp @@ -578,7 +578,27 @@ std::vector Dw100VertexMap::getVertexMap() << " scaleX: " << effectiveScaleX_ << " scaleY: " << effectiveScaleX_ << " rotation: " << rotation_ - << " offset: " << effectiveOffset_; + << " offset: " << effectiveOffset_ + << " lensDewarpEnable: " << lensDewarpEnable_; + + if (dewarpParams_.has_value()) + LOG(Converter, Debug) + << "Lens dewarp parameters cm: " << dewarpParams_->cm + << " coeffs: [" << dewarpParams_->coefficients.k1 + << ", " << dewarpParams_->coefficients.k2 + << ", " << dewarpParams_->coefficients.p1 + << ", " << dewarpParams_->coefficients.p2 + << ", " << dewarpParams_->coefficients.k3 + << ", " << dewarpParams_->coefficients.k4 + << ", " << dewarpParams_->coefficients.k5 + << ", " << dewarpParams_->coefficients.k6 + << ", " << dewarpParams_->coefficients.s1 + << ", " << dewarpParams_->coefficients.s2 + << ", " << dewarpParams_->coefficients.s3 + << ", " << dewarpParams_->coefficients.s4 + << "]"; + else + LOG(Converter, Debug) << "Lens dewarp parameters: None"; Matrix3x3 outputToSensor = Matrix3x3::identity(); /* Move to center of output */ From patchwork Thu Oct 8 16:50:47 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 28416 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 4249EC3305 for ; Thu, 8 Oct 2026 16:51:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D0C6A68DF6; Thu, 8 Oct 2026 18:51:42 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="tb7lkqwG"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 649E668A58 for ; Thu, 8 Oct 2026 18:51:41 +0200 (CEST) Received: from ideasonboard.com (dynamic-2a00-1028-8389-0276-ea41-93be-167f-9761.ipv6.o2.cz [IPv6:2a00:1028:8389:276:ea41:93be:167f:9761]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6C8E563C; Thu, 8 Oct 2026 18:49:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1791478183; bh=M0KFomNGtrAi5haXYfa4Qs8vqqjCwbsRcyCVJWwSboI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tb7lkqwGkSkN0G5Oim43yF2DF4SqpG6jRAAqoocW9wXWkXvV3gfpR8+I5/mQ8wfMV 7KtxYtAuvaZr4qQSVwxjX0KGBwutiddU2v4OccU/ynLITqCh9Pdwpgpc7g7BDezCqK I+TemCT74LkZozCGjCyzlta4CkoHY9M/sqw+loi8= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v1 2/3] libcamera: pipeline: rkisp1: Fix dewarping with multiple cameras Date: Thu, 8 Oct 2026 18:50:47 +0200 Message-ID: <20261008165113.67511-3-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261008165113.67511-1-stefan.klug@ideasonboard.com> References: <20261008165113.67511-1-stefan.klug@ideasonboard.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" The dewarper is only instantiated once per pipeline. One pipeline can support multiple cameras with different sets of dewarp parmeters. In the current implementation the dewarp parameters are stored in the dewarper when the tuning file is loaded at init() time. Therefore the tuning file loaded last will overwrite the dewarp params for all cameras. Fix that by storing the dewarp parameters in the camera data and passing them to the dewarper at configure() time. While at it, mention the dwNew parameter in the yaml code sample. Signed-off-by: Stefan Klug Reviewed-by: Kieran Bingham --- .../internal/converter/converter_dw100.h | 8 ++-- src/libcamera/converter/converter_dw100.cpp | 39 +++++++++++++------ src/libcamera/pipeline/rkisp1/rkisp1.cpp | 5 ++- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/include/libcamera/internal/converter/converter_dw100.h b/include/libcamera/internal/converter/converter_dw100.h index 003f5eb954e9..029810bb4fa6 100644 --- a/include/libcamera/internal/converter/converter_dw100.h +++ b/include/libcamera/internal/converter/converter_dw100.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include @@ -31,11 +32,12 @@ public: static std::unique_ptr createModule(DeviceEnumerator *enumerator); - int init(const ValueNode ¶ms); + int loadDewarpParams(const ValueNode ¶ms, std::optional &dewarpParams); int configure(const StreamConfiguration &inputCfg, const std::vector> - &outputCfg); + &outputCfg, + const std::optional dewarpParams); bool isConfigured(const Stream *stream) const; Size adjustInputSize(const PixelFormat &pixFmt, const Size &size, @@ -75,7 +77,7 @@ private: }; std::map vertexMaps_; - std::optional dewarpParams_; + bool hasDewarpParams_; unsigned int inputBufferCount_; V4L2M2MConverter converter_; Rectangle sensorCrop_; diff --git a/src/libcamera/converter/converter_dw100.cpp b/src/libcamera/converter/converter_dw100.cpp index 300ea808ceff..ba7337b4abdd 100644 --- a/src/libcamera/converter/converter_dw100.cpp +++ b/src/libcamera/converter/converter_dw100.cpp @@ -72,11 +72,14 @@ ConverterDW100Module::createModule(DeviceEnumerator *enumerator) } /** - * \brief Initialize the module with configuration data + * \brief Load dewarp parameters from configuration file * \param[in] params The config parameters + * \param[out] dewarpParams The dewarp parameters * - * This function shall be called from the pipeline handler to initialize the - * module with the provided parameters. + * This function shall be called from the pipeline handler to load dewarp + * parameters from a tuning file. The dewarpParams can then be passed to + * configure() to configure the dewarper. If the tuning file does not contain + * any property, 0 is returned and dewarpParams is set to nullopt_t. * * A typical tuning file entry for the dewarper looks like this: * \code{.unparsed} @@ -87,6 +90,7 @@ ConverterDW100Module::createModule(DeviceEnumerator *enumerator) * 0.0, 1.0, 0.0, * 0.0, 0.0, 1.0, * ] + * cmNew: * coefficients: [ * 0,0,0,0,0, * ] @@ -98,9 +102,11 @@ ConverterDW100Module::createModule(DeviceEnumerator *enumerator) * \sa Dw100VertexMap::setDewarpParams() * \return 0 if successful, an error code otherwise */ -int ConverterDW100Module::init(const ValueNode ¶ms) +int ConverterDW100Module::loadDewarpParams(const ValueNode ¶ms, + std::optional &dewarpParams) { Dw100VertexMap::DewarpParams dp; + dewarpParams.reset(); auto &cm = params["cm"]; auto &coefficients = params["coefficients"]; @@ -153,17 +159,26 @@ int ConverterDW100Module::init(const ValueNode ¶ms) dp.cmNew = dp.cm; } - dewarpParams_ = dp; + dewarpParams = dp; return 0; } /** - * \copydoc libcamera::V4L2M2MConverter::configure + * \brief Configure a the dw100 converter module + * \param[in] inputCfg Input stream configuration + * \param[in] outputCfgs A list of output stream configurations + * \param[in] dewarpParams The lens dewarp parameters to apply + * + * Configures the converter for the given input and output stream configurations + * and an optional set of dewarp parameters. + * + * \return 0 on success or a negative error code otherwise */ int ConverterDW100Module::configure(const StreamConfiguration &inputCfg, const std::vector> - &outputCfgs) + &outputCfgs, + const std::optional dewarpParams) { int ret; @@ -174,6 +189,8 @@ int ConverterDW100Module::configure(const StreamConfiguration &inputCfg, inputBufferCount_ = inputCfg.bufferCount; + hasDewarpParams_ = dewarpParams.has_value(); + for (auto &ref : outputCfgs) { const auto &outputCfg = ref.get(); auto &info = vertexMaps_[outputCfg.stream()]; @@ -182,8 +199,8 @@ int ConverterDW100Module::configure(const StreamConfiguration &inputCfg, vertexMap.setOutputSize(outputCfg.size); vertexMap.setSensorCrop(sensorCrop_); - if (dewarpParams_) - vertexMap.setDewarpParams(*dewarpParams_); + if (dewarpParams) + vertexMap.setDewarpParams(*dewarpParams); info.update = true; } @@ -363,7 +380,7 @@ void ConverterDW100Module::updateControlInfos(const Stream *stream, ControlInfoM controls[&controls::ScalerCrop] = ControlInfo(Rectangle(sensorCrop_.x, sensorCrop_.y, 1, 1), sensorCrop_, sensorCrop_); - if (dewarpParams_.has_value()) + if (hasDewarpParams_) controls[&controls::LensDewarpEnable] = ControlInfo(false, true, true); if (!converter_.supportsRequests()) @@ -424,7 +441,7 @@ void ConverterDW100Module::populateMetadata(const Stream *stream, ControlList &m meta.set(controls::ScalerCrop, vertexMap.effectiveScalerCrop()); - if (dewarpParams_.has_value()) + if (hasDewarpParams_) meta.set(controls::LensDewarpEnable, vertexMap.lensDewarpEnable()); } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 96382c93a427..39fe0f0964d7 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -128,6 +128,7 @@ public: bool canUseDewarper_; bool usesDewarper_; + std::optional dewarpParams_; private: void paramsComputed(unsigned int frame, unsigned int bytesused); @@ -462,7 +463,7 @@ int RkISP1CameraData::loadTuningFile(const std::string &path) if (!params) continue; - ret = pipe()->dewarper_->init(params); + ret = pipe()->dewarper_->loadDewarpParams(params, dewarpParams_); if (ret) return ret; @@ -1058,7 +1059,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) PixelFormatInfo::info(ispCfg.pixelFormat) .stride(ispCfg.size.width, 0); - ret = dewarper_->configure(ispCfg, { cfg }); + ret = dewarper_->configure(ispCfg, { cfg }, data->dewarpParams_); if (ret) return ret; From patchwork Thu Oct 8 16:50:48 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 28417 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 D78E5BDCB2 for ; Thu, 8 Oct 2026 16:51:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 62DA768E22; Thu, 8 Oct 2026 18:51:46 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="uW1CMYOd"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C1D4C68DEF for ; Thu, 8 Oct 2026 18:51:44 +0200 (CEST) Received: from ideasonboard.com (dynamic-2a00-1028-8389-0276-ea41-93be-167f-9761.ipv6.o2.cz [IPv6:2a00:1028:8389:276:ea41:93be:167f:9761]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DFBAE63C; Thu, 8 Oct 2026 18:49:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1791478187; bh=7t8gU65NUpTHqnTLqt58ed5aMYhBI5OxUNqDvKyxk/U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uW1CMYOdg0kPjRpAx236/PzwRHQ7+FMkv4/M5iJ9Kn5Mo7VLAKNuwTvRhPiHdrBQk wKVIZOW0NtaCzK8P2dVeRAcKQ4B1z4ha3kR4C/5HHcx/15Cizd/Xt0mXqVg2/jBoBR Q9/FodZ/rGx4f7wbwM9gUBgUVEx0FwqLlq6wN2NI= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v1 3/3] libcamera: converter: Small fix in parameter documentation Date: Thu, 8 Oct 2026 18:50:48 +0200 Message-ID: <20261008165113.67511-4-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261008165113.67511-1-stefan.klug@ideasonboard.com> References: <20261008165113.67511-1-stefan.klug@ideasonboard.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" The outputCfgs parameter is an input parameter. Adjust the documentation accordingly. Signed-off-by: Stefan Klug Reviewed-by: Kieran Bingham --- src/libcamera/converter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcamera/converter.cpp b/src/libcamera/converter.cpp index ec0a6db6c035..67e02cce0b72 100644 --- a/src/libcamera/converter.cpp +++ b/src/libcamera/converter.cpp @@ -163,7 +163,7 @@ Converter::~Converter() * \fn Converter::configure() * \brief Configure a set of output stream conversion from an input stream * \param[in] inputCfg Input stream configuration - * \param[out] outputCfgs A list of output stream configurations + * \param[in] outputCfgs A list of output stream configurations * \return 0 on success or a negative error code otherwise */